Skip to content

Commit 6d20f30

Browse files
author
Juri Adams
committed
♻️ Moving from JavaScript to TypeScript
1 parent 3a07ce8 commit 6d20f30

File tree

7 files changed

+153
-43
lines changed

7 files changed

+153
-43
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules/
22
build.ts
3-
src/
3+
src/
4+
bin/

README.md

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const buildInfo = {
2020
user: "Juri Adams",
2121
hash: "1e872b5",
2222
version: "1.1.4",
23-
timestamp: "November 15, 2019 16:37:35"
23+
timestamp: "November 15, 2019 16:37:35",
2424
};
2525
```
2626

@@ -59,22 +59,21 @@ import { environment } from "../environments/environment";
5959
@Component({
6060
selector: "app-root",
6161
templateUrl: "./app.component.html",
62-
styleUrls: ["./app.component.css"]
62+
styleUrls: ["./app.component.css"],
6363
})
6464
export class AppComponent {
6565
constructor() {
6666
console.log(
67-
`\n%cBuild Info:\n\n%c ❯ Environment: %c${
68-
environment.production ? "production 🏭" : "development 🚧"
69-
}\n%c ❯ Build Version: ${buildInfo.version}\n ❯ Build Timestamp: ${
70-
buildInfo.timestamp
71-
}\n ❯ Built by: ${buildInfo.user}\n ❯ Commit: ${buildInfo.hash}\n`,
67+
`\n%cBuild Info:\n\n` +
68+
`%c ❯ Environment: %c${environment.production ? "production 🏭" : "development 🚧"}\n` +
69+
`%c ❯ Build Version: ${buildInfo.version}\n` +
70+
` ❯ Build Timestamp: ${buildInfo.timestamp}\n` +
71+
` ❯ Built by: ${buildInfo.user}\n` +
72+
` ❯ Commit: ${buildInfo.hash}\n`,
7273
"font-size: 14px; color: #7c7c7b;",
7374
"font-size: 12px; color: #7c7c7b",
74-
environment.production
75-
? "font-size: 12px; color: #95c230;"
76-
: "font-size: 12px; color: #e26565;",
77-
"font-size: 12px; color: #7c7c7b"
75+
environment.production ? "font-size: 12px; color: #95c230;" : "font-size: 12px; color: #e26565;",
76+
"font-size: 12px; color: #7c7c7b",
7877
);
7978
}
8079
}

bin/build-info.js renamed to angular-build-info.ts

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,45 @@
11
#! /usr/bin/env node
22

3+
/**
4+
* IBuildInfo interface and typings
5+
*/
6+
interface IBuildInfo {
7+
hash?: string; // Latest commit hash
8+
timestamp?: string; // Timestamp on when the build was made
9+
user?: string; // Current git user
10+
version?: string; // `version` from package.json
11+
}
12+
313
/**
414
* Dependencies
515
*/
6-
const moment = require("moment");
7-
const signale = require("signale");
8-
const util = require("util");
9-
const exec = util.promisify(require("child_process").exec);
10-
const fs = require("fs").promises;
16+
import { exec } from "child_process";
17+
import { promises as fs } from "fs";
18+
import moment from "moment";
19+
import signale from "signale";
20+
import { promisify } from "util";
21+
const execAsync = promisify(exec);
1122

1223
/**
1324
* Information sources
1425
*/
15-
const package = require(`${process.cwd()}/package.json`);
16-
const args = process.argv.slice(2);
17-
const opts = [
26+
// tslint:disable-next-line: no-var-requires
27+
const version = require(`${process.cwd()}/package.json`).version;
28+
const args: string[] = process.argv.slice(2);
29+
const opts: string[] = [
1830
"--help", // Shows manual
1931
"--init", // Perform initial setup
2032
"--no-hash", // Don't show commit hash in build info
2133
"--no-user", // Don't show git user in build info
2234
"--no-version", // Don't show package version in build info
23-
"--no-time" // Don't show timestamp in build info
35+
"--no-time", // Don't show timestamp in build info
2436
];
2537

2638
/**
2739
* Get relevant build information
2840
*/
29-
async function getGitUser() {
30-
const { stdout, stderr } = await exec("git config user.name");
41+
async function getGitUser(): Promise<string | undefined> {
42+
const { stdout, stderr } = await execAsync("git config user.name");
3143
if (stderr) {
3244
signale.error("Error getting git user, skipping...");
3345
return undefined;
@@ -37,8 +49,8 @@ async function getGitUser() {
3749
}
3850
}
3951

40-
async function getCommitHash() {
41-
const { stdout, stderr } = await exec("git rev-parse --short HEAD");
52+
async function getCommitHash(): Promise<string | undefined> {
53+
const { stdout, stderr } = await execAsync("git rev-parse --short HEAD");
4254
if (stderr) {
4355
signale.error("Error getting latest commit hash, skipping...");
4456
return undefined;
@@ -48,18 +60,19 @@ async function getCommitHash() {
4860
}
4961
}
5062

51-
async function buildInfo() {
63+
async function buildInfo(): Promise<void> {
5264
signale.start("Collecting build information...");
5365

5466
// Check provided args if they exist
55-
args.map(arg => {
67+
args.map((arg: any) => {
5668
if (!opts.includes(arg)) {
57-
throw `Error: Unknown arg "${arg}", please re-check arguments before running the tool again!`;
69+
signale.error(`Error: Unknown arg "${arg}", please re-check arguments before running the tool again!`);
70+
process.exit(1);
5871
}
5972
});
6073

6174
// Object we store build info in
62-
let build = {};
75+
const build: IBuildInfo = {};
6376

6477
if (!args.includes("--no-hash")) {
6578
build.hash = await getCommitHash();
@@ -70,7 +83,7 @@ async function buildInfo() {
7083
}
7184

7285
if (!args.includes("--no-version")) {
73-
build.version = package.version;
86+
build.version = version;
7487
}
7588

7689
if (!args.includes("--no-time")) {
@@ -89,33 +102,33 @@ async function buildInfo() {
89102
"// Angular build information, automatically generated by `angular-build-info`\n" +
90103
"export const buildInfo = " +
91104
JSON.stringify(build, null, 4).replace(/\"([^(\")"]+)\":/g, "$1:") +
92-
";\n"
105+
";\n",
93106
);
94107
signale.success(`Saved build information to \`${exportPath}\``);
95108
} catch {
96109
signale.error(`An error occured writing to \`${exportPath}\`, does the path exist?`);
97110
}
98111
}
99112

