Skip to content

Commit 9574c14

Browse files
authored
Merge pull request #4 from lightness/feature/api-support
Feature/api support
2 parents 84c27c7 + 71d87f4 commit 9574c14

20 files changed

+200
-87
lines changed

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,19 @@ Options:
7272
[boolean] [default: false]
7373
--json show output as prettified json [boolean] [default: false]
7474
-h, --help Show help [boolean]
75-
```
75+
```
76+
77+
## Use in your app
78+
79+
```js
80+
const { grt } = require('github-repo-tools');
81+
82+
const response = await grt({
83+
user: 'lightness',
84+
package: 'typescript',
85+
yarnLock: false,
86+
token: '<GITHUB_TOKEN>',
87+
});
88+
```
89+
90+
> TODO: Add more descriptive exmaple

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "github-repo-tools",
3-
"version": "2.2.0",
3+
"version": "2.3.0",
44
"description": "Useful tool to get versions from all repos of Github user/org",
5-
"main": "build/app.js",
5+
"main": "build/index.js",
66
"bin": {
77
"grt": "./build/app.js"
88
},

src/app.module.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import { Module } from '@nestjs/common';
1+
import { Module, DynamicModule, Global } from '@nestjs/common';
22
import { CliModule } from './modules/cli/cli.module';
33
import { NodeVersionModule } from './modules/node-version/node.version.module';
44
import { AppService } from './app.service';
55
import { NpmDependencyVersionModule } from './modules/npm-dependency-version/npm.dependency.version.module';
66
import { RateLimitModule } from './modules/rate-limit/rate.limit.module';
77
import { PresenterModule } from './modules/presenter/presenter.module';
8+
import { CumulativeWritable } from './util/cumulative.stream';
89

10+
@Global()
911
@Module({
1012
imports: [
11-
CliModule,
1213
PresenterModule,
1314
RateLimitModule,
1415
NodeVersionModule,
@@ -22,4 +23,30 @@ import { PresenterModule } from './modules/presenter/presenter.module';
2223
],
2324
})
2425
export class AppModule {
26+
static forApi(): DynamicModule {
27+
const streamProvider = {
28+
provide: 'STREAM',
29+
useFactory: () => new CumulativeWritable({})
30+
};
31+
32+
return {
33+
module: AppModule,
34+
providers: [streamProvider],
35+
exports: [streamProvider],
36+
};
37+
}
38+
39+
static forCli(): DynamicModule {
40+
const streamProvider = {
41+
provide: 'STREAM',
42+
useValue: process.stdout
43+
};
44+
45+
return {
46+
module: AppModule,
47+
imports: [CliModule],
48+
providers: [streamProvider],
49+
exports: [streamProvider],
50+
};
51+
}
2552
}

