From 8e522138531c8e54c5dd82d408bf7549a89ec36d Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Thu, 9 Apr 2020 09:38:38 -0700 Subject: [PATCH 1/2] make types more usable --- src/index.ts | 95 ++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2074ae9..6345e62 100644 --- a/src/index.ts +++ b/src/index.ts @@ -38,9 +38,7 @@ const defaultFields = [ ] as const; type DefaultField = typeof defaultFields[number]; -export interface GitlogOptions< - Fields extends readonly CommitField[] = DefaultField[] -> { +export interface GitlogOptions { /** The location of the repo */ repo: string; /** @@ -68,7 +66,7 @@ export interface GitlogOptions< */ number?: number; /** An array of fields to return from the log */ - fields?: Fields; + fields?: readonly Fields[]; /** * Below fields was returned from the log: * @@ -104,7 +102,7 @@ export interface GitlogOptions< const defaultOptions = { number: 10, - fields: (defaultFields as unknown) as readonly CommitField[], + fields: defaultFields, nameStatus: true, includeMergeCommitFiles: false, findCopiesHarder: false, @@ -112,9 +110,9 @@ const defaultOptions = { }; /** Add optional parameter to command */ -function addOptional( +function addOptional( command: string, - options: GitlogOptions + options: GitlogOptions ) { let commandWithOptions = command; const cmdOptional = [ @@ -220,8 +218,8 @@ const parseCommits = ( }; /** Run "git log" and return the result as JSON */ -function createCommand( - options: GitlogOptions & typeof defaultOptions +function createCommand( + options: GitlogOptions ) { // Start constructing command let command = "git log "; @@ -246,13 +244,15 @@ function createCommand( command += ' --pretty="@begin@'; // Iterating through the fields and adding them to the custom format - options.fields.forEach((field) => { - if (!fieldMap[field] && notOptFields.indexOf(field as NotOptField) === -1) { - throw new Error(`Unknown field: ${field}`); - } + if (options.fields) { + options.fields.forEach((field) => { + if (!fieldMap[field] && !notOptFields.includes(field as any)) { + throw new Error(`Unknown field: ${field}`); + } - command += delimiter + fieldMap[field]; - }); + command += delimiter + fieldMap[field]; + }); + } // Close custom format command += '@end@"'; @@ -284,33 +284,30 @@ type CommitBaseWithFiles = Record< string > & { files: string[] }; -function gitlog( - userOptions: GitlogOptions & { nameStatus: false }, - cb: (err: GitlogError, commits: CommitBase[]) => void +function gitlog( + userOptions: GitlogOptions & { nameStatus: false }, + cb: (err: GitlogError, commits: CommitBase[]) => void ): void; -function gitlog( - userOptions: GitlogOptions, - cb: (err: GitlogError, commits: CommitBaseWithFiles[]) => void +function gitlog( + userOptions: GitlogOptions, + cb: (err: GitlogError, commits: CommitBaseWithFiles[]) => void ): void; -function gitlog( - userOptions: GitlogOptions & { nameStatus: false } -): CommitBase[]; +function gitlog( + userOptions: GitlogOptions & { nameStatus: false } +): CommitBase[]; -function gitlog( - userOptions: GitlogOptions -): CommitBaseWithFiles[]; +function gitlog( + userOptions: GitlogOptions +): CommitBaseWithFiles[]; -function gitlog( - userOptions: GitlogOptions, +function gitlog( + userOptions: GitlogOptions, cb?: - | ((err: GitlogError, commits: CommitBase[]) => void) - | (( - err: GitlogError, - commits: CommitBaseWithFiles[] - ) => void) -): CommitBase[] | CommitBaseWithFiles[] | void { + | ((err: GitlogError, commits: CommitBase[]) => void) + | ((err: GitlogError, commits: CommitBaseWithFiles[]) => void) +): CommitBase[] | CommitBaseWithFiles[] | void { if (!userOptions.repo) { throw new Error("Repo required!"); } @@ -321,7 +318,7 @@ function gitlog( // Set defaults const options = { - ...defaultOptions, + ...(defaultOptions as any), ...userOptions, }; const execOptions = { cwd: userOptions.repo, ...userOptions.execOptions }; @@ -356,21 +353,17 @@ function gitlog( }); } -export function gitlogPromise< - Fields extends readonly CommitField[] = DefaultField[] ->( - options: GitlogOptions & { nameStatus: false } -): Promise[]>; - -export function gitlogPromise< - Fields extends readonly CommitField[] = DefaultField[] ->( - options: GitlogOptions -): Promise[]>; - -export function gitlogPromise< - Fields extends readonly CommitField[] = DefaultField[] ->(options: GitlogOptions): Promise[]> { +export function gitlogPromise( + options: GitlogOptions & { nameStatus: false } +): Promise[]>; + +export function gitlogPromise( + options: GitlogOptions +): Promise[]>; + +export function gitlogPromise( + options: GitlogOptions +): Promise[]> { return new Promise((resolve, reject) => { gitlog(options, (err, commits) => { if (err) { From 12360a074feb0ea04d36078b12e0cf92342effe4 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Thu, 9 Apr 2020 09:43:37 -0700 Subject: [PATCH 2/2] add docs --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 5534618..dda114a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,42 @@ gitlog(options) .catch((err) => console.log(err)); ``` +`gitlog` comes with full typescript support! + +```ts +import gitlog, { GitlogOptions } from "gitlog"; + +// Option 1: Just use the function, returned commit type has specified fields +gitlog({ + repo: "foo", + fields: ["subject", "authorName", "authorDate"], +}); + +// Option 2: Use Options type to create options +const options: GitlogOptions<"subject" | "authorName" | "authorDate"> = { + repo: "foo", + fields: ["subject", "authorName", "authorDate"], +}; + +gitlog(options); + +// Option 3: Typescript Magic +const options = { + repo: "foo", + fields: ["subject", "authorName", "authorDate"] as const, +}; + +gitlog(options); + +// NOT SUPPORTED: Without "as const" gitlog can't create a good return type +const options = { + repo: "foo", + fields: ["subject", "authorName", "authorDate"], +}; + +gitlog(options); +``` + ## Options See [git log](http://git-scm.com/docs/git-log) @@ -203,6 +239,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d + This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!