100-
async function init() {
113+
async function init(): Promise<void> {
101114
// Path we write the file to, should match your Angular projects `src/` folder
102115
const exportPath = process.cwd() + "/src/build.ts";
103116

104117
signale.info("Welcome to `angular-build-info`!");
105118
signale.info(
106-
`We will now create a boilerplate \`build.ts\` file in \`${exportPath}\` and fill it with basic information so you can start implementing it in your front-end.`
119+
`We will now create a boilerplate \`build.ts\` file in \`${exportPath}\` and fill it with basic information so you can start implementing it in your front-end.`,
107120
);
108121
signale.info(
109-
`If you wish for more info on how to implement the provided info in your Angular app, feel free to check out the main repo over at https://github.com/4dams/angular-build-info`
122+
`If you wish for more info on how to implement the provided info in your Angular app, feel free to check out the main repo over at https://github.com/4dams/angular-build-info`,
110123
);
111124

112125
signale.start("Creating `build.ts` file...");
113126

114127
const template = {
115-
user: "Octocat",
116128
hash: "1e872b5",
129+
timestamp: moment().format("MMMM DD, YYYY HH:mm:ss"),
130+
user: "Octocat",
117131
version: "1.0.0",
118-
timestamp: moment().format("MMMM DD, YYYY HH:mm:ss")
119132
};
120133

121134
// Try writing file, if it fails, display error message
@@ -125,12 +138,12 @@ async function init() {
125138
"// Angular build information, automatically generated by `angular-build-info`\n" +
126139
"export const buildInfo = " +
127140
JSON.stringify(template, null, 4).replace(/\"([^(\")"]+)\":/g, "$1:") +
128-
";\n"
141+
";\n",
129142
);
130143

131144
signale.success("Successfully created `build.ts` file!");
132145
signale.info(
133-
"You should now modify your build/deploy scripts in your `package.json` file to run this script every time before your Angular app is built. An example would be:"
146+
"You should now modify your build/deploy scripts in your `package.json` file to run this script every time before your Angular app is built. An example would be:",
134147
);
135148
signale.info(`[...] "build": "build-info && ng build --prod", [...]`);
136149
signale.info("Again, you can find more info on implementing this tool on the main repo.");
@@ -153,7 +166,7 @@ async function displayManual() {
153166
/**
154167
* Main function we run upon starting the script
155168
*/
156-
function start() {
169+
function start(): void {
157170
if (args.includes("--init")) {
158171
init();
159172
return;

package-lock.json

Lines changed: 17 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
{
22
"name": "angular-build-info",
33
"version": "1.0.2",
4-
"description": "A command line interface to collect information about your current build.",
4+
"description": "🛠 A command line interface to collect build information for your Angular application.",
55
"main": "index.js",
66
"bin": {
77
"angular-build-info": "bin/build-info.js"
88
},
99
"scripts": {
10-
"test": "echo \"Error: no test specified\" && exit 1"
10+
"test": "echo \"Error: no test specified\" && exit 1",
11+
"build": "tsc",
12+
"publish": "npm ci && tsc && npm publish"
1113
},
1214
"repository": {
1315
"type": "git",
@@ -30,5 +32,9 @@
3032
"dependencies": {
3133
"moment": "^2.24.0",
3234
"signale": "^1.4.0"
35+
},
36+
"devDependencies": {
37+
"@types/node": "^12.12.12",
38+
"@types/signale": "^1.2.1"
3339
}
3440
}

tsconfig.json

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"compilerOptions": {
3+
/* Basic Options */
4+
// "incremental": true, /* Enable incremental compilation */
5+
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */,
6+
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
7+
// "lib": [], /* Specify library files to be included in the compilation. */
8+
// "allowJs": true, /* Allow javascript files to be compiled. */
9+
// "checkJs": true, /* Report errors in .js files. */
10+
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
11+
// "declaration": true, /* Generates corresponding '.d.ts' file. */
12+
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
13+
// "sourceMap": true, /* Generates corresponding '.map' file. */
14+
// "outFile": "./", /* Concatenate and emit output to single file. */
15+
"outDir": "./bin" /* Redirect output structure to the directory. */,
16+
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
17+
// "composite": true, /* Enable project compilation */
18+
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
19+
// "removeComments": true, /* Do not emit comments to output. */
20+
// "noEmit": true, /* Do not emit outputs. */
21+
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
22+
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
23+
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
24+
25+
/* Strict Type-Checking Options */
26+
"strict": true /* Enable all strict type-checking options. */,
27+
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
28+
// "strictNullChecks": true, /* Enable strict null checks. */
29+
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
30+
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
31+
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
32+
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
33+
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
34+
35+
/* Additional Checks */
36+
// "noUnusedLocals": true, /* Report errors on unused locals. */
37+
// "noUnusedParameters": true, /* Report errors on unused parameters. */
38+
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
39+
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
40+
41+
/* Module Resolution Options */
42+
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
43+
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
44+
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
45+
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
46+
// "typeRoots": [], /* List of folders to include type definitions from. */
47+
// "types": [], /* Type declaration files to be included in compilation. */
48+
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
49+
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
50+
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
51+
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
52+
53+
/* Source Map Options */
54+
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
55+
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
56+
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
57+
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
58+
59+
/* Experimental Options */
60+
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
61+
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
62+
63+
/* Advanced Options */
64+
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
65+
"resolveJsonModule": true
66+
}
67+
}

tslint.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"defaultSeverity": "error",
3+
"extends": [
4+
"tslint:recommended"
5+
],
6+
"jsRules": {},
7+
"rules": {},
8+
"rulesDirectory": []
9+
}

0 commit comments

Comments
 (0)