@zukhruf/eslint 0.3.42 → 0.3.43

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.
Files changed (52) hide show
  1. package/README.md +13 -13
  2. package/dist/base/config.d.ts.map +1 -1
  3. package/dist/base/config.js +4 -2
  4. package/dist/base/config.js.map +1 -1
  5. package/dist/diagnostics/config.js +2 -2
  6. package/dist/diagnostics/config.js.map +1 -1
  7. package/dist/environment/config.js +2 -2
  8. package/dist/environment/config.js.map +1 -1
  9. package/dist/files.d.ts +2 -0
  10. package/dist/files.d.ts.map +1 -1
  11. package/dist/files.js +2 -0
  12. package/dist/files.js.map +1 -1
  13. package/dist/hermes/plugin.d.ts.map +1 -1
  14. package/dist/hermes/plugin.js +2 -2
  15. package/dist/hermes/plugin.js.map +1 -1
  16. package/dist/hono/config.js +2 -2
  17. package/dist/hono/config.js.map +1 -1
  18. package/dist/imports/no-test-file-import.d.ts +9 -0
  19. package/dist/imports/no-test-file-import.d.ts.map +1 -0
  20. package/dist/imports/no-test-file-import.js +21 -0
  21. package/dist/imports/no-test-file-import.js.map +1 -0
  22. package/dist/island/plugin.d.ts.map +1 -1
  23. package/dist/island/plugin.js +3 -3
  24. package/dist/island/plugin.js.map +1 -1
  25. package/dist/packaged-app/config.js +2 -2
  26. package/dist/packaged-app/config.js.map +1 -1
  27. package/dist/react-router/config.js +2 -2
  28. package/dist/react-router/config.js.map +1 -1
  29. package/dist/test-files/config.d.ts.map +1 -1
  30. package/dist/test-files/config.js +15 -4
  31. package/dist/test-files/config.js.map +1 -1
  32. package/dist/test-files/no-catch-all-msw-handler.d.ts +10 -0
  33. package/dist/test-files/no-catch-all-msw-handler.d.ts.map +1 -0
  34. package/dist/test-files/no-catch-all-msw-handler.js +16 -0
  35. package/dist/test-files/no-catch-all-msw-handler.js.map +1 -0
  36. package/dist/test-files/no-direct-msw-server.d.ts +12 -0
  37. package/dist/test-files/no-direct-msw-server.d.ts.map +1 -0
  38. package/dist/test-files/no-direct-msw-server.js +67 -0
  39. package/dist/test-files/no-direct-msw-server.js.map +1 -0
  40. package/dist/test-files/no-process-env-write.d.ts +10 -0
  41. package/dist/test-files/no-process-env-write.d.ts.map +1 -0
  42. package/dist/test-files/no-process-env-write.js +21 -0
  43. package/dist/test-files/no-process-env-write.js.map +1 -0
  44. package/dist/test-files/no-timer-race.d.ts +13 -0
  45. package/dist/test-files/no-timer-race.d.ts.map +1 -0
  46. package/dist/test-files/no-timer-race.js +144 -0
  47. package/dist/test-files/no-timer-race.js.map +1 -0
  48. package/package.json +1 -1
  49. package/dist/test-files/require-msw-error-on-unhandled-request.d.ts +0 -11
  50. package/dist/test-files/require-msw-error-on-unhandled-request.d.ts.map +0 -1
  51. package/dist/test-files/require-msw-error-on-unhandled-request.js +0 -17
  52. package/dist/test-files/require-msw-error-on-unhandled-request.js.map +0 -1
