tsl-dx 0.6.1 → 0.7.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/dist/index.d.ts CHANGED
@@ -39,9 +39,55 @@ declare const noDuplicateExports: (options?: "off" | undefined) => tsl.Rule<unkn
39
39
  declare const noDuplicateImports: (options?: "off" | undefined) => tsl.Rule<unknown>;
40
40
  //#endregion
41
41
  //#region src/rules/no-multiline-template-expression-without-auto-dedent.d.ts
42
- declare const noMultilineTemplateExpressionWithoutAutoDedent: (options?: "off" | undefined) => tsl.Rule<unknown>;
42
+ type noMultilineTemplateExpressionWithoutAutoDedentOptions = {
43
+ dedentTagNames?: string[];
44
+ dedentTagImportCallback?: (name: string) => string;
45
+ };
46
+ /**
47
+ * Rule to enforce the use of a dedent tag for multiline template expressions.
48
+ *
49
+ * @example
50
+ *
51
+ * ```ts
52
+ * // Incorrect
53
+ * const message = `
54
+ * Hello
55
+ * World
56
+ * `;
57
+ * ```
58
+ *
59
+ * ```ts
60
+ * // Correct
61
+ * import dedent from "dedent";
62
+ * const message = dedent`
63
+ * Hello
64
+ * World
65
+ * `;
66
+ * ```
67
+ */
68
+ declare const noMultilineTemplateExpressionWithoutAutoDedent: (options?: "off" | noMultilineTemplateExpressionWithoutAutoDedentOptions | undefined) => tsl.Rule<unknown>;
43
69
  //#endregion
44
70
  //#region src/rules/nullish.d.ts
45
- declare const nullish: (options?: Record<string, unknown> | "off" | undefined) => tsl.Rule<unknown>;
71
+ type nullishOptions = {
72
+ runtimeLibrary?: string;
73
+ };
74
+ /**
75
+ * Rule to enforce the use of `unit` instead of `undefined` and loose equality for nullish checks.
76
+ *
77
+ * @example
78
+ *
79
+ * ```ts
80
+ * // Incorrect
81
+ * let x = undefined;
82
+ * if (x === undefined) { }
83
+ * ```
84
+ *
85
+ * ```ts
86
+ * // Correct
87
+ * let x = unit;
88
+ * if (x == null) { }
89
+ * ```
90
+ */
91
+ declare const nullish: (options?: nullishOptions | "off" | undefined) => tsl.Rule<unknown>;
46
92
  //#endregion
47
93
  export { noDuplicateExports, noDuplicateImports, noMultilineTemplateExpressionWithoutAutoDedent, nullish };
