Skip to content

Commit dd1c4e0

Browse files
TypeScript rewrite (#591)
* First steps towards TypeScript conversion * Convert xml.js->xml.ts * Add compilation to build step * Rewrite base.js in TypeScript (maybe shit, need to review own work once I'm done) * Rewrite json.js -> json.ts and get tests passing (I'm honestly shocked they passed) * array.js -> array.ts * character.js -> character.ts * css.js->css.ts * sentence.js->sentence.ts * word.js -> word.ts * line.js -> line.ts * index.js->index.ts * Convert a couple more fiiles * Convert params.ts * string.js -> string.ts * Partly convert patch-related files to TypeScript; more to do * Type more stuff * Begin converting line-endings.js. Interesting TypeScript bug along the way. * Bump TypeScript * Add link to bug report * Finish converted line-endings.js to TypeScript * Add missing overloads to support case where argument type isn't known statically * reverse.js -> reverse.ts * add todo * Rewrite base.ts types (breaks everything for now) * Per-diff-function options types. Still not compiling but close. * Fix build * Run 'yarn add @eslint/js typescript-eslint --save-dev' as suggested at https://typescript-eslint.io/getting-started * Turn on recommended eslint rules as recommended by Getting Started guide at https://typescript-eslint.io/packages/typescript-eslint/#config * Get linting of TypeScript working (now with the officially recommended rules) * yarn lint --fix * Tweak some indentation that eslint broke * Fix a couple of linting errors * Allow explicit 'any' I'm using it and it's convenient. In some places like diffArrays where we allow arrays of arbitrary type, I don't even know how to NOT use it. * Eliminate needless explicit respecification of rules that eslint.configs.recommended already enables * Fix another eslint config bug * Start using arrow functions and thereby resolve a https://typescript-eslint.io/rules/no-this-alias/ error I wasn't using them before because I wasn't sure if our build process would turn them into normal functions for compatability with old JS environments; it turns out it does, so we're fine. * Fix some linting errors about pointless escape sequences * Fix more linting errors about pointless escape sequences * Eliminate a util made redundant by Object.keys, and fix a linting error in the process * Fix a no-prototype-builtins linting error * Disable no-use-before-define for TypeScript code, where it's broken * Liberalise more rules * Fix lint errors in parse.ts * Fix lint errors in apply.ts * Fix remaining linting errors * Add missing newline at EOF * Remove a couple of unused ts-expect-error directives. (My editor was showing errors but tsc doesn't.) * create.js->create.ts * Fix some linting errors * Lint on build, like before * Generate type declarations on build * Migrate to using tsconfig.json instead of CLI args * Start adding tsd tests... but actually maybe should use dtslint? * Correctly mark a load of arguments as optional * convert tests to tsd style * Fix type test * Fix some more type test things * Undo some testing silliness * aaaaaaaaaaargh * Get most of the way to fixing type definitions based on #303 (comment). Doesn't compile yet. * Fix index.ts * Fix remaining compilation errors * Restore 'Change' type from DefinitelyTyped * tsd test syntax fix * Fix: oldHeader & newHeader are allowed to be explicitly given as undefined * Fix 'Abortable' types in patch/create * Fix another typing error * Fix error-handling-related types in patch/apply * Analyse errors I'm seeing in tests copied from DT & add TODOs * Begin adding some docs * Fix a load of test cases where the DT behaviour was just wrong * Make diffArrays generic instead of using any * Make DiffArraysOptions types generic * Rename ParsedDiff -> StructuredPatch * Export ApplyPatchOptions, ApplyPatchesOptions * Make all methods public for backwards compat * Fix remaining type error * Fix ignoring of test-d * Copy latest change from DT (DefinitelyTyped/DefinitelyTyped@2cfdb9f) * Flesh out docs * Resolve ignoreWhitespace dilemma * nah * Remove obsolete TODOs * Fix bad .gitignore rule * Add another type test file * v0.0.1 * v0.0.2 * .npmignore more stuff * Move test-d/ out of types/ so yarn clean won't delete it * Add attw * durrrr * failed fix attempt * Get attw passing (hallelujah!) * Enable "strict": true * Fix a strict mode error * Fix a strict mode error * Fix more strict mode errors * Silence a silly strict mode error * Further placate strict mode * Further placate strict mode * Fix a legit type error that strict mode found * Further placate strict mode * Get TypeScript happy with create.ts * Further placate strict mode * Further placate strict mode * Placate compiler about apply.ts * Fix a load more strict mode errors * Placate strict mode further * Fix some more compilation errors * Fix one more compilation error * Fix remaining base.ts errors * Fix line.ts * Type a variable to remove a slew of compilation errors * Add more types to resolve more errors * Add even more types to resolve even more errors * Fix remaining type errors. Huzzah!!! * Address verbatimModuleSyntax guidance * Remove obsolete comment * Get @typescript-eslint/consistent-type-exports enabled * Un-disable no-duplicate-type-constituents and let it autofix. I guess I was confused. * Reenable another rule * Remove no-longer-needed gitignore rule from earlier in this PR * Remove an obsolete disabling of a rule from early in my eslint tinkering. No longer makes sense. * Fix deps being wrongly declared as non-dev deps * Bump new deps to latest * Re-add support for imports from /lib/, maybe? * Restore support for subpath imports in Node 12.19 and earlier (see #351 (comment)). * Restore es5 support * Improve docs; add more exports to obviate need to import stuff from lib/ * Fix rollup * Improve docs; restore package.json top-level fields that maybe are useful for compatibility with something, somewhere * Stop using babel with rollup. Doesn't seem to really affect anything. Output in dist/diff.js is almost identical; just formatting changes and a handful of other things that look inconsequential. * Remove unused dependency on Babel CLI * Remove another unused dep * Get karma working * Remove apparently unneeded eslint ignore directives * Fix misplaced bullet in release notes * bah * Begin the tedious work of copying and pasting the README documentation into the function comments, so it can show up in people's editors * More copying and pasting. I should probably test this before moving on * More copying and pasting of docs * Finish pasting docs * Revert temporary package name change * Hackily resolve the Intl.Segmenter issue
1 parent 2c36f81 commit dd1c4e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+3647
-1480
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
coverage
22
node_modules
3-
lib
3+
libesm
4+
libcjs
45
dist
56
yarn-error.log
67
.vscode

.npmignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
.babelrc
2-
.eslintrc
2+
.eslint.config.mjs
33
.gitignore
44
.npmignore
55
.vscode
66
.nyc_output
7+
test-d
78
components
89
coverage
910
examples
@@ -15,5 +16,6 @@ runtime.js
1516
src
1617
tasks
1718
test
19+
tsconfig.json
1820
yarn-error.log
1921
yarn.lock

README.md

Lines changed: 68 additions & 36 deletions
Large diffs are not rendered by default.

eslint.config.mjs

Lines changed: 178 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -1,176 +1,182 @@
1-
import globals from "globals";
2-
import babelParser from "@babel/eslint-parser";
3-
4-
export default [
5-
{
6-
languageOptions: {
7-
globals: {
8-
...globals.browser,
9-
},
10-
11-
parser: babelParser,
12-
},
13-
14-
rules: {
15-
// Possible Errors //
16-
//-----------------//
17-
"comma-dangle": [2, "never"],
18-
"no-cond-assign": [2, "except-parens"],
19-
"no-console": 1, // Allow for debugging
20-
"no-constant-condition": 2,
21-
"no-control-regex": 2,
22-
"no-debugger": 1, // Allow for debugging
23-
"no-dupe-args": 2,
24-
"no-dupe-keys": 2,
25-
"no-duplicate-case": 2,
26-
"no-empty": 2,
27-
"no-empty-character-class": 2,
28-
"no-ex-assign": 2,
29-
"no-extra-boolean-cast": 2,
30-
"no-extra-parens": [2, "functions"],
31-
"no-extra-semi": 2,
32-
"no-func-assign": 2,
33-
"no-invalid-regexp": 2,
34-
"no-irregular-whitespace": 2,
35-
"no-negated-in-lhs": 2,
36-
"no-obj-calls": 2,
37-
"no-regex-spaces": 2,
38-
"no-unreachable": 1, // Optimizer and coverage will handle/highlight this and can be useful for debugging
39-
"use-isnan": 2,
40-
"valid-typeof": 2,
41-
42-
// Best Practices //
43-
//----------------//
44-
curly: 2,
45-
"default-case": 1,
46-
47-
"dot-notation": [2, {
48-
allowKeywords: false,
49-
}],
50-
51-
"guard-for-in": 1,
52-
"no-alert": 2,
53-
"no-caller": 2,
54-
"no-div-regex": 1,
55-
"no-eval": 2,
56-
"no-extend-native": 2,
57-
"no-extra-bind": 2,
58-
"no-fallthrough": 2,
59-
"no-floating-decimal": 2,
60-
"no-implied-eval": 2,
61-
"no-iterator": 2,
62-
"no-labels": 2,
63-
"no-lone-blocks": 2,
64-
"no-multi-spaces": 2,
65-
"no-multi-str": 1,
66-
"no-native-reassign": 2,
67-
"no-new": 2,
68-
"no-new-func": 2,
69-
"no-new-wrappers": 2,
70-
"no-octal": 2,
71-
"no-octal-escape": 2,
72-
"no-process-env": 2,
73-
"no-proto": 2,
74-
"no-redeclare": 2,
75-
"no-return-assign": 2,
76-
"no-script-url": 2,
77-
"no-self-compare": 2,
78-
"no-sequences": 2,
79-
"no-throw-literal": 2,
80-
"no-unused-expressions": 2,
81-
"no-warning-comments": 1,
82-
"no-with": 2,
83-
radix: 2,
84-
"wrap-iife": 2,
85-
86-
// Variables //
87-
//-----------//
88-
"no-catch-shadow": 2,
89-
"no-delete-var": 2,
90-
"no-label-var": 2,
91-
"no-undef": 2,
92-
"no-undef-init": 2,
93-
94-
"no-unused-vars": [2, {
95-
vars: "all",
96-
args: "after-used",
97-
}],
98-
99-
"no-use-before-define": [2, "nofunc"],
100-
101-
// Node.js //
102-
//---------//
103-
104-
// Stylistic //
105-
//-----------//
106-
"brace-style": [2, "1tbs", {
107-
allowSingleLine: true,
108-
}],
109-
110-
camelcase: 2,
111-
112-
"comma-spacing": [2, {
113-
before: false,
114-
after: true,
115-
}],
1+
// @ts-check
1162

117-
"comma-style": [2, "last"],
118-
"consistent-this": [1, "self"],
119-
"eol-last": 2,
120-
"func-style": [2, "declaration"],
121-
122-
"key-spacing": [2, {
123-
beforeColon: false,
124-
afterColon: true,
125-
}],
126-
127-
"new-cap": 2,
128-
"new-parens": 2,
129-
"no-array-constructor": 2,
130-
"no-lonely-if": 2,
131-
"no-mixed-spaces-and-tabs": 2,
132-
"no-nested-ternary": 1,
133-
"no-new-object": 2,
134-
"no-spaced-func": 2,
135-
"no-trailing-spaces": 2,
136-
137-
"quote-props": [2, "as-needed", {
138-
keywords: true,
139-
}],
140-
141-
quotes: [2, "single", "avoid-escape"],
142-
semi: 2,
143-
144-
"semi-spacing": [2, {
145-
before: false,
146-
after: true,
147-
}],
148-
149-
"space-before-blocks": [2, "always"],
150-
151-
"space-before-function-paren": [2, {
152-
anonymous: "never",
153-
named: "never",
154-
}],
3+
import eslint from '@eslint/js';
4+
import tseslint from 'typescript-eslint';
5+
import globals from "globals";
1556

156-
"space-in-parens": [2, "never"],
157-
"space-infix-ops": 2,
158-
"space-unary-ops": 2,
159-
"spaced-comment": [2, "always"],
160-
"wrap-regex": 1,
161-
"no-var": 2,
162-
},
7+
export default tseslint.config(
8+
{
9+
ignores: [
10+
"**/*", // ignore everything...
11+
"!src/**/", "!src/**/*.ts", // ... except our TypeScript source files...
12+
"!test/**/", "!test/**/*.js", // ... and our tests
13+
],
14+
},
15+
eslint.configs.recommended,
16+
tseslint.configs.recommended,
17+
{
18+
files: ['src/**/*.ts'],
19+
languageOptions: {
20+
parserOptions: {
21+
projectService: true,
22+
tsconfigRootDir: import.meta.dirname,
23+
},
16324
},
164-
{
165-
files: ['test/**/*.js'],
166-
languageOptions: {
167-
globals: {
168-
...globals.node,
169-
...globals.mocha,
170-
},
171-
},
172-
rules: {
173-
"no-unused-expressions": 0, // Needs disabling to support Chai `.to.be.undefined` etc syntax
174-
},
25+
extends: [tseslint.configs.recommendedTypeChecked],
26+
rules: {
27+
// Not sure if these actually serve a purpose, but they provide a way to enforce SOME of what
28+
// would be imposed by having "verbatimModuleSyntax": true in our tsconfig.json without
29+
// actually doing that.
30+
"@typescript-eslint/consistent-type-imports": 2,
31+
"@typescript-eslint/consistent-type-exports": 2,
32+
33+
// Things from the recommendedTypeChecked shared config that are disabled simply because they
34+
// caused lots of errors in our existing code when tried. Plausibly useful to turn on if
35+
// possible and somebody fancies doing the work:
36+
"@typescript-eslint/no-unsafe-argument": 0,
37+
"@typescript-eslint/no-unsafe-assignment": 0,
38+
"@typescript-eslint/no-unsafe-call": 0,
39+
"@typescript-eslint/no-unsafe-member-access": 0,
40+
"@typescript-eslint/no-unsafe-return": 0,
17541
}
176-
];
42+
},
43+
{
44+
languageOptions: {
45+
globals: {
46+
...globals.browser,
47+
},
48+
},
49+
50+
rules: {
51+
// Possible Errors //
52+
//-----------------//
53+
"comma-dangle": [2, "never"],
54+
"no-console": 1, // Allow for debugging
55+
"no-debugger": 1, // Allow for debugging
56+
"no-extra-parens": [2, "functions"],
57+
"no-extra-semi": 2,
58+
"no-negated-in-lhs": 2,
59+
"no-unreachable": 1, // Optimizer and coverage will handle/highlight this and can be useful for debugging
60+
61+
// Best Practices //
62+
//----------------//
63+
curly: 2,
64+
"default-case": 1,
65+
"dot-notation": [2, {
66+
allowKeywords: false,
67+
}],
68+
"guard-for-in": 1,
69+
"no-alert": 2,
70+
"no-caller": 2,
71+
"no-div-regex": 1,
72+
"no-eval": 2,
73+
"no-extend-native": 2,
74+
"no-extra-bind": 2,
75+
"no-floating-decimal": 2,
76+
"no-implied-eval": 2,
77+
"no-iterator": 2,
78+
"no-labels": 2,
79+
"no-lone-blocks": 2,
80+
"no-multi-spaces": 2,
81+
"no-multi-str": 1,
82+
"no-native-reassign": 2,
83+
"no-new": 2,
84+
"no-new-func": 2,
85+
"no-new-wrappers": 2,
86+
"no-octal-escape": 2,
87+
"no-process-env": 2,
88+
"no-proto": 2,
89+
"no-return-assign": 2,
90+
"no-script-url": 2,
91+
"no-self-compare": 2,
92+
"no-sequences": 2,
93+
"no-throw-literal": 2,
94+
"no-unused-expressions": 2,
95+
"no-warning-comments": 1,
96+
radix: 2,
97+
"wrap-iife": 2,
98+
99+
// Variables //
100+
//-----------//
101+
"no-catch-shadow": 2,
102+
"no-label-var": 2,
103+
"no-undef-init": 2,
104+
105+
// Node.js //
106+
//---------//
107+
108+
// Stylistic //
109+
//-----------//
110+
"brace-style": [2, "1tbs", {
111+
allowSingleLine: true,
112+
}],
113+
camelcase: 2,
114+
"comma-spacing": [2, {
115+
before: false,
116+
after: true,
117+
}],
118+
"comma-style": [2, "last"],
119+
"consistent-this": [1, "self"],
120+
"eol-last": 2,
121+
"func-style": [2, "declaration"],
122+
"key-spacing": [2, {
123+
beforeColon: false,
124+
afterColon: true,
125+
}],
126+
"new-cap": 2,
127+
"new-parens": 2,
128+
"no-array-constructor": 2,
129+
"no-lonely-if": 2,
130+
"no-mixed-spaces-and-tabs": 2,
131+
"no-nested-ternary": 1,
132+
"no-new-object": 2,
133+
"no-spaced-func": 2,
134+
"no-trailing-spaces": 2,
135+
"quote-props": [2, "as-needed", {
136+
keywords: true,
137+
}],
138+
quotes: [2, "single", "avoid-escape"],
139+
semi: 2,
140+
"semi-spacing": [2, {
141+
before: false,
142+
after: true,
143+
}],
144+
"space-before-blocks": [2, "always"],
145+
"space-before-function-paren": [2, {
146+
anonymous: "never",
147+
named: "never",
148+
}],
149+
"space-in-parens": [2, "never"],
150+
"space-infix-ops": 2,
151+
"space-unary-ops": 2,
152+
"spaced-comment": [2, "always"],
153+
"wrap-regex": 1,
154+
"no-var": 2,
155+
156+
// Typescript //
157+
//------------//
158+
"@typescript-eslint/no-explicit-any": 0, // Very strict rule, incompatible with our code
159+
160+
// We use these intentionally - e.g.
161+
// export interface DiffCssOptions extends CommonDiffOptions {}
162+
// for the options argument to diffCss which currently takes no options beyond the ones
163+
// common to all diffFoo functions. Doing this allows consistency (one options interface per
164+
// diffFoo function) and future-proofs against the API having to change in future if we add a
165+
// non-common option to one of these functions.
166+
"@typescript-eslint/no-empty-object-type": [2, {allowInterfaces: 'with-single-extends'}],
167+
},
168+
},
169+
{
170+
files: ['test/**/*.js'],
171+
languageOptions: {
172+
globals: {
173+
...globals.node,
174+
...globals.mocha,
175+
},
176+
},
177+
rules: {
178+
"no-unused-expressions": 0, // Needs disabling to support Chai `.to.be.undefined` etc syntax
179+
"@typescript-eslint/no-unused-expressions": 0, // (as above)
180+
},
181+
}
182+
);

0 commit comments

Comments
 (0)