Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Even Better TS #307

Merged
merged 9 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ jobs:
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Git checkout
# Pin actions their full commit hashes to prevent supply-chain attacks.
# To update, find the latest tag on the releases page,
# then copy the full SHA and paste it back here (and update the comment).
# Alternatively, setup Dependabot for the `github-actions` ecosystem.
lishaduck marked this conversation as resolved.
Show resolved Hide resolved
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
submodules: recursive
Expand Down
61 changes: 0 additions & 61 deletions lib/core.js

This file was deleted.

4 changes: 2 additions & 2 deletions lib/fs-wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ function readJsonFileSync(file) {
* Read a file using Promises.
*
* @param {Path} file
* @param {fs.BaseEncodingOptions & { flag?: fs.OpenMode | undefined }} [options]
* @param {fs.BaseEncodingOptions & { flag?: fs.OpenMode | undefined }} [options={encoding: 'utf8'}]
* @returns {Promise<string>}
*/
async function readFile(file, options) {
async function readFile(file, options = {}) {
const data = await fsp.readFile(file, {encoding: 'utf8', ...options});
return data.toString();
}
Expand Down
3 changes: 2 additions & 1 deletion lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ async function runElmReviewInWatchMode() {

if (!elmModulePath) {
Watch.watchConfiguration(
/** @type {ReviewOptions} */ (options),
// @ts-expect-error(TS2345): `Options` aren't assignable to `ReviewOptions`.
options,
reviewElmJson,
reviewElmJsonPath,
() => {
Expand Down
30 changes: 14 additions & 16 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,23 +50,21 @@ function compute(processArgv) {
processArgv.slice(2).includes('--help') ||
processArgv.slice(2).includes('-h');

const args = /** @type {ParsedArgs} */ (
minimist(processArgv.slice(2), {
alias: Flags.flags.reduce((object, flag) => {
if (flag.alias !== undefined) {
object[flag.name] = flag.alias;
}
const args = minimist(processArgv.slice(2), {
alias: Flags.flags.reduce((object, flag) => {
if (flag.alias !== undefined) {
object[flag.name] = flag.alias;
}

return object;
}, /** @type {Record<string, string>} */ ({})),
boolean: Flags.flags.flatMap((flag) => (flag.boolean ? [flag.name] : [])),
default: {
color: true,
details: true
},
unknown: containsHelp ? () => true : unknownCheck()
})
);
return object;
}, /** @type {Record<string, string>} */ ({})),
boolean: Flags.flags.flatMap((flag) => (flag.boolean ? [flag.name] : [])),
default: {
color: true,
details: true
},
unknown: containsHelp ? () => true : unknownCheck()
});

/** @type {Subcommand | null} */
const subcommand =
Expand Down
2 changes: 1 addition & 1 deletion lib/result-cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ async function load(options, ignoredDirs, ignoredFiles, cacheFolder) {
* @returns {CacheKey}
*/
function key(ruleName, ruleId) {
return /** @type {CacheKey} */ (`${ruleName}-${ruleId}`);
return `${ruleName}-${ruleId}`;
}

/**
Expand Down
61 changes: 61 additions & 0 deletions lib/result.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Port of `elm/core` primitives to TS.
* Enables functional-style programming without having to pull in `Effect.TS`.
*/

/**
* @import {Fail, Success, Result} from './types/result';
*/

const {intoError} = require('./utils');

/**
* Create a successful result.
*
* @template Value
*
* @param {Value} value
* @returns {Success<Value>}
*/
function succeed(value) {
return {tag: 'ok', value};
}

/**
* Create a failed result.
*
* @template Failure
*
* @param {Failure} failure
* @returns {Fail<Failure>}
*/
function fail(failure) {
return {tag: 'fail', failure};
}

/**
* Returns the value of a result, or throws if in an errored state.
*
* @remarks
* Converts errors into {@linkcode Error}s before throwing.
* For more details, see {@linkcode intoError}.
*
* @template Value
*
* @param {Result<unknown, Value>} value
* @returns {Value}
* @throws {Error}
*/
function orThrow(value) {
if (value.tag === 'ok') {
return value.value;
}

throw intoError(value.failure);
}

module.exports = {
succeed,
fail,
orThrow
};
6 changes: 3 additions & 3 deletions lib/sync-get-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

const https = require('node:https');
const workerThreads = require('node:worker_threads');
const {result} = require('./core');
const Result = require('./result');

/** @type {WorkerThreads<WorkerData>} */
const {parentPort, workerData} = workerThreads;
Expand All @@ -17,11 +17,11 @@ if (parentPort) {
try {
const response = await getBody(url);
requestPort.postMessage(
/** @satisfies {PortResponse} */ (result.succeed(response))
/** @satisfies {PortResponse} */ (Result.succeed(response))
);
} catch (error) {
requestPort.postMessage(
/** @satisfies {PortResponse} */ (result.fail(error))
/** @satisfies {PortResponse} */ (Result.fail(error))
);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/sync-get.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const {
MessageChannel,
receiveMessageOnPort
} = require('node:worker_threads');
const {result} = require('./core');
const Result = require('./result');

/**
* Start a worker thread and return a `syncGetWorker`
Expand Down Expand Up @@ -43,7 +43,7 @@ function startWorker() {
return '';
}

return result.orThrow(response.message);
return Result.orThrow(response.message);
}

/**
Expand Down
3 changes: 0 additions & 3 deletions lib/types/core.ts

This file was deleted.

2 changes: 1 addition & 1 deletion lib/types/result-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ declare global {
export type RuleName = string;
export type RuleId = string;
export type CacheEntry = unknown;
export type CacheKey = `${RuleName}-${RuleId}}`;
export type CacheKey = `${RuleName}-${RuleId}`;

export type CacheData = {
filePath: Path;
Expand Down
3 changes: 3 additions & 0 deletions lib/types/result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type Result<Error, Value> = Success<Value> | Fail<Error>;
export type Success<Value> = {tag: 'ok'; value: Value};
export type Fail<Failure> = {tag: 'fail'; failure: Failure};
2 changes: 1 addition & 1 deletion lib/types/sync-get.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {MessagePort} from 'node:worker_threads';
import type {Result} from './core.ts';
import type {Result} from './result.js';

export type WorkerData = {
sharedLock: SharedArrayBuffer;
Expand Down
6 changes: 4 additions & 2 deletions lib/watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,11 @@ function watchFiles(
disableGlobbing: true
})
.on('change', async () => {
const newValue = await FS.readJsonFile(options.elmJsonPath);
const newValue = /** @type {ElmJson} */ (
await FS.readJsonFile(options.elmJsonPath)
);
if (JSON.stringify(newValue) !== JSON.stringify(elmJsonContent)) {
elmJsonContent = /** @type {ElmJson} */ (newValue);
elmJsonContent = newValue;
runReview = () => {};
clearTimeout(suppressedErrorsTimeout);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ function checkDepsAreCompatible(exampleConfiguration, previewDependencies) {

const remainingKeys = Object.keys(previewDependencies);
if (remainingKeys.length > 0) {
const extraneousDependencies = remainingKeys.join(', ');

console.error(
// prettier-ignore
`There are extraneous dependencies in the ${exampleConfiguration}/ configuration: ${remainingKeys.join(', ')}`
`There are extraneous dependencies in the ${exampleConfiguration}/ configuration: ${extraneousDependencies}`
);
process.exit(1);
}
Expand Down
Loading