package/dist/index.js CHANGED
@@ -170,6 +170,9 @@ const dual = function(arity, body) {
170
170
  * Composes two functions, `ab` and `bc` into a single function that takes in an argument `a` of type `A` and returns a result of type `C`.
171
171
  * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
172
172
  *
173
+ * @param self - The first function to apply (or the composed function in data-last style).
174
+ * @param bc - The second function to apply.
175
+ * @returns A composed function that applies both functions in sequence.
173
176
  * @example
174
177
  * ```ts
175
178
  * import * as assert from "node:assert"
@@ -277,26 +280,85 @@ function getLine(node) {
277
280
 
278
281
  //#endregion
279
282
  //#region src/rules/no-multiline-template-expression-without-auto-dedent.ts
280
- const messages$1 = { default: () => `Avoid using multiline template expression without auto-dedent` };
281
- const noMultilineTemplateExpressionWithoutAutoDedent = defineRule(() => ({
282
- name: "dx/no-multiline-template-expression-without-auto-dedent",
283
- visitor: { NoSubstitutionTemplateLiteral(ctx, node) {
284
- if (node.parent.kind === SyntaxKind.TaggedTemplateExpression) return;
285
- const [startLine, endLine] = getLine(node);
286
- if (startLine !== endLine) ctx.report({
287
- node,
288
- message: messages$1.default()
289
- });
290
- } }
291
- }));
283
+ const messages$1 = {
284
+ useDedentTag: () => "Use a dedent tag to auto-dedent this template expression's content.",
285
+ addDedentTag: (p) => `Add a/an '${p.name}' tag to this template expression to auto-dedent its content.`
286
+ };
287
+ /**
288
+ * Rule to enforce the use of a dedent tag for multiline template expressions.
289
+ *
290
+ * @example
291
+ *
292
+ * ```ts
293
+ * // Incorrect
294
+ * const message = `
295
+ * Hello
296
+ * World
297
+ * `;
298
+ * ```
299
+ *
300
+ * ```ts
301
+ * // Correct
302
+ * import dedent from "dedent";
303
+ * const message = dedent`
304
+ * Hello
305
+ * World
306
+ * `;
307
+ * ```
308
+ */
309
+ const noMultilineTemplateExpressionWithoutAutoDedent = defineRule((options) => {
310
+ const dedentTagNames = options?.dedentTagNames ?? ["dedent"];
311
+ const dedentTagImportCallback = options?.dedentTagImportCallback ?? ((name) => `import ${name} from "dedent";\n`);
312
+ return {
313
+ name: "dx/no-multiline-template-expression-without-auto-dedent",
314
+ visitor: { NoSubstitutionTemplateLiteral(ctx, node) {
315
+ if (node.parent.kind === SyntaxKind.TaggedTemplateExpression) return;
316
+ const [startLine, endLine] = getLine(node);
317
+ if (startLine !== endLine) ctx.report({
318
+ node,
319
+ message: messages$1.useDedentTag(),
320
+ suggestions: dedentTagNames.map((name) => {
321
+ return {
322
+ message: messages$1.addDedentTag({ name }),
323
+ changes: [{
324
+ start: 0,
325
+ end: 0,
326
+ newText: dedentTagImportCallback(name)
327
+ }, {
328
+ node,
329
+ newText: `${name}${node.getFullText()}`
330
+ }]
331
+ };
332
+ })
333
+ });
334
+ } }
335
+ };
336
+ });
292
337
 
293
338
  //#endregion
294
339
  //#region src/rules/nullish.ts
295
340
  const messages = {
296
341
  useUnitForUndefined: "Use 'unit' instead of 'undefined'.",
297
- useLooseNullishComparison: (p) => `Use '${p.op}' for nullish comparison.`
342
+ useLooseNullishComparison: (p) => `Use '${p.op}' for nullish comparison.`,
343
+ replaceWithExpression: (p) => `Replace with '${p.expr}'.`
298
344
  };
299
- const suggestions = { replaceWithExpression: (p) => `Replace with '${p.expr}'.` };
345
+ /**
346
+ * Rule to enforce the use of `unit` instead of `undefined` and loose equality for nullish checks.
347
+ *
348
+ * @example
349
+ *
350
+ * ```ts
351
+ * // Incorrect
352
+ * let x = undefined;
353
+ * if (x === undefined) { }
354
+ * ```
355
+ *
356
+ * ```ts
357
+ * // Correct
358
+ * let x = unit;
359
+ * if (x == null) { }
360
+ * ```
361
+ */
300
362
  const nullish = defineRule((options) => ({
301
363
  name: "dx/nullish",
302
364
  createData(ctx) {
@@ -310,14 +372,14 @@ const nullish = defineRule((options) => ({
310
372
  node,
311
373
  message: messages.useUnitForUndefined,
312
374
  suggestions: [{
313
- message: suggestions.replaceWithExpression({ expr: "unit" }),
375
+ message: messages.replaceWithExpression({ expr: "unit" }),
314
376
  changes: [{
315
- node,
316
- newText: "unit"
317
- }, {
318
377
  start: 0,
319
378
  end: 0,
320
379
  newText: `import { unit } from '${ctx.data.runtimeLibrary}';\n`
380
+ }, {
381
+ node,
382
+ newText: "unit"
321
383
  }]
322
384
  }]
323
385
  });
@@ -328,14 +390,14 @@ const nullish = defineRule((options) => ({
328
390
  node,
329
391
  message: messages.useUnitForUndefined,
330
392
  suggestions: [{
331
- message: suggestions.replaceWithExpression({ expr: "unit" }),
393
+ message: messages.replaceWithExpression({ expr: "unit" }),
332
394
  changes: [{
333
- node,
334
- newText: "unit"
335
- }, {
336
395
  start: 0,
337
396
  end: 0,
338
397
  newText: `import type { unit } from '${ctx.data.runtimeLibrary}';\n`
398
+ }, {
399
+ node,
400
+ newText: "unit"
339
401
  }]
340
402
  }]
341
403
  });
@@ -356,7 +418,7 @@ const nullish = defineRule((options) => ({
356
418
  message: messages.useLooseNullishComparison({ op: newOperatorText }),
357
419
  node,
358
420
  suggestions: [{
359
- message: suggestions.replaceWithExpression({ expr: offendingChild === node.left ? `null ${newOperatorText} ${node.right.getText()}` : `${node.left.getText()} ${newOperatorText} null` }),
421
+ message: messages.replaceWithExpression({ expr: offendingChild === node.left ? `null ${newOperatorText} ${node.right.getText()}` : `${node.left.getText()} ${newOperatorText} null` }),
360
422
  changes: [{
361
423
  node: node.operatorToken,
362
424
  newText: newOperatorText
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsl-dx",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "A tsl plugin for better JavaScript/TypeScript DX.",
5
5
  "keywords": [
6
6
  "tsl",