package/README.md CHANGED
@@ -40,19 +40,19 @@ Put framework presets (for example Nx's `flat/react`) **before** the zukhruf con
40
40
 
41
41
  ## Configs
42
42
 
43
- | Config | Files | Rules |
44
- | ----------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
45
- | `base` | all source | `@eslint/js` and `typescript-eslint` recommended; `consistent-type-assertions` (never), `no-namespace`, `zukhruf/no-enum`; `import-x/no-duplicates`, `import-x/no-unassigned-import`; `functional/no-let` (module scope); `zukhruf/no-state-managers`, `zukhruf/no-playwright-test`; typed lint: `no-floating-promises`, `no-misused-promises`, `only-throw-error`, `switch-exhaustiveness-check` (a `default` counts as exhaustive), `zukhruf/no-promise-field`, `zukhruf/no-phase-flag`; `no-require-imports` is off in `.cjs` and `.cts`, because `require()` is the only import form in a CommonJS file |
46
- | `tests` | test files | `no-test-lifecycle-hooks`, `require-msw-error-on-unhandled-request` |
47
- | `diagnostics` | source, not tests | `no-fabricated-fallback`, `no-hardcoded-id-shape`, `consistent-event-name` |
48
- | `env` | TypeScript, not tests or tool configs | `no-undeclared-process-env`, `no-single-env-read-wrapper`, `no-default-for-path-env` |
49
- | `packaged-app` | TypeScript, not tests | `no-bare-spawn` |
50
- | `react` | `.tsx`, `.jsx` | `no-as-child` |
51
- | `react-router` | source | `require-loader-data-type-argument`; outside tests: `no-raw-route-path`, `no-internal-anchor`; TypeScript: `only-throw-error` allows a `Response` and `DataWithResponseInit` |
52
- | `hono` | TypeScript, not tests | `no-untyped-empty-json` |
53
- | `tailwind` | source | `no-h-screen`, `no-arbitrary-z-index`, `no-will-change` |
54
- | `pulumi` | TypeScript | `require-server-replace-guard` |
55
- | `nx-project-json` | `project.json` | `no-missing-asset-input` |
43
+ | Config | Files | Rules |
44
+ | ----------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
45
+ | `base` | all source | `@eslint/js` and `typescript-eslint` recommended; `consistent-type-assertions` (never), `no-namespace`, `zukhruf/no-enum`; `import-x/no-duplicates`, `import-x/no-unassigned-import`; `functional/no-let` (module scope); `zukhruf/no-state-managers`, `zukhruf/no-playwright-test`, `zukhruf/no-test-file-import`; typed lint: `no-floating-promises`, `no-misused-promises`, `only-throw-error`, `switch-exhaustiveness-check` (a `default` counts as exhaustive), `zukhruf/no-promise-field`, `zukhruf/no-phase-flag`; `no-require-imports` is off in `.cjs` and `.cts`, because `require()` is the only import form in a CommonJS file |
46
+ | `tests` | test files, `src/testing` | `no-test-lifecycle-hooks`, `no-process-env-write`, `no-direct-msw-server`, `no-catch-all-msw-handler`, `no-timer-race` |
47
+ | `diagnostics` | source, not tests | `no-fabricated-fallback`, `no-hardcoded-id-shape`, `consistent-event-name` |
48
+ | `env` | TypeScript, not tests or tool configs | `no-undeclared-process-env`, `no-single-env-read-wrapper`, `no-default-for-path-env` |
49
+ | `packaged-app` | TypeScript, not tests | `no-bare-spawn` |
50
+ | `react` | `.tsx`, `.jsx` | `no-as-child` |
51
+ | `react-router` | source | `require-loader-data-type-argument`; outside tests: `no-raw-route-path`, `no-internal-anchor`; TypeScript: `only-throw-error` allows a `Response` and `DataWithResponseInit` |
52
+ | `hono` | TypeScript, not tests | `no-untyped-empty-json` |
53
+ | `tailwind` | source | `no-h-screen`, `no-arbitrary-z-index`, `no-will-change` |
54
+ | `pulumi` | TypeScript | `require-server-replace-guard` |
55
+ | `nx-project-json` | `project.json` | `no-missing-asset-input` |
56
56
 
57
57
  `base` turns on typed lint (`parserOptions.projectService`). Each linted TypeScript file must be in a tsconfig.
58
58
 
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/base/config.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AA4BrD;;;;GAIG;AACH,eAAO,MAAM,IAAI,EAAE,OA6HlB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/base/config.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AA+BrD;;;;GAIG;AACH,eAAO,MAAM,IAAI,EAAE,OA6HlB,CAAC"}
@@ -7,15 +7,17 @@ import tseslint from 'typescript-eslint';
7
7
  import noPromiseField from "../async-values/no-promise-field.js";
8
8
  import noPhaseFlag from "../class-state/no-phase-flag.js";
9
9
  import { enable } from "../concept.js";
10
- import { BUILD_OUTPUT, COMMONJS, FIXTURES, JAVASCRIPT, SOURCE, TESTS, TYPESCRIPT, } from "../files.js";
10
+ import { BUILD_OUTPUT, COMMONJS, FIXTURES, JAVASCRIPT, SOURCE, TESTS, TEST_SUPPORT, TYPESCRIPT, } from "../files.js";
11
11
  import noPlaywrightTest from "../imports/no-playwright-test.js";
12
12
  import noStateManagers from "../imports/no-state-managers.js";
13
+ import noTestFileImport from "../imports/no-test-file-import.js";
13
14
  import noEnum from "../language/no-enum.js";
14
15
  import { workspaceRootOf } from "../workspace/workspace-root.js";
15
16
  import { noFloatingPromises, noLet } from "./options.js";
16
17
  const importBans = {
17
18
  'no-state-managers': noStateManagers,
18
19
  'no-playwright-test': noPlaywrightTest,
20
+ 'no-test-file-import': noTestFileImport,
19
21
  };
20
22
  const rules = {
21
23
  'no-enum': noEnum,
@@ -100,7 +102,7 @@ export const base = {
100
102
  // through their signatures. Keep mutable state in its owner.
101
103
  name: 'zukhruf/base/module-state',
102
104
  files: TYPESCRIPT,
103
- ignores: [...TESTS, ...FIXTURES],
105
+ ignores: [...TESTS, ...TEST_SUPPORT, ...FIXTURES],
104
106
  plugins: { functional },
105
107
  rules: { 'functional/no-let': ['error', noLet()] },
106
108
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/base/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAClD,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,OAAO,cAAc,MAAM,qCAAqC,CAAC;AACjE,OAAO,WAAW,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,MAAM,EACN,KAAK,EACL,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,gBAAgB,MAAM,kCAAkC,CAAC;AAChE,OAAO,eAAe,MAAM,iCAAiC,CAAC;AAC9D,OAAO,MAAM,MAAM,wBAAwB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,UAAU,GAAG;IACjB,mBAAmB,EAAE,eAAe;IACpC,oBAAoB,EAAE,gBAAgB;CACvC,CAAC;AAEF,MAAM,KAAK,GAAG;IACZ,SAAS,EAAE,MAAM;IACjB,kBAAkB,EAAE,cAAc;IAClC,eAAe,EAAE,WAAW;IAC5B,GAAG,UAAU;CACd,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,IAAI,GAAY;IAC3B,IAAI,EAAE,MAAM;IACZ,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAClB,YAAY,CACV,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,CAAC,GAAG,YAAY,EAAE,QAAQ,CAAC,EAAE,EACtE;QACE,IAAI,EAAE,0BAA0B;QAChC,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC;KAChE,EACD;QACE,IAAI,EAAE,iCAAiC;QACvC,KAAK,EAAE,UAAU;QACjB,eAAe,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE;KACtE,EACD;QACE,IAAI,EAAE,kCAAkC;QACxC,KAAK,EAAE,MAAM;QACb,KAAK,EAAE;YACL,cAAc,EAAE,KAAK;YACrB,iCAAiC,EAAE,OAAO;YAC1C,iCAAiC,EAAE,KAAK;YACxC,0CAA0C,EAAE,KAAK;YACjD,oCAAoC,EAAE,KAAK;YAC3C,mCAAmC,EAAE,KAAK;YAC1C,UAAU,EAAE,KAAK;YACjB,sCAAsC,EAAE,KAAK;YAC7C,yCAAyC,EAAE,OAAO;YAClD,iDAAiD,EAAE,OAAO;YAC1D,6CAA6C,EAAE,OAAO;YACtD,wCAAwC,EAAE,OAAO;SAClD;KACF,EACD;QACE,oEAAoE;QACpE,wEAAwE;QACxE,wDAAwD;QACxD,IAAI,EAAE,uBAAuB;QAC7B,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,EAAE,uCAAuC,EAAE,KAAK,EAAE;KAC1D,EACD;QACE,IAAI,EAAE,yBAAyB;QAC/B,KAAK,EAAE,UAAU;QACjB,OAAO;QACP,KAAK,EAAE;YACL,oEAAoE;YACpE,yDAAyD;YACzD,+CAA+C,EAAE;gBAC/C,OAAO;gBACP,EAAE,cAAc,EAAE,OAAO,EAAE;aAC5B;YACD,oEAAoE;YACpE,0CAA0C;YAC1C,iCAAiC,EAAE,OAAO;YAC1C,iBAAiB,EAAE,OAAO;SAC3B;QACD,mEAAmE;QACnE,aAAa,EAAE,EAAE,6BAA6B,EAAE,OAAO,EAAE;KAC1D,EACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE;QAC5C,KAAK,EAAE;YACL,GAAG,MAAM,CAAC,UAAU,CAAC;YACrB,mEAAmE;YACnE,2DAA2D;YAC3D,wBAAwB,EAAE,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;YAC/D,kEAAkE;YAClE,gDAAgD;YAChD,+BAA+B,EAAE,OAAO;SACzC;KACF,EACD;QACE,mEAAmE;QACnE,sEAAsE;QACtE,6DAA6D;QAC7D,IAAI,EAAE,2BAA2B;QACjC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,QAAQ,CAAC;QAChC,OAAO,EAAE,EAAE,UAAU,EAAE;QACvB,KAAK,EAAE,EAAE,mBAAmB,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;KACnD,EACD;QACE,8DAA8D;QAC9D,yEAAyE;QACzE,iEAAiE;QACjE,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE,UAAU;QACjB,OAAO;QACP,eAAe,EAAE;YACf,aAAa,EAAE;gBACb,cAAc,EAAE,IAAI;gBACpB,eAAe,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE;aACjE;SACF;QACD,KAAK,EAAE;YACL,mEAAmE;YACnE,oDAAoD;YACpD,yCAAyC,EAAE;gBACzC,OAAO;gBACP,kBAAkB,EAAE;aACrB;YACD,kEAAkE;YAClE,gBAAgB;YAChB,wCAAwC,EAAE;gBACxC,OAAO;gBACP,EAAE,kBAAkB,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE;aACpD;YACD,mEAAmE;YACnE,yBAAyB;YACzB,qCAAqC,EAAE,OAAO;YAC9C,kEAAkE;YAClE,gCAAgC;YAChC,gDAAgD,EAAE;gBAChD,OAAO;gBACP,EAAE,kCAAkC,EAAE,IAAI,EAAE;aAC7C;YACD,0BAA0B,EAAE,OAAO;YACnC,uBAAuB,EAAE,OAAO;SACjC;KACF,CACF;CACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/base/config.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { enable } from "../concept.js";
2
- import { SOURCE, TESTS } from "../files.js";
2
+ import { SOURCE, TESTS, TEST_SUPPORT } from "../files.js";
3
3
  import consistentEventName from "./consistent-event-name.js";
4
4
  import noFabricatedFallback from "./no-fabricated-fallback.js";
5
5
  import noHardcodedIdShape from "./no-hardcoded-id-shape.js";
@@ -16,7 +16,7 @@ export const diagnostics = {
16
16
  {
17
17
  name: 'zukhruf/diagnostics',
18
18
  files: SOURCE,
19
- ignores: TESTS,
19
+ ignores: [...TESTS, ...TEST_SUPPORT],
20
20
  plugins,
21
21
  rules: enable(rules),
22
22
  },
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/diagnostics/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,oBAAoB,MAAM,6BAA6B,CAAC;AAC/D,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAE5D,MAAM,KAAK,GAAG;IACZ,wBAAwB,EAAE,oBAAoB;IAC9C,uBAAuB,EAAE,kBAAkB;IAC3C,uBAAuB,EAAE,mBAAmB;CAC7C,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,IAAI,EAAE,aAAa;IACnB,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,qBAAqB;YAC3B,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,KAAK;YACd,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/diagnostics/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,mBAAmB,MAAM,4BAA4B,CAAC;AAC7D,OAAO,oBAAoB,MAAM,6BAA6B,CAAC;AAC/D,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAE5D,MAAM,KAAK,GAAG;IACZ,wBAAwB,EAAE,oBAAoB;IAC9C,uBAAuB,EAAE,kBAAkB;IAC3C,uBAAuB,EAAE,mBAAmB;CAC7C,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,IAAI,EAAE,aAAa;IACnB,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,qBAAqB;YAC3B,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;YACpC,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { enable } from "../concept.js";
2
- import { CONFIG_FILES, TESTS, TYPESCRIPT } from "../files.js";
2
+ import { CONFIG_FILES, TESTS, TEST_SUPPORT, TYPESCRIPT } from "../files.js";
3
3
  import noDefaultForPathEnv from "./no-default-for-path-env.js";
4
4
  import noSingleEnvReadWrapper from "./no-single-env-read-wrapper.js";
5
5
  import noUndeclaredProcessEnv from "./no-undeclared-process-env.js";
@@ -21,7 +21,7 @@ export const env = {
21
21
  name: 'zukhruf/env',
22
22
  files: TYPESCRIPT,
23
23
  // A tool config runs at build time, with no startup env schema.
24
- ignores: [...TESTS, ...CONFIG_FILES],
24
+ ignores: [...TESTS, ...TEST_SUPPORT, ...CONFIG_FILES],
25
25
  plugins,
26
26
  rules: enable(rules),
27
27
  },
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/environment/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,mBAAmB,MAAM,8BAA8B,CAAC;AAC/D,OAAO,sBAAsB,MAAM,iCAAiC,CAAC;AACrE,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AAEpE,MAAM,KAAK,GAAG;IACZ,2BAA2B,EAAE,sBAAsB;IACnD,4BAA4B,EAAE,sBAAsB;IACpD,yBAAyB,EAAE,mBAAmB;CAC/C,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,GAAG,GAAY;IAC1B,IAAI,EAAE,KAAK;IACX,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,UAAU;YACjB,gEAAgE;YAChE,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;YACpC,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/environment/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,mBAAmB,MAAM,8BAA8B,CAAC;AAC/D,OAAO,sBAAsB,MAAM,iCAAiC,CAAC;AACrE,OAAO,sBAAsB,MAAM,gCAAgC,CAAC;AAEpE,MAAM,KAAK,GAAG;IACZ,2BAA2B,EAAE,sBAAsB;IACnD,4BAA4B,EAAE,sBAAsB;IACpD,yBAAyB,EAAE,mBAAmB;CAC/C,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,GAAG,GAAY;IAC1B,IAAI,EAAE,KAAK;IACX,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,UAAU;YACjB,gEAAgE;YAChE,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC;YACrD,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
package/dist/files.d.ts CHANGED
@@ -6,6 +6,8 @@ export declare const JSX: string[];
6
6
  /** The extensions a test file can have: `x.test.<extension>` or `x.spec.<extension>`. */
7
7
  export declare const TEST_EXTENSIONS: string[];
8
8
  export declare const TESTS: string[];
9
+ /** Test helpers: a file in `src/testing` is a test file too, and the build does not ship it. */
10
+ export declare const TEST_SUPPORT: string[];
9
11
  /** Test-support scripts run top-level like tests: their state is arrange state. */
10
12
  export declare const FIXTURES: string[];
11
13
  /** A script's stdout is its interface. */
@@ -1 +1 @@
1
- {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,UAAU,UAAkD,CAAC;AAC1E,eAAO,MAAM,UAAU,UAAkD,CAAC;AAC1E,eAAO,MAAM,MAAM,UAAiC,CAAC;AACrD,eAAO,MAAM,QAAQ,UAA2B,CAAC;AACjD,eAAO,MAAM,GAAG,UAA2B,CAAC;AAC5C,yFAAyF;AACzF,eAAO,MAAM,eAAe,UAS3B,CAAC;AACF,eAAO,MAAM,KAAK,UAAsD,CAAC;AACzE,mFAAmF;AACnF,eAAO,MAAM,QAAQ,UAAsB,CAAC;AAC5C,0CAA0C;AAC1C,eAAO,MAAM,OAAO,UAAoB,CAAC;AACzC,qEAAqE;AACrE,eAAO,MAAM,YAAY,UAA0C,CAAC;AACpE,eAAO,MAAM,YAAY,UAAsB,CAAC;AAChD,eAAO,MAAM,YAAY,UAAsB,CAAC;AAChD,8EAA8E;AAC9E,eAAO,MAAM,YAAY,UAOxB,CAAC"}
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,UAAU,UAAkD,CAAC;AAC1E,eAAO,MAAM,UAAU,UAAkD,CAAC;AAC1E,eAAO,MAAM,MAAM,UAAiC,CAAC;AACrD,eAAO,MAAM,QAAQ,UAA2B,CAAC;AACjD,eAAO,MAAM,GAAG,UAA2B,CAAC;AAC5C,yFAAyF;AACzF,eAAO,MAAM,eAAe,UAS3B,CAAC;AACF,eAAO,MAAM,KAAK,UAAsD,CAAC;AACzE,gGAAgG;AAChG,eAAO,MAAM,YAAY,UAAwB,CAAC;AAClD,mFAAmF;AACnF,eAAO,MAAM,QAAQ,UAAsB,CAAC;AAC5C,0CAA0C;AAC1C,eAAO,MAAM,OAAO,UAAoB,CAAC;AACzC,qEAAqE;AACrE,eAAO,MAAM,YAAY,UAA0C,CAAC;AACpE,eAAO,MAAM,YAAY,UAAsB,CAAC;AAChD,eAAO,MAAM,YAAY,UAAsB,CAAC;AAChD,8EAA8E;AAC9E,eAAO,MAAM,YAAY,UAOxB,CAAC"}
package/dist/files.js CHANGED
@@ -19,6 +19,8 @@ export const TEST_EXTENSIONS = [
19
19
  'mjs',
20
20
  ];
21
21
  export const TESTS = [`**/*.{test,spec}.{${TEST_EXTENSIONS.join(',')}}`];
22
+ /** Test helpers: a file in `src/testing` is a test file too, and the build does not ship it. */
23
+ export const TEST_SUPPORT = ['**/src/testing/**'];
22
24
  /** Test-support scripts run top-level like tests: their state is arrange state. */
23
25
  export const FIXTURES = ['**/*.fixture.ts'];
24
26
  /** A script's stdout is its interface. */
package/dist/files.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,uEAAuE;AACvE,4EAA4E;AAC5E,qDAAqD;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC5C,yFAAyF;AACzF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AACF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,qBAAqB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzE,mFAAmF;AACnF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC5C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,eAAe,CAAC,CAAC;AACzC,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAChD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS;IACT,YAAY;IACZ,UAAU;IACV,kBAAkB;IAClB,6BAA6B;IAC7B,+BAA+B;CAChC,CAAC"}
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,uEAAuE;AACvE,4EAA4E;AAC5E,qDAAqD;AACrD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AACjD,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AAC5C,yFAAyF;AACzF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC;AACF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,qBAAqB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACzE,gGAAgG;AAChG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAClD,mFAAmF;AACnF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAC5C,0CAA0C;AAC1C,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,eAAe,CAAC,CAAC;AACzC,qEAAqE;AACrE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAChD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,iBAAiB,CAAC,CAAC;AAChD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,SAAS;IACT,YAAY;IACZ,UAAU;IACV,kBAAkB;IAClB,6BAA6B;IAC7B,+BAA+B;CAChC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/hermes/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAW7C;;;;;GAKG;AACH,QAAA,MAAM,MAAM;;;;;;;;;CAIa,CAAC;AAuB1B,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/hermes/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAiB7C;;;;;GAKG;AACH,QAAA,MAAM,MAAM;;;;;;;;;CAIa,CAAC;AAuB1B,eAAe,MAAM,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import esx from 'eslint-plugin-es-x';
2
2
  import importX from 'eslint-plugin-import-x';
3
- import { CONFIG_FILES, SCRIPTS, SOURCE, TESTS } from "../files.js";
3
+ import { CONFIG_FILES, SCRIPTS, SOURCE, TESTS, TEST_SUPPORT, } from "../files.js";
4
4
  import noMissingConsole from "./no-missing-console.js";
5
5
  const rules = { 'no-missing-console': noMissingConsole };
6
6
  const configs = {};
@@ -19,7 +19,7 @@ configs['recommended'] = [
19
19
  {
20
20
  name: 'hermes/recommended',
21
21
  files: SOURCE,
22
- ignores: [...TESTS, ...CONFIG_FILES, ...SCRIPTS],
22
+ ignores: [...TESTS, ...TEST_SUPPORT, ...CONFIG_FILES, ...SCRIPTS],
23
23
  plugins: { hermes: plugin, 'es-x': esx, 'import-x': importX },
24
24
  rules: {
25
25
  'hermes/no-missing-console': 'error',
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/hermes/plugin.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,oBAAoB,CAAC;AACrC,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AAEvD,MAAM,KAAK,GAAG,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;AAEzD,MAAM,OAAO,GAAoC,EAAE,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,8BAA8B,EAAE,SAAS,EAAE,QAAQ,EAAE;IACnE,KAAK;IACL,OAAO;CACgB,CAAC;AAE1B,OAAO,CAAC,aAAa,CAAC,GAAG;IACvB;QACE,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;QAChD,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE;QAC7D,KAAK,EAAE;YACL,2BAA2B,EAAE,OAAO;YACpC,oEAAoE;YACpE,2BAA2B,EAAE,OAAO;YACpC,6BAA6B,EAAE,OAAO;YACtC,yBAAyB,EAAE,OAAO;YAClC,qBAAqB,EAAE,OAAO;YAC9B,0BAA0B,EAAE,OAAO;YACnC,iCAAiC,EAAE,OAAO;YAC1C,wBAAwB,EAAE,OAAO;YACjC,4BAA4B,EAAE,OAAO;SACtC;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/hermes/plugin.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,oBAAoB,CAAC;AACrC,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAE7C,OAAO,EACL,YAAY,EACZ,OAAO,EACP,MAAM,EACN,KAAK,EACL,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AAEvD,MAAM,KAAK,GAAG,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;AAEzD,MAAM,OAAO,GAAoC,EAAE,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,8BAA8B,EAAE,SAAS,EAAE,QAAQ,EAAE;IACnE,KAAK;IACL,OAAO;CACgB,CAAC;AAE1B,OAAO,CAAC,aAAa,CAAC,GAAG;IACvB;QACE,IAAI,EAAE,oBAAoB;QAC1B,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;QACjE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE;QAC7D,KAAK,EAAE;YACL,2BAA2B,EAAE,OAAO;YACpC,oEAAoE;YACpE,2BAA2B,EAAE,OAAO;YACpC,6BAA6B,EAAE,OAAO;YACtC,yBAAyB,EAAE,OAAO;YAClC,qBAAqB,EAAE,OAAO;YAC9B,0BAA0B,EAAE,OAAO;YACnC,iCAAiC,EAAE,OAAO;YAC1C,wBAAwB,EAAE,OAAO;YACjC,4BAA4B,EAAE,OAAO;SACtC;KACF;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { enable } from "../concept.js";
2
- import { TESTS, TYPESCRIPT } from "../files.js";
2
+ import { TESTS, TEST_SUPPORT, TYPESCRIPT } from "../files.js";
3
3
  import noUntypedEmptyJson from "./no-untyped-empty-json.js";
4
4
  const rules = { 'no-untyped-empty-json': noUntypedEmptyJson };
5
5
  export const hono = {
@@ -9,7 +9,7 @@ export const hono = {
9
9
  {
10
10
  name: 'zukhruf/hono',
11
11
  files: TYPESCRIPT,
12
- ignores: TESTS,
12
+ ignores: [...TESTS, ...TEST_SUPPORT],
13
13
  plugins,
14
14
  rules: enable(rules),
15
15
  },
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/hono/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAE5D,MAAM,KAAK,GAAG,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC;AAE9D,MAAM,CAAC,MAAM,IAAI,GAAY;IAC3B,IAAI,EAAE,MAAM;IACZ,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,KAAK;YACd,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/hono/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,kBAAkB,MAAM,4BAA4B,CAAC;AAE5D,MAAM,KAAK,GAAG,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,CAAC;AAE9D,MAAM,CAAC,MAAM,IAAI,GAAY;IAC3B,IAAI,EAAE,MAAM;IACZ,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;YACpC,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * A `.test.`/`.spec.` file is a test entry point: `node --test` runs each one
3
+ * it finds, so a module that imports one runs its tests again, and a test file
4
+ * that exports helpers mixes two jobs. Code that tests share lives in a file
5
+ * without the suffix, for example in `src/testing`.
6
+ */
7
+ declare const _default: import("eslint").Rule.RuleModule;
8
+ export default _default;
9
+ //# sourceMappingURL=no-test-file-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-test-file-import.d.ts","sourceRoot":"","sources":["../../src/imports/no-test-file-import.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;;AACH,wBAWG"}
@@ -0,0 +1,21 @@
1
+ import { selectorRule } from "../authoring/selector-rule.js";
2
+ import { TEST_EXTENSIONS } from "../files.js";
3
+ const TEST_FILE = `/\\.(test|spec)\\.(${TEST_EXTENSIONS.join('|')})$/`;
4
+ /**
5
+ * A `.test.`/`.spec.` file is a test entry point: `node --test` runs each one
6
+ * it finds, so a module that imports one runs its tests again, and a test file
7
+ * that exports helpers mixes two jobs. Code that tests share lives in a file
8
+ * without the suffix, for example in `src/testing`.
9
+ */
10
+ export default selectorRule({
11
+ description: 'Disallow an import of a .test. or .spec. file',
12
+ selectors: [
13
+ `ImportDeclaration[source.value=${TEST_FILE}]`,
14
+ `ExportNamedDeclaration[source.value=${TEST_FILE}]`,
15
+ `ExportAllDeclaration[source.value=${TEST_FILE}]`,
16
+ `ImportExpression[source.value=${TEST_FILE}]`,
17
+ `CallExpression[callee.name="require"] > Literal.arguments[value=${TEST_FILE}]`,
18
+ ],
19
+ message: 'A .test./.spec. file is a test entry point: node --test runs it. Move the shared code to a file without the suffix.',
20
+ });
21
+ //# sourceMappingURL=no-test-file-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-test-file-import.js","sourceRoot":"","sources":["../../src/imports/no-test-file-import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,SAAS,GAAG,sBAAsB,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;AAEvE;;;;;GAKG;AACH,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,+CAA+C;IAC5D,SAAS,EAAE;QACT,kCAAkC,SAAS,GAAG;QAC9C,uCAAuC,SAAS,GAAG;QACnD,qCAAqC,SAAS,GAAG;QACjD,iCAAiC,SAAS,GAAG;QAC7C,mEAAmE,SAAS,GAAG;KAChF;IACD,OAAO,EACL,qHAAqH;CACxH,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/island/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAmC7C;;;;;;;GAOG;AACH,QAAA,MAAM,MAAM;;;;;;;;;;;;;CAIa,CAAC;AAkC1B,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/island/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAoC7C;;;;;;;GAOG;AACH,QAAA,MAAM,MAAM;;;;;;;;;;;;;CAIa,CAAC;AAkC1B,eAAe,MAAM,CAAC"}
@@ -3,7 +3,7 @@ import * as jsonc from 'jsonc-eslint-parser';
3
3
  import tseslint from 'typescript-eslint';
4
4
  import { ruleOf } from "../authoring/rule-module.js";
5
5
  import { scopedRule } from "../authoring/scoped-rule.js";
6
- import { CONFIG_FILES, PACKAGE_JSON, SCRIPTS, TESTS, TYPESCRIPT, } from "../files.js";
6
+ import { CONFIG_FILES, PACKAGE_JSON, SCRIPTS, TESTS, TEST_SUPPORT, TYPESCRIPT, } from "../files.js";
7
7
  import { dependencyPolicy } from "../nx-policy/dependency-policy.js";
8
8
  import { inIsland, inLibrary } from "./island-scope.js";
9
9
  import noConsole from "./no-console.js";
@@ -38,7 +38,7 @@ configs['recommended'] = [
38
38
  {
39
39
  name: 'island/recommended/ports',
40
40
  files: TYPESCRIPT,
41
- ignores: TESTS,
41
+ ignores: [...TESTS, ...TEST_SUPPORT],
42
42
  plugins,
43
43
  rules: {
44
44
  'island/no-generic-port': 'error',
@@ -48,7 +48,7 @@ configs['recommended'] = [
48
48
  {
49
49
  name: 'island/recommended/library',
50
50
  files: TYPESCRIPT,
51
- ignores: [...TESTS, ...SCRIPTS, ...CONFIG_FILES],
51
+ ignores: [...TESTS, ...TEST_SUPPORT, ...SCRIPTS, ...CONFIG_FILES],
52
52
  plugins,
53
53
  rules: {
54
54
  'island/no-process-env': 'error',
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/island/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEnC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,KAAK,EACL,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,0EAA0E;AAC1E,iFAAiF;AACjF,wEAAwE;AACxE,MAAM,KAAK,GAAG;IACZ,iBAAiB,EAAE,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC;IACtD,iBAAiB,EAAE,UAAU,CAC3B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC1C,QAAQ,CACT;IACD,mBAAmB,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,mBAAmB,CAAC,EAAE,QAAQ,CAAC;IAC1E,gBAAgB,EAAE,UAAU,CAAC,YAAY,EAAE,SAAS,CAAC;IACrD,YAAY,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/C,CAAC;AAEF,MAAM,OAAO,GAAoC,EAAE,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,SAAS,EAAE,QAAQ,EAAE;IACzD,KAAK;IACL,OAAO;CACgB,CAAC;AAE1B,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAEnC,OAAO,CAAC,aAAa,CAAC,GAAG;IACvB;QACE,IAAI,EAAE,0BAA0B;QAChC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,KAAK;QACd,OAAO;QACP,KAAK,EAAE;YACL,wBAAwB,EAAE,OAAO;YACjC,wBAAwB,EAAE,OAAO;SAClC;KACF;IACD;QACE,IAAI,EAAE,4BAA4B;QAClC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,OAAO,EAAE,GAAG,YAAY,CAAC;QAChD,OAAO;QACP,KAAK,EAAE;YACL,uBAAuB,EAAE,OAAO;YAChC,mBAAmB,EAAE,OAAO;SAC7B;KACF;IACD;QACE,IAAI,EAAE,iCAAiC;QACvC,KAAK,EAAE,YAAY;QACnB,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAClC,OAAO;QACP,KAAK,EAAE,EAAE,0BAA0B,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,CAAC,EAAE;KACrE;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/island/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEnC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,KAAK,EACL,YAAY,EACZ,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,0EAA0E;AAC1E,iFAAiF;AACjF,wEAAwE;AACxE,MAAM,KAAK,GAAG;IACZ,iBAAiB,EAAE,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC;IACtD,iBAAiB,EAAE,UAAU,CAC3B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC1C,QAAQ,CACT;IACD,mBAAmB,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,mBAAmB,CAAC,EAAE,QAAQ,CAAC;IAC1E,gBAAgB,EAAE,UAAU,CAAC,YAAY,EAAE,SAAS,CAAC;IACrD,YAAY,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/C,CAAC;AAEF,MAAM,OAAO,GAAoC,EAAE,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,SAAS,EAAE,QAAQ,EAAE;IACzD,KAAK;IACL,OAAO;CACgB,CAAC;AAE1B,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAEnC,OAAO,CAAC,aAAa,CAAC,GAAG;IACvB;QACE,IAAI,EAAE,0BAA0B;QAChC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;QACpC,OAAO;QACP,KAAK,EAAE;YACL,wBAAwB,EAAE,OAAO;YACjC,wBAAwB,EAAE,OAAO;SAClC;KACF;IACD;QACE,IAAI,EAAE,4BAA4B;QAClC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,EAAE,GAAG,YAAY,CAAC;QACjE,OAAO;QACP,KAAK,EAAE;YACL,uBAAuB,EAAE,OAAO;YAChC,mBAAmB,EAAE,OAAO;SAC7B;KACF;IACD;QACE,IAAI,EAAE,iCAAiC;QACvC,KAAK,EAAE,YAAY;QACnB,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAClC,OAAO;QACP,KAAK,EAAE,EAAE,0BAA0B,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,CAAC,EAAE;KACrE;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { enable } from "../concept.js";
2
- import { TESTS, TYPESCRIPT } from "../files.js";
2
+ import { TESTS, TEST_SUPPORT, TYPESCRIPT } from "../files.js";
3
3
  import noBareSpawn from "./no-bare-spawn.js";
4
4
  const rules = { 'no-bare-spawn': noBareSpawn };
5
5
  /** An app installed and launched outside a terminal, which gets the OS's minimal PATH. */
@@ -10,7 +10,7 @@ export const packagedApp = {
10
10
  {
11
11
  name: 'zukhruf/packaged-app',
12
12
  files: TYPESCRIPT,
13
- ignores: TESTS,
13
+ ignores: [...TESTS, ...TEST_SUPPORT],
14
14
  plugins,
15
15
  rules: enable(rules),
16
16
  },
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/packaged-app/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAE7C,MAAM,KAAK,GAAG,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAE/C,0FAA0F;AAC1F,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,IAAI,EAAE,cAAc;IACpB,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,sBAAsB;YAC5B,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,KAAK;YACd,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/packaged-app/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAE7C,MAAM,KAAK,GAAG,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AAE/C,0FAA0F;AAC1F,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,IAAI,EAAE,cAAc;IACpB,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,sBAAsB;YAC5B,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;YACpC,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { enable } from "../concept.js";
2
- import { SOURCE, TESTS, TYPESCRIPT } from "../files.js";
2
+ import { SOURCE, TESTS, TEST_SUPPORT, TYPESCRIPT } from "../files.js";
3
3
  import noInternalAnchor from "./no-internal-anchor.js";
4
4
  import noRawRoutePath from "./no-raw-route-path.js";
5
5
  import { reactRouterOnlyThrowError } from "./options.js";
@@ -23,7 +23,7 @@ export const reactRouter = {
23
23
  // A test renders links to whatever path it sets up.
24
24
  name: 'zukhruf/react-router/links',
25
25
  files: SOURCE,
26
- ignores: TESTS,
26
+ ignores: [...TESTS, ...TEST_SUPPORT],
27
27
  plugins,
28
28
  rules: enable({
29
29
  'no-raw-route-path': noRawRoutePath,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/react-router/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AACvD,OAAO,cAAc,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,6BAA6B,MAAM,wCAAwC,CAAC;AAEnF,MAAM,KAAK,GAAG;IACZ,mCAAmC,EAAE,6BAA6B;IAClE,mBAAmB,EAAE,cAAc;IACnC,oBAAoB,EAAE,gBAAgB;CACvC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,IAAI,EAAE,cAAc;IACpB,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,sBAAsB;YAC5B,KAAK,EAAE,MAAM;YACb,OAAO;YACP,KAAK,EAAE,EAAE,2CAA2C,EAAE,OAAO,EAAE;SAChE;QACD;YACE,oDAAoD;YACpD,IAAI,EAAE,4BAA4B;YAClC,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,KAAK;YACd,OAAO;YACP,KAAK,EAAE,MAAM,CAAC;gBACZ,mBAAmB,EAAE,cAAc;gBACnC,oBAAoB,EAAE,gBAAgB;aACvC,CAAC;SACH;QACD;YACE,mEAAmE;YACnE,oEAAoE;YACpE,yCAAyC;YACzC,IAAI,EAAE,6BAA6B;YACnC,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE;gBACL,qCAAqC,EAAE;oBACrC,OAAO;oBACP,yBAAyB,EAAE;iBAC5B;aACF;SACF;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/react-router/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,gBAAgB,MAAM,yBAAyB,CAAC;AACvD,OAAO,cAAc,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,6BAA6B,MAAM,wCAAwC,CAAC;AAEnF,MAAM,KAAK,GAAG;IACZ,mCAAmC,EAAE,6BAA6B;IAClE,mBAAmB,EAAE,cAAc;IACnC,oBAAoB,EAAE,gBAAgB;CACvC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,IAAI,EAAE,cAAc;IACpB,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,sBAAsB;YAC5B,KAAK,EAAE,MAAM;YACb,OAAO;YACP,KAAK,EAAE,EAAE,2CAA2C,EAAE,OAAO,EAAE;SAChE;QACD;YACE,oDAAoD;YACpD,IAAI,EAAE,4BAA4B;YAClC,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;YACpC,OAAO;YACP,KAAK,EAAE,MAAM,CAAC;gBACZ,mBAAmB,EAAE,cAAc;gBACnC,oBAAoB,EAAE,gBAAgB;aACvC,CAAC;SACH;QACD;YACE,mEAAmE;YACnE,oEAAoE;YACpE,yCAAyC;YACzC,IAAI,EAAE,6BAA6B;YACnC,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE;gBACL,qCAAqC,EAAE;oBACrC,OAAO;oBACP,yBAAyB,EAAE;iBAC5B;aACF;SACF;KACF;CACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/test-files/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AAUrD,eAAO,MAAM,KAAK,EAAE,OAMnB,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/test-files/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AAgBrD,eAAO,MAAM,KAAK,EAAE,OAWnB,CAAC"}
@@ -1,16 +1,27 @@
1
1
  import { enable } from "../concept.js";
2
- import { TESTS } from "../files.js";
2
+ import { TESTS, TEST_SUPPORT } from "../files.js";
3
+ import noCatchAllMswHandler from "./no-catch-all-msw-handler.js";
4
+ import noDirectMswServer from "./no-direct-msw-server.js";
5
+ import noProcessEnvWrite from "./no-process-env-write.js";
3
6
  import noTestLifecycleHooks from "./no-test-lifecycle-hooks.js";
4
- import requireMswErrorOnUnhandledRequest from "./require-msw-error-on-unhandled-request.js";
7
+ import noTimerRace from "./no-timer-race.js";
5
8
  const rules = {
6
9
  'no-test-lifecycle-hooks': noTestLifecycleHooks,
7
- 'require-msw-error-on-unhandled-request': requireMswErrorOnUnhandledRequest,
10
+ 'no-process-env-write': noProcessEnvWrite,
11
+ 'no-direct-msw-server': noDirectMswServer,
12
+ 'no-catch-all-msw-handler': noCatchAllMswHandler,
13
+ 'no-timer-race': noTimerRace,
8
14
  };
9
15
  export const tests = {
10
16
  name: 'tests',
11
17
  rules,
12
18
  config: (plugins) => [
13
- { name: 'zukhruf/tests', files: TESTS, plugins, rules: enable(rules) },
19
+ {
20
+ name: 'zukhruf/tests',
21
+ files: [...TESTS, ...TEST_SUPPORT],
22
+ plugins,
23
+ rules: enable(rules),
24
+ },
14
25
  ],
15
26
  };
16
27
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/test-files/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,oBAAoB,MAAM,8BAA8B,CAAC;AAChE,OAAO,iCAAiC,MAAM,6CAA6C,CAAC;AAE5F,MAAM,KAAK,GAAG;IACZ,yBAAyB,EAAE,oBAAoB;IAC/C,wCAAwC,EAAE,iCAAiC;CAC5E,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAY;IAC5B,IAAI,EAAE,OAAO;IACb,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;KACvE;CACF,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/test-files/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,oBAAoB,MAAM,+BAA+B,CAAC;AACjE,OAAO,iBAAiB,MAAM,2BAA2B,CAAC;AAC1D,OAAO,iBAAiB,MAAM,2BAA2B,CAAC;AAC1D,OAAO,oBAAoB,MAAM,8BAA8B,CAAC;AAChE,OAAO,WAAW,MAAM,oBAAoB,CAAC;AAE7C,MAAM,KAAK,GAAG;IACZ,yBAAyB,EAAE,oBAAoB;IAC/C,sBAAsB,EAAE,iBAAiB;IACzC,sBAAsB,EAAE,iBAAiB;IACzC,0BAA0B,EAAE,oBAAoB;IAChD,eAAe,EAAE,WAAW;CAC7B,CAAC;AAEF,MAAM,CAAC,MAAM,KAAK,GAAY;IAC5B,IAAI,EAAE,OAAO;IACb,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,YAAY,CAAC;YAClC,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * msw 3 sends a request that no handler matches to the network unless the
3
+ * strategy is strict, and a request that a catch-all handler matches but does
4
+ * not answer goes to the network too. So `http.all('*', () => {})` turns the
5
+ * strict strategy off for every origin. Scoped to a file that imports msw; a
6
+ * handler made with a `RegExp` built at run time is not seen.
7
+ */
8
+ declare const _default: import("eslint").Rule.RuleModule;
9
+ export default _default;
10
+ //# sourceMappingURL=no-catch-all-msw-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-catch-all-msw-handler.d.ts","sourceRoot":"","sources":["../../src/test-files/no-catch-all-msw-handler.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;;AACH,wBAQG"}
@@ -0,0 +1,16 @@
1
+ import { selectorRule } from "../authoring/selector-rule.js";
2
+ /**
3
+ * msw 3 sends a request that no handler matches to the network unless the
4
+ * strategy is strict, and a request that a catch-all handler matches but does
5
+ * not answer goes to the network too. So `http.all('*', () => {})` turns the
6
+ * strict strategy off for every origin. Scoped to a file that imports msw; a
7
+ * handler made with a `RegExp` built at run time is not seen.
8
+ */
9
+ export default selectorRule({
10
+ description: 'Disallow an msw handler that matches every request; match the origin',
11
+ selectors: [
12
+ 'Program:has(ImportDeclaration[source.value="msw"]) CallExpression[callee.object.name="http"]:matches([arguments.0.value="*"], [arguments.0.regex.pattern=/^\\^?\\.[*+]\\$?$/])',
13
+ ],
14
+ message: 'A catch-all handler that returns nothing sends unmatched requests to the network and turns the strict strategy off (msw 3). Match the origin: http.all(`${origin}/*`, () => passthrough()).',
15
+ });
16
+ //# sourceMappingURL=no-catch-all-msw-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-catch-all-msw-handler.js","sourceRoot":"","sources":["../../src/test-files/no-catch-all-msw-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;;;;;GAMG;AACH,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,sEAAsE;IACxE,SAAS,EAAE;QACT,gLAAgL;KACjL;IACD,OAAO,EACL,6LAA6L;CAChM,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Rule } from 'eslint';
2
+ /**
3
+ * A server from msw's own `setupServer` sends an unmatched request to the
4
+ * network unless the test passes the strict option, keeps no record of what it
5
+ * answered, and stays open when a test forgets `close()`. `Msw` of
6
+ * `@zukhruf/testing/msw` is always strict, records each request, and closes at
7
+ * scope end. The rule follows the binding that `msw/node` exports, aliased or
8
+ * through a namespace, so a `setupServer` from another module is not reported.
9
+ */
10
+ declare const rule: Rule.RuleModule;
11
+ export default rule;
12
+ //# sourceMappingURL=no-direct-msw-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-direct-msw-server.d.ts","sourceRoot":"","sources":["../../src/test-files/no-direct-msw-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAS,MAAM,QAAQ,CAAC;AA6B1C;;;;;;;GAOG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAmChB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { identifierName, isAstNode, isType } from "../authoring/ast.js";
2
+ const parentOf = (node) => isAstNode(node) ? node['parent'] : undefined;
3
+ /**
4
+ * The calls that the references to `variable` make: `setupServer()`, or
5
+ * `namespace.setupServer()` when the variable is the module namespace.
6
+ */
7
+ function callsOf(variable, member) {
8
+ return variable.references.flatMap(({ identifier }) => {
9
+ const access = parentOf(identifier);
10
+ const callee = member === undefined
11
+ ? identifier
12
+ : isType(access, 'MemberExpression') &&
13
+ access['computed'] === false &&
14
+ identifierName(access['property']) === member
15
+ ? access
16
+ : undefined;
17
+ const call = parentOf(callee);
18
+ return isType(call, 'CallExpression') && call['callee'] === callee
19
+ ? [call]
20
+ : [];
21
+ });
22
+ }
23
+ /**
24
+ * A server from msw's own `setupServer` sends an unmatched request to the
25
+ * network unless the test passes the strict option, keeps no record of what it
26
+ * answered, and stays open when a test forgets `close()`. `Msw` of
27
+ * `@zukhruf/testing/msw` is always strict, records each request, and closes at
28
+ * scope end. The rule follows the binding that `msw/node` exports, aliased or
29
+ * through a namespace, so a `setupServer` from another module is not reported.
30
+ */
31
+ const rule = {
32
+ meta: {
33
+ type: 'problem',
34
+ docs: {
35
+ description: "Disallow msw's setupServer in tests; use Msw from @zukhruf/testing/msw",
36
+ },
37
+ schema: [],
38
+ messages: {
39
+ direct: 'Use `new Msw().intercept(...handlers)` from @zukhruf/testing/msw: it is always strict, records each request, and closes at scope end.',
40
+ },
41
+ },
42
+ create(context) {
43
+ return {
44
+ ImportDeclaration(node) {
45
+ if (node.source.value !== 'msw/node')
46
+ return;
47
+ for (const specifier of node.specifiers) {
48
+ const [variable] = context.sourceCode.getDeclaredVariables(specifier);
49
+ if (variable === undefined)
50
+ continue;
51
+ const calls = specifier.type === 'ImportNamespaceSpecifier'
52
+ ? callsOf(variable, 'setupServer')
53
+ : specifier.type === 'ImportSpecifier' &&
54
+ specifier.imported.type === 'Identifier' &&
55
+ specifier.imported.name === 'setupServer'
56
+ ? callsOf(variable)
57
+ : [];
58
+ for (const call of calls) {
59
+ context.report({ node: call, messageId: 'direct' });
60
+ }
61
+ }
62
+ },
63
+ };
64
+ },
65
+ };
66
+ export default rule;
67
+ //# sourceMappingURL=no-direct-msw-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-direct-msw-server.js","sourceRoot":"","sources":["../../src/test-files/no-direct-msw-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAExE,MAAM,QAAQ,GAAG,CAAC,IAAa,EAAE,EAAE,CACjC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAE/C;;;GAGG;AACH,SAAS,OAAO,CAAC,QAAwB,EAAE,MAAe;IACxD,OAAO,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE;QACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QACpC,MAAM,MAAM,GACV,MAAM,KAAK,SAAS;YAClB,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC;gBAChC,MAAM,CAAC,UAAU,CAAC,KAAK,KAAK;gBAC5B,cAAc,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,MAAM;gBAC/C,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,SAAS,CAAC;QAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,MAAM;YAChE,CAAC,CAAC,CAAC,IAAI,CAAC;YACR,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,IAAI,GAAoB;IAC5B,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,wEAAwE;SAC3E;QACD,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,MAAM,EACJ,uIAAuI;SAC1I;KACF;IACD,MAAM,CAAC,OAAO;QACZ,OAAO;YACL,iBAAiB,CAAC,IAAI;gBACpB,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,UAAU;oBAAE,OAAO;gBAC7C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACxC,MAAM,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;oBACtE,IAAI,QAAQ,KAAK,SAAS;wBAAE,SAAS;oBACrC,MAAM,KAAK,GACT,SAAS,CAAC,IAAI,KAAK,0BAA0B;wBAC3C,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC;wBAClC,CAAC,CAAC,SAAS,CAAC,IAAI,KAAK,iBAAiB;4BAClC,SAAS,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;4BACxC,SAAS,CAAC,QAAQ,CAAC,IAAI,KAAK,aAAa;4BAC3C,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;4BACnB,CAAC,CAAC,EAAE,CAAC;oBACX,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;wBACzB,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;oBACtD,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tests run concurrently, and `process.env` is one object for the whole
3
+ * process: a test that sets a variable changes it for every test that runs at
4
+ * the same time, and a restore in `finally` cannot undo what the others read
5
+ * meanwhile. Reads and copies (`{ ...process.env, X: '1' }` for a child
6
+ * process) stay allowed.
7
+ */
8
+ declare const _default: import("eslint").Rule.RuleModule;
9
+ export default _default;
10
+ //# sourceMappingURL=no-process-env-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-process-env-write.d.ts","sourceRoot":"","sources":["../../src/test-files/no-process-env-write.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;;AACH,wBAWG"}
@@ -0,0 +1,21 @@
1
+ import { selectorRule } from "../authoring/selector-rule.js";
2
+ const PROCESS_ENV = '[object.name="process"][property.name="env"]';
3
+ /**
4
+ * Tests run concurrently, and `process.env` is one object for the whole
5
+ * process: a test that sets a variable changes it for every test that runs at
6
+ * the same time, and a restore in `finally` cannot undo what the others read
7
+ * meanwhile. Reads and copies (`{ ...process.env, X: '1' }` for a child
8
+ * process) stay allowed.
9
+ */
10
+ export default selectorRule({
11
+ description: 'Disallow a test that changes process.env',
12
+ selectors: [
13
+ `AssignmentExpression[left.object.object.name="process"][left.object.property.name="env"]`,
14
+ `AssignmentExpression > MemberExpression.left${PROCESS_ENV}`,
15
+ `UnaryExpression[operator="delete"][argument.object.object.name="process"][argument.object.property.name="env"]`,
16
+ `CallExpression[callee.object.name="Object"][callee.property.name=/^(assign|defineProperty|defineProperties)$/] > MemberExpression.arguments:first-child${PROCESS_ENV}`,
17
+ 'CallExpression[callee.object.name="vi"][callee.property.name="stubEnv"]',
18
+ ],
19
+ message: 'Tests run concurrently, and process.env is one object for the whole process. Pass the environment (or the value) to the code under test, or give a child process its own env.',
20
+ });
21
+ //# sourceMappingURL=no-process-env-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-process-env-write.js","sourceRoot":"","sources":["../../src/test-files/no-process-env-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,MAAM,WAAW,GAAG,8CAA8C,CAAC;AAEnE;;;;;;GAMG;AACH,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,0CAA0C;IACvD,SAAS,EAAE;QACT,0FAA0F;QAC1F,+CAA+C,WAAW,EAAE;QAC5D,gHAAgH;QAChH,0JAA0J,WAAW,EAAE;QACvK,yEAAyE;KAC1E;IACD,OAAO,EACL,+KAA+K;CAClL,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Rule } from 'eslint';
2
+ /**
3
+ * A race against a timer that rejects fails the test when the promise is late,
4
+ * with an error the test wrote itself, and leaves the promise running. A
5
+ * timeout belongs to the test (`{ timeout }`), or to `settleWithin`, which
6
+ * names what was late. Follows one variable: a timer built in a helper that
7
+ * returns it is not seen. A timer that resolves a marker
8
+ * (`sleep(ms).then(() => false)`, `delay(ms, 'pending')`) asserts that the
9
+ * promise stays pending, which is a different check, and stays allowed.
10
+ */
11
+ declare const rule: Rule.RuleModule;
12
+ export default rule;
13
+ //# sourceMappingURL=no-timer-race.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-timer-race.d.ts","sourceRoot":"","sources":["../../src/test-files/no-timer-race.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAS,MAAM,QAAQ,CAAC;AA8I1C;;;;;;;;GAQG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UA6BhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,144 @@
1
+ import { identifierName, isAstNode, isType, } from "../authoring/ast.js";
2
+ /** Timers that take a callback: `setTimeout(() => reject(...), ms)`. */
3
+ const CALLBACK_TIMERS = new Set(['setTimeout']);
4
+ /** Timers that return a promise: `sleep(ms)`, `delay(ms)`, and `setTimeout(ms)` of `node:timers/promises`. */
5
+ const PROMISE_TIMERS = new Set(['sleep', 'delay', 'setTimeout']);
6
+ function calleeName(call) {
7
+ const callee = call['callee'];
8
+ if (isType(callee, 'MemberExpression'))
9
+ return identifierName(callee['property']);
10
+ return identifierName(callee);
11
+ }
12
+ function isTimerCall(node, names) {
13
+ if (!isType(node, 'CallExpression'))
14
+ return false;
15
+ const name = calleeName(node);
16
+ return name !== undefined && names.has(name);
17
+ }
18
+ /** Whether a reference to `variable` sits in the arguments of a callback timer. */
19
+ function calledByTimer(variable) {
20
+ return (variable?.references ?? []).some(({ identifier }) => {
21
+ let child = identifier;
22
+ let parent = isAstNode(child) ? child['parent'] : undefined;
23
+ while (isAstNode(parent)) {
24
+ if (isTimerCall(parent, CALLBACK_TIMERS) &&
25
+ Array.isArray(parent['arguments']) &&
26
+ parent['arguments'].includes(child)) {
27
+ return true;
28
+ }
29
+ child = parent;
30
+ parent = parent['parent'];
31
+ }
32
+ return false;
33
+ });
34
+ }
35
+ function declared(context, node, name) {
36
+ return context.sourceCode
37
+ .getDeclaredVariables(node)
38
+ .find((variable) => variable.name === name);
39
+ }
40
+ /** `new Promise((_, reject) => setTimeout(() => reject(...), ms))`. */
41
+ function rejectingExecutor(context, node) {
42
+ if (identifierName(node['callee']) !== 'Promise')
43
+ return false;
44
+ const executor = Array.isArray(node['arguments'])
45
+ ? node['arguments'][0]
46
+ : undefined;
47
+ if (!isType(executor, 'ArrowFunctionExpression') &&
48
+ !isType(executor, 'FunctionExpression')) {
49
+ return false;
50
+ }
51
+ const params = Array.isArray(executor['params']) ? executor['params'] : [];
52
+ return calledByTimer(declared(context, executor, identifierName(params[1])));
53
+ }
54
+ /** `sleep(ms).then(() => { throw ... })`. */
55
+ function throwingContinuation(node) {
56
+ const callee = node['callee'];
57
+ if (!isType(callee, 'MemberExpression') ||
58
+ identifierName(callee['property']) !== 'then' ||
59
+ !isTimerCall(callee['object'], PROMISE_TIMERS)) {
60
+ return false;
61
+ }
62
+ const onFulfilled = Array.isArray(node['arguments'])
63
+ ? node['arguments'][0]
64
+ : undefined;
65
+ const body = isAstNode(onFulfilled) ? onFulfilled['body'] : undefined;
66
+ return (isType(body, 'BlockStatement') &&
67
+ Array.isArray(body['body']) &&
68
+ body['body'].some((statement) => isType(statement, 'ThrowStatement')));
69
+ }
70
+ /**
71
+ * `const { promise, reject } = Promise.withResolvers()`, or any other
72
+ * destructured `reject`, with `reject` called by a timer.
73
+ */
74
+ function rejectingResolvers(context, declarator) {
75
+ const pattern = declarator['id'];
76
+ if (!isType(pattern, 'ObjectPattern'))
77
+ return false;
78
+ const properties = pattern['properties'];
79
+ if (!Array.isArray(properties))
80
+ return false;
81
+ const reject = properties.find((property) => isType(property, 'Property') &&
82
+ identifierName(property['key']) === 'reject');
83
+ return (isAstNode(reject) &&
84
+ calledByTimer(declared(context, declarator, identifierName(reject['value']))));
85
+ }
86
+ function rejectsOnTimer(context, element, resolveBinding) {
87
+ if (isType(element, 'NewExpression')) {
88
+ return rejectingExecutor(context, element);
89
+ }
90
+ if (isType(element, 'CallExpression'))
91
+ return throwingContinuation(element);
92
+ if (!resolveBinding || !isType(element, 'Identifier'))
93
+ return false;
94
+ const reference = context.sourceCode
95
+ .getScope(element)
96
+ .references.find(({ identifier }) => identifier === element);
97
+ const definition = reference?.resolved?.defs[0];
98
+ if (definition?.type !== 'Variable' || !isAstNode(definition.node)) {
99
+ return false;
100
+ }
101
+ const declarator = definition.node;
102
+ return isType(declarator['id'], 'Identifier')
103
+ ? rejectsOnTimer(context, declarator['init'], false)
104
+ : rejectingResolvers(context, declarator);
105
+ }
106
+ /**
107
+ * A race against a timer that rejects fails the test when the promise is late,
108
+ * with an error the test wrote itself, and leaves the promise running. A
109
+ * timeout belongs to the test (`{ timeout }`), or to `settleWithin`, which
110
+ * names what was late. Follows one variable: a timer built in a helper that
111
+ * returns it is not seen. A timer that resolves a marker
112
+ * (`sleep(ms).then(() => false)`, `delay(ms, 'pending')`) asserts that the
113
+ * promise stays pending, which is a different check, and stays allowed.
114
+ */
115
+ const rule = {
116
+ meta: {
117
+ type: 'problem',
118
+ docs: {
119
+ description: 'Disallow Promise.race against a timer that rejects',
120
+ },
121
+ schema: [],
122
+ messages: {
123
+ matched: 'This race fails the test when the promise is late: use settleWithin(promise, label, ms) from @zukhruf/testing/async, or give the test its own { timeout }.',
124
+ },
125
+ },
126
+ create(context) {
127
+ return {
128
+ 'CallExpression[callee.object.name="Promise"][callee.property.name="race"] > ArrayExpression.arguments'(array) {
129
+ if (!isType(array, 'ArrayExpression'))
130
+ return;
131
+ const elements = Array.isArray(array['elements'])
132
+ ? array['elements']
133
+ : [];
134
+ for (const element of elements) {
135
+ if (isAstNode(element) && rejectsOnTimer(context, element, true)) {
136
+ context.report({ node: element, messageId: 'matched' });
137
+ }
138
+ }
139
+ },
140
+ };
141
+ },
142
+ };
143
+ export default rule;
144
+ //# sourceMappingURL=no-timer-race.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-timer-race.js","sourceRoot":"","sources":["../../src/test-files/no-timer-race.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zukhruf/eslint",
3
- "version": "0.3.42",
3
+ "version": "0.3.43",
4
4
  "description": "ESLint rules and configs shared across workspaces. Every check is its own named rule, so a repo's own config cannot silently erase it.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,11 +0,0 @@
1
- /**
2
- * msw answers only what a handler lists. Without this option an unstubbed
3
- * request is warned about and sent to the real network, so the test passes on
4
- * a live dependency it never meant to touch. msw 3 names the option
5
- * `onUnhandledFrame`; msw 2 named it `onUnhandledRequest`. Scoped by the
6
- * `msw/node` import; a `listen()` on something else in the same file, called
7
- * with no argument or an object, is the one known false positive.
8
- */
9
- declare const _default: import("eslint").Rule.RuleModule;
10
- export default _default;
11
- //# sourceMappingURL=require-msw-error-on-unhandled-request.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"require-msw-error-on-unhandled-request.d.ts","sourceRoot":"","sources":["../../src/test-files/require-msw-error-on-unhandled-request.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;;AACH,wBAOG"}
@@ -1,17 +0,0 @@
1
- import { selectorRule } from "../authoring/selector-rule.js";
2
- /**
3
- * msw answers only what a handler lists. Without this option an unstubbed
4
- * request is warned about and sent to the real network, so the test passes on
5
- * a live dependency it never meant to touch. msw 3 names the option
6
- * `onUnhandledFrame`; msw 2 named it `onUnhandledRequest`. Scoped by the
7
- * `msw/node` import; a `listen()` on something else in the same file, called
8
- * with no argument or an object, is the one known false positive.
9
- */
10
- export default selectorRule({
11
- description: "Require msw's server.listen() to fail on unhandled requests",
12
- selectors: [
13
- 'Program:has(ImportDeclaration[source.value="msw/node"]) CallExpression[callee.property.name="listen"]:matches([arguments.length=0], [arguments.0.type="ObjectExpression"]):not(:has(Property[key.name=/^onUnhandled(Frame|Request)$/] > Literal[value="error"]))',
14
- ],
15
- message: "msw: server.listen() must pass { onUnhandledFrame: 'error' } (msw 2: onUnhandledRequest) so an unstubbed request fails the test instead of reaching the network.",
16
- });
17
- //# sourceMappingURL=require-msw-error-on-unhandled-request.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"require-msw-error-on-unhandled-request.js","sourceRoot":"","sources":["../../src/test-files/require-msw-error-on-unhandled-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;;;;;;GAOG;AACH,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,6DAA6D;IAC1E,SAAS,EAAE;QACT,kQAAkQ;KACnQ;IACD,OAAO,EACL,kKAAkK;CACrK,CAAC,CAAC"}