Skip to content

Commit

Permalink
feat: rewrite to TypeScript … (#202)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Drop Flow, bump minimum Node version to 12.

Co-authored-by: Matthew Fernando Garcia <[email protected]>
  • Loading branch information
wtgtybhertgeghgtwtg and Matthew Fernando Garcia authored Dec 19, 2020
1 parent f3b0c37 commit 459f335
Show file tree
Hide file tree
Showing 49 changed files with 1,545 additions and 2,343 deletions.
9 changes: 3 additions & 6 deletions .babelrc.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
module.exports = {
plugins: [
'@babel/proposal-nullish-coalescing-operator',
'@babel/proposal-optional-chaining',
],
plugins: ['@babel/proposal-nullish-coalescing-operator'],
presets: [
[
'@babel/env',
{
modules: process.env.NODE_ENV === 'test' && 'commonjs',
targets: {node: '6'},
targets: {node: '12'},
},
],
'@babel/flow',
'@babel/typescript',
],
};
8 changes: 4 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
jobs:
lint:
docker:
- image: circleci/node:8
- image: circleci/node:12
steps:
- checkout
- restore_cache:
Expand All @@ -18,7 +18,7 @@ jobs:

release:
docker:
- image: circleci/node:8
- image: circleci/node:12
steps:
- checkout
- restore_cache:
Expand All @@ -35,7 +35,7 @@ jobs:

test:
docker:
- image: circleci/node:8
- image: circleci/node:12
steps:
- checkout
- restore_cache:
Expand All @@ -52,7 +52,7 @@ jobs:

test-dist:
docker:
- image: circleci/node:8
- image: circleci/node:12
steps:
- checkout
- restore_cache:
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
coverage/*
dist/*
flow-typed/*
node_modules/*
57 changes: 57 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const rushstackEslintConfig = require('@rushstack/eslint-config/profile/node');
const assert = require('assert');
const path = require('path');
const {isDeepStrictEqual} = require('util');

// Rushstack: "This is a workaround for https://github.com/eslint/eslint/issues/3458".
require('@rushstack/eslint-config/patch/modern-module-resolution');

// ESLint configuration is not user-friendly.
const overrides = rushstackEslintConfig.overrides.filter((override) =>
isDeepStrictEqual(override.files, ['*.ts', '*.tsx']),
);
assert(
overrides.length === 1,
"The assumption for locating the .ts override in '@rushstack/eslint-config' is faulty.",
);

module.exports = {
extends: [
'@rushstack/eslint-config/profile/node',
'@rushstack/eslint-config/mixins/tsdoc',
'plugin:eslint-comments/recommended',
'plugin:unicorn/recommended',
],
overrides: [
{
files: ['types/*.d.ts'],
rules: {
// Type files should have the name of the packages that use them, which don't necessarily follow this rule (e.g. `JSONStream`).
'unicorn/filename-case': 'off',
},
},
{
files: ['*.ts'],
rules: {
'@rushstack/typedef-var': 'off',
// Rationale: https://github.com/microsoft/rushstack/blob/63777148e110b2d9b690e60d74e58af03d0e7b7e/stack/eslint-config/index.js#L327-L332
'@typescript-eslint/naming-convention': overrides[0].rules[
'@typescript-eslint/naming-convention'
].map((value) =>
typeof value === 'object' && value.selector === 'interface'
? {format: ['PascalCase'], selector: 'interface'}
: value,
),
},
},
],
parserOptions: {
project: path.join(__dirname, './tsconfig.json'),
},
rules: {
'eslint-comments/no-unused-disable': 'error',
// Since this is covered by 'eslint-comments/no-unlimited-disable'.
'unicorn/no-abusive-eslint-disable': 'off',
'unicorn/no-unsafe-regex': 'error',
},
};
22 changes: 0 additions & 22 deletions .eslintrc.yml

This file was deleted.

11 changes: 0 additions & 11 deletions .flowconfig

This file was deleted.

4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
coverage
dist
lib
node_modules
yarn.lock
yarn-debug.log*
yarn-error.log*
*.log*
3 changes: 3 additions & 0 deletions .huskyrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
hooks:
commit-msg: commitlint -e $HUSKY_GIT_PARAMS
pre-commit: tsc && cross-env NODE_ENV=test lint-staged
3 changes: 0 additions & 3 deletions .huskyrc.yml

This file was deleted.

6 changes: 6 additions & 0 deletions .lintstagedrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'*.{json,md,yaml}':
- 'prettier --write'
'*.{js,ts}':
- 'prettier --write'
- 'eslint --fix'
- 'jest --config ./scripts/jest/config.source.js --bail --findRelatedTests'
9 changes: 0 additions & 9 deletions .lintstagedrc.yml

This file was deleted.

File renamed without changes.
37 changes: 13 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,24 @@ $ yarn add env-and-files
```js
const {loadConfig} = require('env-and-files');

loadConfig({
// A conceptual grouping of configuration properties. In this case, configuration for the logger.
logger: {
// The "logger.level" property will be equal to the "LOG_LEVEL" environmental variable, or undefined if it is not present.
level: 'LOG_LEVEL',
loadConfigSync({
postgresPassword: {
filePath: '/secrets/password',
},
server: {
port: {
// Specify that this property is required. If "PORT" is not found, an error will be given.
required: true,
// Coerce the value to a number. If it can't be coerced, an error will be given.
type: 'number',
variableName: 'PORT',
},
postgresUrl: {
format: (value) => new URL(value),
variableName: 'POSTGRES_URL',
},
sql: {
password: {
// The "sql.password" property will be equal to the contents of "/path/to/secret", or undefined if it could not be read.
filePath: '/path/to/secret',
required: true,
},
postgresUsername: {
defaultValue: 'postgres',
filePath: '/secrets/username',
},
})
.then(config => {
// "config" will be an object map of configuration groups. So, you'd get something like
// { logger: { level: undefined }, server: { port: 8000 }, sql: { password: 'abc123' } }
.then((config) => {
// "config" will be an object map of configuration properties.
console.log(config);
})
.catch(error => {
.catch((error) => {
// If any of the required properties cannot be loaded, the Promise will reject.
console.error(error);
});
Expand All @@ -65,7 +54,7 @@ Load configuration. Returns a `Promise` that will resolve to the loaded configur

Type: `Object`

An object map of conceptual groupings of necessary configuration and where to find it. By default, all configuration properties are optional, but if one is marked required and is not found, an error will be given. See [usage](#usage) for examples of config maps.
An object map of configuration and where to find it. By default, all configuration properties are required. See [usage](#usage) for examples of config maps.

### loadConfigSync(configMap)

Expand Down
19 changes: 10 additions & 9 deletions __mocks__/fs.js → __mocks__/fs.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
// @flow
import mapToMap from 'map-to-map';

let files: Map<string, Buffer> = new Map();

function __setFiles(newFiles: {[path: string]: Buffer}) {
function _setFiles(newFiles: {[path: string]: Buffer}): void {
files = mapToMap(newFiles);
}

// $FlowFixMe
const readFile = jest.fn(
(
path: string,
encoding: buffer$Encoding,
callback: (error: ?Error, value: ?string) => void,
encoding: BufferEncoding,
// eslint-disable-next-line @rushstack/no-new-null
callback: (error: Error | null, value?: string) => void,
) => {
const file = files.get(path);
if (file && Buffer.isBuffer(file)) {
const decodedFile = file.toString(encoding);
// eslint-disable-next-line unicorn/no-null
callback(null, decodedFile);
} else {
const error = new Error();
callback(error, null);
const error = new Error('File not found.');
callback(error);
}
},
);

// $FlowFixMe
const readFileSync = jest.fn((path: string, encoding: buffer$Encoding) => {
const readFileSync = jest.fn((path: string, encoding: BufferEncoding) => {
const file = files.get(path);
if (file && Buffer.isBuffer(file)) {
return file.toString(encoding);
}
throw new Error();
throw new Error('File not found.');
});

module.exports = {
__setFiles,
_setFiles,
readFile,
readFileSync,
};
Loading

0 comments on commit 459f335

Please sign in to comment.