harper.js 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs.sh CHANGED
@@ -14,7 +14,7 @@ for file in ./markdown/*.md
14
14
  do
15
15
  BASE=$(basename $file .md)
16
16
  pandoc $file -o html/$BASE.html
17
- sed -i 's/"\(.*\).md"/"\1.html"/g' html/$BASE.html
17
+ perl -pi -e 's/"\K([^"]+)\.md(?=")/\1.html/g' html/$BASE.html
18
18
 
19
19
  echo '<link rel="stylesheet" href="https://unpkg.com/mvp.css">' >> html/$BASE.html
20
20
  done
@@ -1,6 +1,5 @@
1
- import * as harper from 'harper.js';
2
-
3
1
  async function main() {
2
+ const harper = await import('harper.js');
4
3
  // We cannot use `WorkerLinter` on Node.js since it relies on web-specific APIs.
5
4
  let linter = new harper.LocalLinter();
6
5
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "harper.js",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Elijah Potter",
6
6
  "description": "The grammar checker for developers.",
@@ -131,6 +131,44 @@ for (const [linterName, Linter] of Object.entries(linters)) {
131
131
  expect(value).not.toBeNull();
132
132
  }
133
133
  });
134
+
135
+ test(`${linterName} can ignore lints`, async () => {
136
+ const linter = new Linter();
137
+ const source = 'This is an test.';
138
+
139
+ const firstRound = await linter.lint(source);
140
+
141
+ expect(firstRound.length).toBeGreaterThanOrEqual(1);
142
+
143
+ await linter.ignoreLint(firstRound[0]);
144
+
145
+ const secondRound = await linter.lint(source);
146
+
147
+ expect(secondRound.length).toBeLessThan(firstRound.length);
148
+ });
149
+
150
+ test(`${linterName} can reimport ignored lints.`, async () => {
151
+ const source = 'This is an test of xporting lints.';
152
+
153
+ const firstLinter = new Linter();
154
+
155
+ const firstLints = await firstLinter.lint(source);
156
+
157
+ for (const lint of firstLints) {
158
+ await firstLinter.ignoreLint(lint);
159
+ }
160
+
161
+ const exported = await firstLinter.exportIgnoredLints();
162
+
163
+ /// Create a new instance and reimport the lints.
164
+ const secondLinter = new Linter();
165
+ await secondLinter.importIgnoredLints(exported);
166
+
167
+ const secondLints = await secondLinter.lint(source);
168
+
169
+ expect(firstLints.length).toBeGreaterThan(secondLints.length);
170
+ expect(secondLints.length).toBe(0);
171
+ });
134
172
  }
135
173
 
136
174
  test('Linters have the same config format', async () => {
package/src/Linter.ts CHANGED
@@ -50,4 +50,17 @@ export default interface Linter {
50
50
 
51
51
  /** Convert a string to Chicago-style title case. */
52
52
  toTitleCase(text: string): Promise<string>;
53
+
54
+ /** Ignore future instances of a lint from a previous linting run in future invocations. */
55
+ ignoreLint(lint: Lint): Promise<void>;
56
+
57
+ /** Export the ignored lints to a JSON list of privacy-respecting hashes. */
58
+ exportIgnoredLints(): Promise<string>;
59
+
60
+ /** Import ignored lints from a JSON list to the linter.
61
+ * This function appends to the existing lints, if any. */
62
+ importIgnoredLints(json: string): Promise<void>;
63
+
64
+ /** Clear records of all previously ignored lints. */
65
+ clearIgnoredLints(): Promise<void>;
53
66
  }
@@ -97,4 +97,28 @@ export default class LocalLinter implements Linter {
97
97
  await this.initialize();
98
98
  return this.inner!.get_lint_descriptions_as_json();
99
99
  }
100
+
101
+ async ignoreLint(lint: Lint): Promise<void> {
102
+ await this.initialize();
103
+
104
+ this.inner!.ignore_lint(lint);
105
+ }
106
+
107
+ async exportIgnoredLints(): Promise<string> {
108
+ await this.initialize();
109
+
110
+ return this.inner!.export_ignored_lints();
111
+ }
112
+
113
+ async importIgnoredLints(json: string): Promise<void> {
114
+ await this.initialize();
115
+
116
+ return this.inner!.import_ignored_lints(json);
117
+ }
118
+
119
+ async clearIgnoredLints(): Promise<void> {
120
+ await this.initialize();
121
+
122
+ return this.inner!.clear_ignored_lints();
123
+ }
100
124
  }
@@ -113,6 +113,22 @@ export default class WorkerLinter implements Linter {
113
113
  return JSON.parse(await this.getDefaultLintConfigAsJSON()) as LintConfig;
114
114
  }
115
115
 
116
+ async ignoreLint(lint: Lint): Promise<void> {
117
+ return this.rpc('ignoreLint', [lint]);
118
+ }
119
+
120
+ async exportIgnoredLints(): Promise<string> {
121
+ return this.rpc('exportIgnoredLints', []);
122
+ }
123
+
124
+ async importIgnoredLints(json: string): Promise<void> {
125
+ return this.rpc('importIgnoredLints', [json]);
126
+ }
127
+
128
+ async clearIgnoredLints(): Promise<void> {
129
+ return this.rpc('clearIgnoredLints', []);
130
+ }
131
+
116
132
  /** Run a procedure on the remote worker. */
117
133
  private async rpc(procName: string, args: any[]): Promise<any> {
118
134
  const promise = new Promise((resolve, reject) => {