src/app.service.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable } from '@nestjs/common';
1+
import { Injectable, Optional } from '@nestjs/common';
22
import { CliService } from './modules/cli/cli.service';
33
import { NodeVersionService } from './modules/node-version/node.version.service';
44
import { INodeVersion } from './modules/node-version/interfaces';
@@ -13,7 +13,7 @@ import { PresentationMode } from './modules/presenter/interfaces';
1313
export class AppService {
1414

1515
constructor(
16-
private cliService: CliService,
16+
@Optional() private cliService: CliService,
1717
private presenterService: PresenterService,
1818
private rateLimitService: RateLimitService,
1919
private nodeVersionService: NodeVersionService,
@@ -24,19 +24,23 @@ export class AppService {
2424
public async main() {
2525
const options: IProgramOptions = await this.cliService.getProgramOptions();
2626

27+
return this.run(options);
28+
}
29+
30+
public async run(options: IProgramOptions) {
2731
this.setupPresenter(options);
2832

2933
this.presenterService.showFiglet();
3034
this.presenterService.showGithubTokenInfo(options);
3135

32-
const { package: packageName, node, rateLimit } = options;
36+
const { package: packageName, node, rateLimit, token } = options;
3337

3438
if (node) {
3539
return this.nodeCase(options);
3640
} else if (packageName) {
3741
return this.packageCase(options);
3842
} else if (rateLimit) {
39-
return this.showRateLimit(true);
43+
return this.showRateLimit(true, token);
4044
} else {
4145
this.presenterService.showError('Wrong input');
4246
}
@@ -45,17 +49,17 @@ export class AppService {
4549
private async nodeCase(options: IProgramOptions) {
4650
const report: INodeVersion[] = await this.nodeVersionService.getReport(options);
4751
this.presenterService.showData(report, options);
48-
this.showRateLimit(false);
52+
this.showRateLimit(false, options.token);
4953
}
5054

5155
private async packageCase(options: IProgramOptions) {
5256
const report: IPacakgeVersion[] = await this.npmDependencyVersionService.getReport(options);
5357
this.presenterService.showData(report, options);
54-
this.showRateLimit(false);
58+
this.showRateLimit(false, options.token);
5559
}
5660

57-
private async showRateLimit(isMainInfo: boolean) {
58-
const rateLimit = await this.rateLimitService.getRateLimit();
61+
private async showRateLimit(isMainInfo: boolean, token?: string) {
62+
const rateLimit = await this.rateLimitService.getRateLimit(token);
5963

6064
this.presenterService.showRateLimit(rateLimit, isMainInfo);
6165
}

src/app.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import { AppService } from './app.service';
55
import { AppLogger } from './app.logger';
66

77
async function bootstrap() {
8-
const app = await NestFactory.createApplicationContext(AppModule, { logger: new AppLogger() });
8+
const app = await NestFactory.createApplicationContext(
9+
AppModule.forCli(),
10+
{ logger: new AppLogger() }
11+
);
912

1013
const appService = app.get(AppService);
1114
await appService.main();

src/config/default.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { IProgramOptions } from "../interfaces";
2+
3+
export const DEFAULT: IProgramOptions = {
4+
skipEmpty: true,
5+
skipError: [404],
6+
7+
json: false,
8+
rawJson: false,
9+
10+
engines: true,
11+
nvm: true,
12+
13+
deps: true,
14+
devDeps: true,
15+
peerDeps: true,
16+
packageLock: true,
17+
yarnLock: true,
18+
19+
token: process.env.GITHUB_TOKEN,
20+
}

src/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { NestFactory } from '@nestjs/core';
2+
import { AppModule } from './app.module';
3+
import { AppService } from './app.service';
4+
import { AppLogger } from './app.logger';
5+
import { IProgramOptions } from './interfaces';
6+
import { CumulativeWritable } from './util/cumulative.stream';
7+
import { DEFAULT } from './config/default';
8+
9+
export async function grt(options: IProgramOptions) {
10+
const app = await NestFactory.createApplicationContext(
11+
AppModule.forApi(),
12+
{ logger: new AppLogger() }
13+
);
14+
15+
const appService = app.get(AppService);
16+
await appService.run({ ...DEFAULT, ...options, json: true });
17+
const stream: CumulativeWritable = app.get('STREAM');
18+
19+
return JSON.parse(stream.getAccumulated());
20+
}

src/interfaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export interface INodeOptions {
2424
}
2525

2626
export interface IPresenterOptions {
27-
json?: number;
27+
json?: boolean;
2828
rawJson?: boolean;
2929
}
3030

src/modules/cli/commander.service.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as yargs from 'yargs';
22
import { Injectable } from '@nestjs/common';
3-
import { IProgramOptions } from '../../interfaces.js';
3+
import { IProgramOptions } from '../../interfaces';
4+
import { DEFAULT } from '../../config/default';
45

56
@Injectable()
67
export class CommanderService {
@@ -31,27 +32,27 @@ export class CommanderService {
3132
})
3233
.option('deps', {
3334
describe: 'disable search in "dependencies" package.json field',
34-
default: true,
35+
default: DEFAULT.deps,
3536
type: 'boolean',
3637
})
3738
.option('dev-deps', {
3839
describe: 'disable search in "devDependencies" package.json field',
39-
default: true,
40+
default: DEFAULT.devDeps,
4041
type: 'boolean',
4142
})
4243
.option('peer-deps', {
4344
describe: 'disable search in "peerDependencies" package.json field',
44-
default: true,
45+
default: DEFAULT.peerDeps,
4546
type: 'boolean',
4647
})
4748
.option('yarn-lock', {
4849
describe: 'disable search in yarn.lock',
49-
default: true,
50+
default: DEFAULT.yarnLock,
5051
type: 'boolean',
5152
})
5253
.option('package-lock', {
5354
describe: 'disable search in package-lock.json',
54-
default: true,
55+
default: DEFAULT.packageLock,
5556
type: 'boolean',
5657
})
5758
.option('node', {
@@ -60,12 +61,12 @@ export class CommanderService {
6061
})
6162
.options('nvm', {
6263
describe: 'disable search in .nvmrc',
63-
default: true,
64+
default: DEFAULT.nvm,
6465
type: 'boolean',
6566
})
6667
.options('engines', {
6768
describe: 'disable search in package.json engines',
68-
default: true,
69+
default: DEFAULT.engines,
6970
type: 'boolean',
7071
})
7172
.option('rate-limit', {
@@ -74,28 +75,28 @@ export class CommanderService {
7475
})
7576
.option('skip-empty', {
7677
describe: 'skip repo, if package/node not found',
77-
default: true,
78+
default: DEFAULT.skipEmpty,
7879
type: 'boolean',
7980
})
8081
.option('skip-error', {
8182
describe: 'skip repo, if error with such code occured',
82-
default: [404],
83+
default: DEFAULT.skipError,
8384
type: 'array'
8485
})
8586
.option('raw-json', {
8687
describe: 'show output as json without whitespaces',
87-
default: false,
88+
default: DEFAULT.rawJson,
8889
type: 'boolean',
8990
})
9091
.option('json', {
9192
describe: 'show output as prettified json',
92-
default: false,
93+
default: DEFAULT.json,
9394
type: 'boolean',
9495
})
9596
.option('token', {
9697
alias: 't',
9798
describe: 'token to auth on github. Env var GITHUB_TOKEN strictly prefered',
98-
default: process.env.GITHUB_TOKEN,
99+
default: DEFAULT.token,
99100
type: 'string'
100101
})
101102
.group(['user', 'org'], 'Owner:')

src/modules/node-version/node.version.service.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ export class NodeVersionService {
1414
}
1515

1616
public async getReport(options: IProgramOptions): Promise<INodeVersion[]> {
17-
const { org, user, nvm, engines } = options;
17+
const { org, user, nvm, engines, token } = options;
1818

19-
const repos = await this.octokitService.getRepos({ org, user });
19+
const repos = await this.octokitService.getRepos({ org, user, token });
2020

2121
if (!repos) {
2222
return null;
@@ -28,8 +28,8 @@ export class NodeVersionService {
2828
repos.map(async repo => {
2929
try {
3030
const [nvmVersion, enginesVersion] = await Promise.all([
31-
nvm ? this.getNvmrc(org || user, repo).catch(() => null) : null,
32-
engines ? this.getEngines(org || user, repo).catch(() => null) : null
31+
nvm ? this.getNvmrc(org || user, repo, token).catch(() => null) : null,
32+
engines ? this.getEngines(org || user, repo, token).catch(() => null) : null
3333
]);
3434

3535
const data: INodeVersion = { repo };
@@ -54,14 +54,14 @@ export class NodeVersionService {
5454
return result;
5555
}
5656

57-
private async getNvmrc(owner, repo): Promise<string> {
58-
const content = await this.octokitService.getFileContent(owner, repo, '.nvmrc');
57+
private async getNvmrc(owner, repo, token): Promise<string> {
58+
const content = await this.octokitService.getFileContent(owner, repo, '.nvmrc', token);
5959

6060
return content.trim();
6161
}
6262

63-
private async getEngines(owner, repo): Promise<string> {
64-
const packageJson = await this.octokitService.getPackageJson(owner, repo);
63+
private async getEngines(owner, repo, token): Promise<string> {
64+
const packageJson = await this.octokitService.getPackageJson(owner, repo, token);
6565
const engines = packageJson.engines;
6666

6767
if (!engines || !engines.node) {

0 commit comments

Comments
 (0)