@opetope/lint 0.14.0 → 0.16.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.
Files changed (137) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +75 -87
  3. package/dist/ast.d.ts +14 -2
  4. package/dist/ast.js +1 -1
  5. package/dist/ast.js.map +1 -1
  6. package/dist/command-hooks.d.ts +7 -6
  7. package/dist/command-hooks.js +1 -1
  8. package/dist/command-hooks.js.map +1 -1
  9. package/dist/context-members.d.ts +8 -7
  10. package/dist/context-members.js +1 -1
  11. package/dist/context-members.js.map +1 -1
  12. package/dist/declaration-ingress.d.ts +43 -11
  13. package/dist/declaration-ingress.js +1 -1
  14. package/dist/declaration-ingress.js.map +1 -1
  15. package/dist/declarations.d.ts +1 -1
  16. package/dist/declarations.js +1 -1
  17. package/dist/declarations.js.map +1 -1
  18. package/dist/effect-declarations.d.ts +3 -2
  19. package/dist/effect-declarations.js +1 -1
  20. package/dist/effect-declarations.js.map +1 -1
  21. package/dist/entry-move-rows.d.ts +21 -0
  22. package/dist/entry-move-rows.js +2 -0
  23. package/dist/entry-move-rows.js.map +1 -0
  24. package/dist/entry-moves.d.ts +25 -0
  25. package/dist/entry-moves.js +10 -0
  26. package/dist/entry-moves.js.map +1 -0
  27. package/dist/feature-body-records.d.ts +5 -3
  28. package/dist/feature-body-records.js +1 -1
  29. package/dist/feature-body-records.js.map +1 -1
  30. package/dist/index.d.ts +65 -58
  31. package/dist/index.js +1 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/lazy-body-migration.d.ts +5 -5
  34. package/dist/lazy-body-migration.js +1 -1
  35. package/dist/lazy-body-migration.js.map +1 -1
  36. package/dist/model-bindings.d.ts +21 -13
  37. package/dist/model-bindings.js +1 -1
  38. package/dist/model-bindings.js.map +1 -1
  39. package/dist/resource-vocabulary.d.ts +17 -0
  40. package/dist/resource-vocabulary.js +2 -0
  41. package/dist/resource-vocabulary.js.map +1 -0
  42. package/dist/retired-vocabulary-messages.d.ts +6 -0
  43. package/dist/retired-vocabulary-messages.js +2 -0
  44. package/dist/retired-vocabulary-messages.js.map +1 -0
  45. package/dist/retired-vocabulary.d.ts +10 -8
  46. package/dist/retired-vocabulary.js +1 -1
  47. package/dist/retired-vocabulary.js.map +1 -1
  48. package/dist/rule.d.ts +94 -5
  49. package/dist/rule.js +1 -1
  50. package/dist/rule.js.map +1 -1
  51. package/dist/rules/capture-command-cleanup.d.ts +1 -4
  52. package/dist/rules/capture-command-cleanup.js +1 -1
  53. package/dist/rules/capture-command-cleanup.js.map +1 -1
  54. package/dist/rules/define-feature-property-order.d.ts +1 -4
  55. package/dist/rules/define-feature-property-order.js +1 -1
  56. package/dist/rules/define-feature-property-order.js.map +1 -1
  57. package/dist/rules/enabled-predicate.d.ts +1 -4
  58. package/dist/rules/enabled-predicate.js +1 -1
  59. package/dist/rules/enabled-predicate.js.map +1 -1
  60. package/dist/rules/id-naming.d.ts +1 -3
  61. package/dist/rules/layer-placement.d.ts +1 -3
  62. package/dist/rules/no-behavior-in-integration.d.ts +8 -0
  63. package/dist/rules/no-behavior-in-integration.js +2 -0
  64. package/dist/rules/no-behavior-in-integration.js.map +1 -0
  65. package/dist/rules/no-command-in-deps.d.ts +1 -4
  66. package/dist/rules/no-command-in-deps.js +1 -1
  67. package/dist/rules/no-command-in-deps.js.map +1 -1
  68. package/dist/rules/no-dead-abort-check.d.ts +8 -0
  69. package/dist/rules/no-dead-abort-check.js +2 -0
  70. package/dist/rules/no-dead-abort-check.js.map +1 -0
  71. package/dist/rules/no-event-without-emit.d.ts +10 -0
  72. package/dist/rules/no-event-without-emit.js +2 -0
  73. package/dist/rules/no-event-without-emit.js.map +1 -0
  74. package/dist/rules/no-inline-requires-models.d.ts +8 -0
  75. package/dist/rules/no-inline-requires-models.js +5 -0
  76. package/dist/rules/no-inline-requires-models.js.map +1 -0
  77. package/dist/rules/no-internal-imports.d.ts +1 -3
  78. package/dist/rules/no-internal-imports.js +1 -1
  79. package/dist/rules/no-internal-imports.js.map +1 -1
  80. package/dist/rules/no-redundant-const-tuple.d.ts +1 -4
  81. package/dist/rules/no-redundant-const-tuple.js +1 -1
  82. package/dist/rules/no-redundant-const-tuple.js.map +1 -1
  83. package/dist/rules/no-retired-vocabulary.d.ts +2 -4
  84. package/dist/rules/no-retired-vocabulary.js +1 -1
  85. package/dist/rules/no-retired-vocabulary.js.map +1 -1
  86. package/dist/rules/no-single-command-lane.d.ts +10 -0
  87. package/dist/rules/no-single-command-lane.js +2 -0
  88. package/dist/rules/no-single-command-lane.js.map +1 -0
  89. package/dist/rules/no-snapshot-in-update.d.ts +1 -4
  90. package/dist/rules/no-snapshot-in-update.js.map +1 -1
  91. package/dist/rules/no-snapshot-read-in-render.d.ts +2 -3
  92. package/dist/rules/no-snapshot-read-in-render.js +1 -1
  93. package/dist/rules/no-snapshot-read-in-render.js.map +1 -1
  94. package/dist/rules/no-subscribe-outside-models.d.ts +1 -3
  95. package/dist/rules/no-subscribe-outside-models.js +1 -1
  96. package/dist/rules/no-subscribe-outside-models.js.map +1 -1
  97. package/dist/rules/no-write-after-source-write.d.ts +1 -4
  98. package/dist/rules/no-write-after-source-write.js +1 -1
  99. package/dist/rules/no-write-after-source-write.js.map +1 -1
  100. package/dist/rules/prefer-derive.d.ts +7 -0
  101. package/dist/rules/prefer-derive.js +2 -0
  102. package/dist/rules/prefer-derive.js.map +1 -0
  103. package/dist/rules/prefer-effect-current.d.ts +1 -4
  104. package/dist/rules/prefer-effect-current.js +1 -1
  105. package/dist/rules/prefer-effect-current.js.map +1 -1
  106. package/dist/rules/prefer-lazy-body-record.d.ts +1 -4
  107. package/dist/rules/prefer-lazy-body-record.js +1 -1
  108. package/dist/rules/prefer-lazy-body-record.js.map +1 -1
  109. package/dist/rules/prefer-model-selection.d.ts +1 -3
  110. package/dist/rules/prefer-model-selection.js +1 -1
  111. package/dist/rules/prefer-model-selection.js.map +1 -1
  112. package/dist/rules/prefer-read.d.ts +2 -0
  113. package/dist/rules/prefer-read.js +2 -0
  114. package/dist/rules/prefer-read.js.map +1 -0
  115. package/dist/rules/prefer-when-over-enabled.d.ts +7 -0
  116. package/dist/rules/prefer-when-over-enabled.js +2 -0
  117. package/dist/rules/prefer-when-over-enabled.js.map +1 -0
  118. package/dist/rules/require-declared-models.d.ts +1 -3
  119. package/dist/rules/require-declared-models.js +1 -1
  120. package/dist/rules/require-declared-models.js.map +1 -1
  121. package/dist/rules/require-literal-id.d.ts +2 -3
  122. package/dist/rules/require-literal-id.js +1 -1
  123. package/dist/rules/require-literal-id.js.map +1 -1
  124. package/dist/rules/require-static-feature.d.ts +9 -0
  125. package/dist/rules/require-static-feature.js +2 -0
  126. package/dist/rules/require-static-feature.js.map +1 -0
  127. package/dist/rules/scope-builder-releases-subscriptions.d.ts +10 -0
  128. package/dist/rules/scope-builder-releases-subscriptions.js +2 -0
  129. package/dist/rules/scope-builder-releases-subscriptions.js.map +1 -0
  130. package/dist/snapshot-updates.d.ts +4 -3
  131. package/dist/snapshot-updates.js +1 -1
  132. package/dist/snapshot-updates.js.map +1 -1
  133. package/dist/static-value.d.ts +3 -2
  134. package/dist/static-value.js +1 -1
  135. package/dist/static-value.js.map +1 -1
  136. package/oxlintrc.json +10 -0
  137. package/package.json +13 -3
@@ -1,8 +1,10 @@
1
- import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
1
+ import type { TSESTree } from '@typescript-eslint/types';
2
+ import type { SourceCode } from './rule.js';
2
3
  interface BodyRecordEntry {
3
4
  readonly implementation: TSESTree.Node | undefined;
4
5
  readonly options: TSESTree.Node | undefined;
5
6
  }
7
+ declare function isBodyCall(source: SourceCode, call: TSESTree.CallExpression): boolean;
6
8
  /** Resolve local record/tuple aliases only after identifying the authentic authoring API by its import. */
7
- declare function bodyRecordEntries(source: TSESLint.SourceCode, call: TSESTree.CallExpression): readonly BodyRecordEntry[];
8
- export { bodyRecordEntries };
9
+ declare function bodyRecordEntries(source: SourceCode, call: TSESTree.CallExpression): readonly BodyRecordEntry[];
10
+ export { bodyRecordEntries, isBodyCall };
@@ -1,2 +1,2 @@
1
- import{AST_NODE_TYPES as r}from"@typescript-eslint/utils";import{findProperty as f}from"./ast.js";import{localValue as p,isApi as s}from"./model-bindings.js";function a(n,t){const e=p(n,t.callee);return e.type!==r.MemberExpression||e.computed||e.property.type!==r.Identifier||e.property.name!=="body"?!1:s(n,e.object,"@opetope/runtime","defineFeature")}function l(n,t){if(!a(n,t))return;const e=t.arguments[1];if(e===void 0)return;const i=p(n,e);return i.type===r.ObjectExpression?i:void 0}function y(n,t){const e=l(n,t);if(e===void 0)return[];const i=f(e,"provides");if(i===void 0)return[];const u=p(n,i.value);return u.type!==r.ObjectExpression?[]:u.properties.flatMap(d=>{if(d.type!==r.Property)return[];const o=p(n,d.value);return[{implementation:o.type===r.ArrayExpression?o.elements[0]??void 0:o,options:o.type===r.ArrayExpression?o.elements[1]??void 0:void 0}]})}export{y as bodyRecordEntries};
1
+ import{AST_NODE_TYPES as r}from"@typescript-eslint/types";import{findProperty as s}from"./ast.js";import{localValue as p,isApi as a}from"./model-bindings.js";function f(n,t){const e=p(n,t.callee);return e.type!==r.MemberExpression||e.computed||e.property.type!==r.Identifier||e.property.name!=="body"?!1:a(n,e.object,"@opetope/runtime","defineFeature")}function l(n,t){if(!f(n,t))return;const e=t.arguments[1];if(e===void 0)return;const i=p(n,e);return i.type===r.ObjectExpression?i:void 0}function y(n,t){const e=l(n,t);if(e===void 0)return[];const i=s(e,"provides");if(i===void 0)return[];const u=p(n,i.value);return u.type!==r.ObjectExpression?[]:u.properties.flatMap(d=>{if(d.type!==r.Property)return[];const o=p(n,d.value);return[{implementation:o.type===r.ArrayExpression?o.elements[0]??void 0:o,options:o.type===r.ArrayExpression?o.elements[1]??void 0:void 0}]})}export{y as bodyRecordEntries,f as isBodyCall};
2
2
  //# sourceMappingURL=feature-body-records.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-body-records.js","sources":["../src/feature-body-records.ts"],"sourcesContent":["import type { TSESLint, TSESTree } from '@typescript-eslint/utils';\nimport { AST_NODE_TYPES } from '@typescript-eslint/utils';\n\nimport { findProperty } from './ast';\nimport { isApi, localValue } from './model-bindings';\n\ninterface BodyRecordEntry {\n readonly implementation: TSESTree.Node | undefined;\n readonly options: TSESTree.Node | undefined;\n}\n\nfunction isBodyCall(source: TSESLint.SourceCode, call: TSESTree.CallExpression): boolean {\n const callee = localValue(source, call.callee);\n if (callee.type !== AST_NODE_TYPES.MemberExpression || callee.computed) return false;\n if (callee.property.type !== AST_NODE_TYPES.Identifier || callee.property.name !== 'body') return false;\n return isApi(source, callee.object, '@opetope/runtime', 'defineFeature');\n}\n\nfunction bodySections(\n source: TSESLint.SourceCode,\n call: TSESTree.CallExpression,\n): TSESTree.ObjectExpression | undefined {\n if (!isBodyCall(source, call)) return undefined;\n const input = call.arguments[1];\n if (input === undefined) return undefined;\n const value = localValue(source, input);\n return value.type === AST_NODE_TYPES.ObjectExpression ? value : undefined;\n}\n\n/** Resolve local record/tuple aliases only after identifying the authentic authoring API by its import. */\nfunction bodyRecordEntries(source: TSESLint.SourceCode, call: TSESTree.CallExpression): readonly BodyRecordEntry[] {\n const sections = bodySections(source, call);\n if (sections === undefined) return [];\n const property = findProperty(sections, 'provides');\n if (property === undefined) return [];\n const record = localValue(source, property.value);\n if (record.type !== AST_NODE_TYPES.ObjectExpression) return [];\n return record.properties.flatMap(entry => {\n if (entry.type !== AST_NODE_TYPES.Property) return [];\n const value = localValue(source, entry.value);\n return [\n {\n implementation: value.type === AST_NODE_TYPES.ArrayExpression ? (value.elements[0] ?? undefined) : value,\n options: value.type === AST_NODE_TYPES.ArrayExpression ? (value.elements[1] ?? undefined) : undefined,\n },\n ];\n });\n}\n\nexport { bodyRecordEntries };\n"],"names":["isBodyCall","source","call","callee","localValue","AST_NODE_TYPES","isApi","bodySections","input","value","bodyRecordEntries","sections","property","findProperty","record","entry"],"mappings":"8JAWA,SAASA,EAAWC,EAA6BC,EAA6B,CAC5E,MAAMC,EAASC,EAAWH,EAAQC,EAAK,MAAM,EAE7C,OADIC,EAAO,OAASE,EAAe,kBAAoBF,EAAO,UAC1DA,EAAO,SAAS,OAASE,EAAe,YAAcF,EAAO,SAAS,OAAS,OAAe,GAC3FG,EAAML,EAAQE,EAAO,OAAQ,mBAAoB,eAAe,CACzE,CAEA,SAASI,EACPN,EACAC,EAA6B,CAE7B,GAAI,CAACF,EAAWC,EAAQC,CAAI,EAAG,OAC/B,MAAMM,EAAQN,EAAK,UAAU,CAAC,EAC9B,GAAIM,IAAU,OAAW,OACzB,MAAMC,EAAQL,EAAWH,EAAQO,CAAK,EACtC,OAAOC,EAAM,OAASJ,EAAe,iBAAmBI,EAAQ,MAClE,CAGA,SAASC,EAAkBT,EAA6BC,EAA6B,CACnF,MAAMS,EAAWJ,EAAaN,EAAQC,CAAI,EAC1C,GAAIS,IAAa,OAAW,MAAO,CAAA,EACnC,MAAMC,EAAWC,EAAaF,EAAU,UAAU,EAClD,GAAIC,IAAa,OAAW,MAAO,CAAA,EACnC,MAAME,EAASV,EAAWH,EAAQW,EAAS,KAAK,EAChD,OAAIE,EAAO,OAAST,EAAe,iBAAyB,CAAA,EACrDS,EAAO,WAAW,QAAQC,GAAQ,CACvC,GAAIA,EAAM,OAASV,EAAe,SAAU,MAAO,CAAA,EACnD,MAAMI,EAAQL,EAAWH,EAAQc,EAAM,KAAK,EAC5C,MAAO,CACL,CACE,eAAgBN,EAAM,OAASJ,EAAe,gBAAmBI,EAAM,SAAS,CAAC,GAAK,OAAaA,EACnG,QAASA,EAAM,OAASJ,EAAe,gBAAmBI,EAAM,SAAS,CAAC,GAAK,OAAa,MAC7F,EAEL,CAAC,CACH"}
1
+ {"version":3,"file":"feature-body-records.js","sources":["../src/feature-body-records.ts"],"sourcesContent":["import { AST_NODE_TYPES } from '@typescript-eslint/types';\nimport type { TSESTree } from '@typescript-eslint/types';\n\nimport { findProperty } from './ast';\nimport { isApi, localValue } from './model-bindings';\nimport type { SourceCode } from './rule';\n\ninterface BodyRecordEntry {\n readonly implementation: TSESTree.Node | undefined;\n readonly options: TSESTree.Node | undefined;\n}\n\nfunction isBodyCall(source: SourceCode, call: TSESTree.CallExpression): boolean {\n const callee = localValue(source, call.callee);\n if (callee.type !== AST_NODE_TYPES.MemberExpression || callee.computed) return false;\n if (callee.property.type !== AST_NODE_TYPES.Identifier || callee.property.name !== 'body') return false;\n return isApi(source, callee.object, '@opetope/runtime', 'defineFeature');\n}\n\nfunction bodySections(source: SourceCode, call: TSESTree.CallExpression): TSESTree.ObjectExpression | undefined {\n if (!isBodyCall(source, call)) return undefined;\n const input = call.arguments[1];\n if (input === undefined) return undefined;\n const value = localValue(source, input);\n return value.type === AST_NODE_TYPES.ObjectExpression ? value : undefined;\n}\n\n/** Resolve local record/tuple aliases only after identifying the authentic authoring API by its import. */\nfunction bodyRecordEntries(source: SourceCode, call: TSESTree.CallExpression): readonly BodyRecordEntry[] {\n const sections = bodySections(source, call);\n if (sections === undefined) return [];\n const property = findProperty(sections, 'provides');\n if (property === undefined) return [];\n const record = localValue(source, property.value);\n if (record.type !== AST_NODE_TYPES.ObjectExpression) return [];\n return record.properties.flatMap(entry => {\n if (entry.type !== AST_NODE_TYPES.Property) return [];\n const value = localValue(source, entry.value);\n return [\n {\n implementation: value.type === AST_NODE_TYPES.ArrayExpression ? (value.elements[0] ?? undefined) : value,\n options: value.type === AST_NODE_TYPES.ArrayExpression ? (value.elements[1] ?? undefined) : undefined,\n },\n ];\n });\n}\n\nexport { bodyRecordEntries, isBodyCall };\n"],"names":["isBodyCall","source","call","callee","localValue","AST_NODE_TYPES","isApi","bodySections","input","value","bodyRecordEntries","sections","property","findProperty","record","entry"],"mappings":"8JAYA,SAASA,EAAWC,EAAoBC,EAA6B,CACnE,MAAMC,EAASC,EAAWH,EAAQC,EAAK,MAAM,EAE7C,OADIC,EAAO,OAASE,EAAe,kBAAoBF,EAAO,UAC1DA,EAAO,SAAS,OAASE,EAAe,YAAcF,EAAO,SAAS,OAAS,OAAe,GAC3FG,EAAML,EAAQE,EAAO,OAAQ,mBAAoB,eAAe,CACzE,CAEA,SAASI,EAAaN,EAAoBC,EAA6B,CACrE,GAAI,CAACF,EAAWC,EAAQC,CAAI,EAAG,OAC/B,MAAMM,EAAQN,EAAK,UAAU,CAAC,EAC9B,GAAIM,IAAU,OAAW,OACzB,MAAMC,EAAQL,EAAWH,EAAQO,CAAK,EACtC,OAAOC,EAAM,OAASJ,EAAe,iBAAmBI,EAAQ,MAClE,CAGA,SAASC,EAAkBT,EAAoBC,EAA6B,CAC1E,MAAMS,EAAWJ,EAAaN,EAAQC,CAAI,EAC1C,GAAIS,IAAa,OAAW,MAAO,CAAA,EACnC,MAAMC,EAAWC,EAAaF,EAAU,UAAU,EAClD,GAAIC,IAAa,OAAW,MAAO,CAAA,EACnC,MAAME,EAASV,EAAWH,EAAQW,EAAS,KAAK,EAChD,OAAIE,EAAO,OAAST,EAAe,iBAAyB,CAAA,EACrDS,EAAO,WAAW,QAAQC,GAAQ,CACvC,GAAIA,EAAM,OAASV,EAAe,SAAU,MAAO,CAAA,EACnD,MAAMI,EAAQL,EAAWH,EAAQc,EAAM,KAAK,EAC5C,MAAO,CACL,CACE,eAAgBN,EAAM,OAASJ,EAAe,gBAAmBI,EAAM,SAAS,CAAC,GAAK,OAAaA,EACnG,QAASA,EAAM,OAASJ,EAAe,gBAAmBI,EAAM,SAAS,CAAC,GAAK,OAAa,MAC7F,EAEL,CAAC,CACH"}
package/dist/index.d.ts CHANGED
@@ -4,13 +4,36 @@ import type { ESLint, Linter } from 'eslint';
4
4
  * to reach past a layer. `tests` defaults to the usual two shapes of a test path.
5
5
  */
6
6
  type LayerOptions = {
7
+ /**
8
+ * Globs of the layer that composes features: `layer-placement` holds there, and `no-behavior-in-integration` warns
9
+ * there, except in the files `tests` names. Omitted, the project has no such layer.
10
+ */
7
11
  readonly integration?: readonly string[];
12
+ /**
13
+ * Globs of the model layer, where `layer-placement` holds. Naming them turns on `no-subscribe-outside-models` for
14
+ * every source file except this layer and `tests`, and `scope-builder-releases-subscriptions` for every source file.
15
+ */
8
16
  readonly models?: readonly string[];
17
+ /**
18
+ * The tests that may subscribe outside the model layer and declare behavior inside the integration layer; an empty
19
+ * list leaves no exception, and `layer-placement` never steps aside for them. Omitted, every `__tests__` directory
20
+ * and every `.spec.ts` and `.spec.tsx` file.
21
+ */
9
22
  readonly tests?: readonly string[];
23
+ /** Globs of the UI layer, where `layer-placement` holds. Omitted, the project has no such layer. */
10
24
  readonly ui?: readonly string[];
11
25
  };
12
26
  type InternalImportOptions = {
27
+ /**
28
+ * Trusted library implementation and host integration files, where this rule alone is switched off; place the
29
+ * helper's blocks after `recommended`, which re-enables it.
30
+ * @default []
31
+ */
13
32
  readonly allow?: readonly string[];
33
+ /**
34
+ * The files the rule covers. Omitted, every JavaScript and TypeScript file: `js`, `jsx`, `mjs`, `cjs`, `ts`, `tsx`,
35
+ * `mts` and `cts`.
36
+ */
14
37
  readonly files?: readonly string[];
15
38
  };
16
39
  declare const plugin: {
@@ -19,68 +42,42 @@ declare const plugin: {
19
42
  version: string;
20
43
  };
21
44
  rules: {
22
- 'capture-command-cleanup': import("@typescript-eslint/utils/ts-eslint").RuleModule<"captureCommandCleanup" | "parallelCommandCleanup", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
23
- name: string;
24
- };
25
- 'define-feature-property-order': import("@typescript-eslint/utils/ts-eslint").RuleModule<"sectionOrder", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
26
- name: string;
27
- };
28
- 'id-naming': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidId" | "missingPrefix", readonly [{
45
+ 'capture-command-cleanup': import("./rule.js").RuleModule<"captureCommandCleanup" | "parallelCommandCleanup", []>;
46
+ 'define-feature-property-order': import("./rule.js").RuleModule<"sectionOrder", []>;
47
+ 'id-naming': import("./rule.js").RuleModule<"invalidId" | "missingPrefix", readonly [{
29
48
  readonly prefix?: string;
30
- }], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
31
- name: string;
32
- };
33
- 'layer-placement': import("@typescript-eslint/utils/ts-eslint").RuleModule<"misplacedDeclaration", readonly [{
49
+ }]>;
50
+ 'layer-placement': import("./rule.js").RuleModule<"misplacedDeclaration", readonly [{
34
51
  readonly layer?: "integration" | "models" | "ui";
35
- }], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
36
- name: string;
37
- };
38
- 'no-command-in-deps': import("@typescript-eslint/utils/ts-eslint").RuleModule<"commandHookInDeps" | "commandRecordInDeps" | "dependOnMember", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
39
- name: string;
40
- };
41
- 'no-internal-imports': import("@typescript-eslint/utils/ts-eslint").RuleModule<"internalImport", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
42
- name: string;
43
- };
44
- 'no-redundant-const-tuple': import("@typescript-eslint/utils/ts-eslint").RuleModule<"redundantConstTuple", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
45
- name: string;
46
- };
47
- 'no-retired-vocabulary': import("@typescript-eslint/utils/ts-eslint").RuleModule<"commandLane" | "commandLatest" | "commandName" | "commandOnce" | "commandOutcomeStatus" | "commandPolicy" | "commandQueueBy" | "conditionFrom" | "contextCall" | "contextCalls" | "contributionWhen" | "deliveryKey" | "deliveryKind" | "deliveryReject" | "effectOnDispose" | "effectSkipInitial" | "effectWhen" | "eventBackpressure" | "fromExternal" | "navigatorPolicy" | "resourceActivity" | "resourceDisposer" | "resourceInvalidate" | "runtimeInternalEntry" | "scopeKeyed" | "stateActivity" | "useCommands", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
48
- name: string;
49
- };
50
- 'no-snapshot-in-update': import("@typescript-eslint/utils/ts-eslint").RuleModule<"snapshotInUpdate" | "writeFromPrevious", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
51
- name: string;
52
- };
53
- 'no-snapshot-read-in-render': import("@typescript-eslint/utils/ts-eslint").RuleModule<"snapshotInRender", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
54
- name: string;
55
- };
56
- 'no-subscribe-outside-models': import("@typescript-eslint/utils/ts-eslint").RuleModule<"handWrittenSubscription", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
57
- name: string;
58
- };
59
- 'no-write-after-source-write': import("@typescript-eslint/utils/ts-eslint").RuleModule<"writeAfterInvokedSourceWrite" | "writeAfterSourceWrite", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
60
- name: string;
61
- };
62
- 'prefer-effect-current': import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferEffectCurrent", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
63
- name: string;
64
- };
65
- 'prefer-lazy-body-record': import("@typescript-eslint/utils/ts-eslint").RuleModule<"preferRecord", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
66
- name: string;
67
- };
68
- 'prefer-model-selection': import("@typescript-eslint/utils/ts-eslint").RuleModule<"separateHooks", readonly [{
52
+ }]>;
53
+ 'no-behavior-in-integration': import("./rule.js").RuleModule<"behaviorInIntegration", []>;
54
+ 'no-command-in-deps': import("./rule.js").RuleModule<"commandHookInDeps" | "commandRecordInDeps" | "dependOnMember", []>;
55
+ 'no-dead-abort-check': import("./rule.js").RuleModule<"deadAbortCheck", []>;
56
+ 'no-event-without-emit': import("./rule.js").RuleModule<"eventWithoutEmit", []>;
57
+ 'no-inline-requires-models': import("./rule.js").RuleModule<"inlineComponent", []>;
58
+ 'no-internal-imports': import("./rule.js").RuleModule<"internalImport", []>;
59
+ 'no-redundant-const-tuple': import("./rule.js").RuleModule<"redundantConstTuple", []>;
60
+ 'no-retired-vocabulary': import("./rule.js").RuleModule<import("./retired-vocabulary-messages.js").MessageIds, []>;
61
+ 'no-single-command-lane': import("./rule.js").RuleModule<"singleCommandLane" | "singleSelectionLane", []>;
62
+ 'no-snapshot-in-update': import("./rule.js").RuleModule<"snapshotInUpdate" | "writeFromPrevious", []>;
63
+ 'no-snapshot-read-in-render': import("./rule.js").RuleModule<"selectorIdentity" | "snapshotInRender" | "snapshotInSelector", []>;
64
+ 'no-subscribe-outside-models': import("./rule.js").RuleModule<"handWrittenSubscription", []>;
65
+ 'no-write-after-source-write': import("./rule.js").RuleModule<"writeAfterInvokedSourceWrite" | "writeAfterSourceWrite", []>;
66
+ 'prefer-derive': import("./rule.js").RuleModule<"preferDerive", []>;
67
+ 'prefer-effect-current': import("./rule.js").RuleModule<"preferEffectCurrent", []>;
68
+ 'prefer-lazy-body-record': import("./rule.js").RuleModule<"preferRecord", []>;
69
+ 'prefer-model-selection': import("./rule.js").RuleModule<"separateHooks", readonly [{
69
70
  readonly threshold: number;
70
- }], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
71
- name: string;
72
- };
73
- 'require-declared-models': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingWrapper" | "undeclaredUiModel", readonly [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
74
- name: string;
75
- };
76
- 'require-literal-id': import("@typescript-eslint/utils/ts-eslint").RuleModule<"computedId", readonly [{
71
+ }]>;
72
+ 'prefer-read': import("./rule.js").RuleModule<"preferRead", []>;
73
+ 'prefer-when-over-enabled': import("./rule.js").RuleModule<"preferWhen", []>;
74
+ 'require-declared-models': import("./rule.js").RuleModule<"missingWrapper" | "undeclaredUiModel", readonly []>;
75
+ 'require-literal-id': import("./rule.js").RuleModule<"computedId" | "missingCatalogId", readonly [{
77
76
  readonly allowInCallees: readonly string[];
78
- }], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
79
- name: string;
80
- };
81
- 'enabled-predicate': import("@typescript-eslint/utils/ts-eslint").RuleModule<"enabledIsAsync" | "enabledReturnsBareSource" | "enabledReturnsSource", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
82
- name: string;
83
- };
77
+ }]>;
78
+ 'require-static-feature': import("./rule.js").RuleModule<"duplicateSection" | "dynamicSection" | "sectionsNotLiteral" | "spreadSection" | "unknownBodySection" | "unknownSection", []>;
79
+ 'scope-builder-releases-subscriptions': import("./rule.js").RuleModule<"unreleasedSubscription" | "unreleasedViewSubscription", []>;
80
+ 'enabled-predicate': import("./rule.js").RuleModule<"enabledIsAsync" | "enabledReturnsBareSource" | "enabledReturnsSource", []>;
84
81
  };
85
82
  };
86
83
  /**
@@ -112,19 +109,29 @@ declare const configuredPlugin: {
112
109
  'opetope/define-feature-property-order': "error";
113
110
  'opetope/id-naming': "error";
114
111
  'opetope/layer-placement': "off";
112
+ 'opetope/no-behavior-in-integration': "off";
115
113
  'opetope/no-command-in-deps': "error";
114
+ 'opetope/no-dead-abort-check': "warn";
115
+ 'opetope/no-event-without-emit': "warn";
116
+ 'opetope/no-inline-requires-models': "warn";
116
117
  'opetope/no-internal-imports': "error";
117
118
  'opetope/no-redundant-const-tuple': "error";
118
119
  'opetope/no-retired-vocabulary': "error";
120
+ 'opetope/no-single-command-lane': "warn";
119
121
  'opetope/no-snapshot-in-update': "error";
120
122
  'opetope/no-snapshot-read-in-render': "error";
121
123
  'opetope/no-subscribe-outside-models': "off";
122
124
  'opetope/no-write-after-source-write': "error";
125
+ 'opetope/prefer-derive': "warn";
123
126
  'opetope/prefer-effect-current': "error";
124
127
  'opetope/prefer-lazy-body-record': "warn";
125
128
  'opetope/prefer-model-selection': "off";
129
+ 'opetope/prefer-read': "warn";
130
+ 'opetope/prefer-when-over-enabled': "warn";
126
131
  'opetope/require-declared-models': "error";
127
132
  'opetope/require-literal-id': "error";
133
+ 'opetope/require-static-feature': "warn";
134
+ 'opetope/scope-builder-releases-subscriptions': "error";
128
135
  'opetope/enabled-predicate': "error";
129
136
  };
130
137
  };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{captureCommandCleanup as p}from"./rules/capture-command-cleanup.js";import{defineFeaturePropertyOrder as s}from"./rules/define-feature-property-order.js";import{idNaming as i}from"./rules/id-naming.js";import{layerPlacement as a}from"./rules/layer-placement.js";import{noCommandInDeps as m}from"./rules/no-command-in-deps.js";import{noInternalImports as l}from"./rules/no-internal-imports.js";import{noRedundantConstTuple as d}from"./rules/no-redundant-const-tuple.js";import{noRetiredVocabulary as c}from"./rules/no-retired-vocabulary.js";import{noSnapshotInUpdate as u}from"./rules/no-snapshot-in-update.js";import{noSnapshotReadInRender as f}from"./rules/no-snapshot-read-in-render.js";import{noSubscribeOutsideModels as b}from"./rules/no-subscribe-outside-models.js";import{noWriteAfterSourceWrite as y}from"./rules/no-write-after-source-write.js";import{preferEffectCurrent as g}from"./rules/prefer-effect-current.js";import{preferLazyBodyRecord as S}from"./rules/prefer-lazy-body-record.js";import{preferModelSelection as h}from"./rules/prefer-model-selection.js";import{requireDeclaredModels as I}from"./rules/require-declared-models.js";import{requireLiteralId as R}from"./rules/require-literal-id.js";import{enabledPredicate as q}from"./rules/enabled-predicate.js";const w=["integration","models","ui"],C=["**/*.ts","**/*.tsx"],E=["**/__tests__/**","**/*.spec.ts","**/*.spec.tsx"],L={meta:{name:"@opetope/lint",version:"0.14.0"},rules:{"capture-command-cleanup":p,"define-feature-property-order":s,"id-naming":i,"layer-placement":a,"no-command-in-deps":m,"no-internal-imports":l,"no-redundant-const-tuple":d,"no-retired-vocabulary":c,"no-snapshot-in-update":u,"no-snapshot-read-in-render":f,"no-subscribe-outside-models":b,"no-write-after-source-write":y,"prefer-effect-current":g,"prefer-lazy-body-record":S,"prefer-model-selection":h,"require-declared-models":I,"require-literal-id":R,"enabled-predicate":q}},r=L,_={name:"opetope/recommended",plugins:{opetope:r},rules:{"opetope/capture-command-cleanup":"error","opetope/define-feature-property-order":"error","opetope/id-naming":"error","opetope/layer-placement":"off","opetope/no-command-in-deps":"error","opetope/no-internal-imports":"error","opetope/no-redundant-const-tuple":"error","opetope/no-retired-vocabulary":"error","opetope/no-snapshot-in-update":"error","opetope/no-snapshot-read-in-render":"error","opetope/no-subscribe-outside-models":"off","opetope/no-write-after-source-write":"error","opetope/prefer-effect-current":"error","opetope/prefer-lazy-body-record":"warn","opetope/prefer-model-selection":"off","opetope/require-declared-models":"error","opetope/require-literal-id":"error","opetope/enabled-predicate":"error"}},j=e=>w.flatMap(o=>{const t=e[o]??[];return t.length===0?[]:[{files:[...t],name:`opetope/layers-${o}`,plugins:{opetope:r},rules:{"opetope/layer-placement":["error",{layer:o}]}}]}),x=({models:e=[],tests:o=E})=>e.length===0?[]:[{files:C,name:"opetope/layers-subscriptions",plugins:{opetope:r},rules:{"opetope/no-subscribe-outside-models":"error"}},{files:[...e,...o],name:"opetope/layers-subscriptions-allowed",rules:{"opetope/no-subscribe-outside-models":"off"}}],P=e=>[...j(e),...x(e)],v=({allow:e=[],files:o=["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}"]}={})=>[{files:[...o],name:"opetope/internal-imports",plugins:{opetope:r},rules:{"opetope/no-internal-imports":"error"}},...e.length===0?[]:[{files:[...e],name:"opetope/internal-imports-allowed",rules:{"opetope/no-internal-imports":"off"}}]],M=Object.assign(r,{configs:{internalImports:v,layers:P,recommended:_}}),n=M;export{n as default,n as opetopeLint};
1
+ import{captureCommandCleanup as i}from"./rules/capture-command-cleanup.js";import{defineFeaturePropertyOrder as s}from"./rules/define-feature-property-order.js";import{idNaming as a}from"./rules/id-naming.js";import{layerPlacement as m}from"./rules/layer-placement.js";import{noBehaviorInIntegration as l}from"./rules/no-behavior-in-integration.js";import{noCommandInDeps as d}from"./rules/no-command-in-deps.js";import{noDeadAbortCheck as c}from"./rules/no-dead-abort-check.js";import{noEventWithoutEmit as u}from"./rules/no-event-without-emit.js";import{noInlineRequiresModels as f}from"./rules/no-inline-requires-models.js";import{noInternalImports as b}from"./rules/no-internal-imports.js";import{noRedundantConstTuple as g}from"./rules/no-redundant-const-tuple.js";import{noRetiredVocabulary as h}from"./rules/no-retired-vocabulary.js";import{noSingleCommandLane as v}from"./rules/no-single-command-lane.js";import{noSnapshotInUpdate as w}from"./rules/no-snapshot-in-update.js";import{noSnapshotReadInRender as y}from"./rules/no-snapshot-read-in-render.js";import{noSubscribeOutsideModels as S}from"./rules/no-subscribe-outside-models.js";import{noWriteAfterSourceWrite as q}from"./rules/no-write-after-source-write.js";import{preferDerive as I}from"./rules/prefer-derive.js";import{preferEffectCurrent as R}from"./rules/prefer-effect-current.js";import{preferLazyBodyRecord as E}from"./rules/prefer-lazy-body-record.js";import{preferModelSelection as C}from"./rules/prefer-model-selection.js";import{preferRead as L}from"./rules/prefer-read.js";import{preferWhenOverEnabled as _}from"./rules/prefer-when-over-enabled.js";import{requireDeclaredModels as j}from"./rules/require-declared-models.js";import{requireLiteralId as x}from"./rules/require-literal-id.js";import{requireStaticFeature as M}from"./rules/require-static-feature.js";import{scopeBuilderReleasesSubscriptions as O}from"./rules/scope-builder-releases-subscriptions.js";import{enabledPredicate as P}from"./rules/enabled-predicate.js";const D=["integration","models","ui"],F=["**/*.ts","**/*.tsx"],n=["**/__tests__/**","**/*.spec.ts","**/*.spec.tsx"],W={meta:{name:"@opetope/lint",version:"0.16.0"},rules:{"capture-command-cleanup":i,"define-feature-property-order":s,"id-naming":a,"layer-placement":m,"no-behavior-in-integration":l,"no-command-in-deps":d,"no-dead-abort-check":c,"no-event-without-emit":u,"no-inline-requires-models":f,"no-internal-imports":b,"no-redundant-const-tuple":g,"no-retired-vocabulary":h,"no-single-command-lane":v,"no-snapshot-in-update":w,"no-snapshot-read-in-render":y,"no-subscribe-outside-models":S,"no-write-after-source-write":q,"prefer-derive":I,"prefer-effect-current":R,"prefer-lazy-body-record":E,"prefer-model-selection":C,"prefer-read":L,"prefer-when-over-enabled":_,"require-declared-models":j,"require-literal-id":x,"require-static-feature":M,"scope-builder-releases-subscriptions":O,"enabled-predicate":P}},r=W,k={name:"opetope/recommended",plugins:{opetope:r},rules:{"opetope/capture-command-cleanup":"error","opetope/define-feature-property-order":"error","opetope/id-naming":"error","opetope/layer-placement":"off","opetope/no-behavior-in-integration":"off","opetope/no-command-in-deps":"error","opetope/no-dead-abort-check":"warn","opetope/no-event-without-emit":"warn","opetope/no-inline-requires-models":"warn","opetope/no-internal-imports":"error","opetope/no-redundant-const-tuple":"error","opetope/no-retired-vocabulary":"error","opetope/no-single-command-lane":"warn","opetope/no-snapshot-in-update":"error","opetope/no-snapshot-read-in-render":"error","opetope/no-subscribe-outside-models":"off","opetope/no-write-after-source-write":"error","opetope/prefer-derive":"warn","opetope/prefer-effect-current":"error","opetope/prefer-lazy-body-record":"warn","opetope/prefer-model-selection":"off","opetope/prefer-read":"warn","opetope/prefer-when-over-enabled":"warn","opetope/require-declared-models":"error","opetope/require-literal-id":"error","opetope/require-static-feature":"warn","opetope/scope-builder-releases-subscriptions":"error","opetope/enabled-predicate":"error"}},z=e=>D.flatMap(o=>{const t=e[o]??[];return t.length===0?[]:[{files:[...t],name:`opetope/layers-${o}`,plugins:{opetope:r},rules:{"opetope/layer-placement":["error",{layer:o}]}}]}),A=({models:e=[],tests:o=n})=>e.length===0?[]:[{files:F,name:"opetope/layers-subscriptions",plugins:{opetope:r},rules:{"opetope/no-subscribe-outside-models":"error","opetope/scope-builder-releases-subscriptions":"error"}},{files:[...e,...o],name:"opetope/layers-subscriptions-allowed",rules:{"opetope/no-subscribe-outside-models":"off"}}],B=({integration:e=[],tests:o=n})=>e.length===0?[]:[{files:[...e],...o.length===0?{}:{ignores:[...o]},name:"opetope/layers-integration-behavior",plugins:{opetope:r},rules:{"opetope/no-behavior-in-integration":"warn"}}],T=e=>[...z(e),...B(e),...A(e)],U=({allow:e=[],files:o=["**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}"]}={})=>[{files:[...o],name:"opetope/internal-imports",plugins:{opetope:r},rules:{"opetope/no-internal-imports":"error"}},...e.length===0?[]:[{files:[...e],name:"opetope/internal-imports-allowed",rules:{"opetope/no-internal-imports":"off"}}]],N=Object.assign(r,{configs:{internalImports:U,layers:T,recommended:k}}),p=N;export{p as default,p as opetopeLint};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import type { ESLint, Linter } from 'eslint';\n\nimport { captureCommandCleanup } from './rules/capture-command-cleanup';\nimport { defineFeaturePropertyOrder } from './rules/define-feature-property-order';\nimport { idNaming } from './rules/id-naming';\nimport { layerPlacement } from './rules/layer-placement';\nimport { noCommandInDeps } from './rules/no-command-in-deps';\nimport { noInternalImports } from './rules/no-internal-imports';\nimport { noRedundantConstTuple } from './rules/no-redundant-const-tuple';\nimport { noRetiredVocabulary } from './rules/no-retired-vocabulary';\nimport { noSnapshotInUpdate } from './rules/no-snapshot-in-update';\nimport { noSnapshotReadInRender } from './rules/no-snapshot-read-in-render';\nimport { noSubscribeOutsideModels } from './rules/no-subscribe-outside-models';\nimport { noWriteAfterSourceWrite } from './rules/no-write-after-source-write';\nimport { preferEffectCurrent } from './rules/prefer-effect-current';\nimport { preferLazyBodyRecord } from './rules/prefer-lazy-body-record';\nimport { preferModelSelection } from './rules/prefer-model-selection';\nimport { requireDeclaredModels } from './rules/require-declared-models';\nimport { requireLiteralId } from './rules/require-literal-id';\nimport { enabledPredicate } from './rules/enabled-predicate';\n\n/**\n * The layers a host names for itself, as globs of the files that hold each one, with the tests that are allowed\n * to reach past a layer. `tests` defaults to the usual two shapes of a test path.\n */\ntype LayerOptions = {\n readonly integration?: readonly string[];\n readonly models?: readonly string[];\n readonly tests?: readonly string[];\n readonly ui?: readonly string[];\n};\n\ntype InternalImportOptions = {\n readonly allow?: readonly string[];\n readonly files?: readonly string[];\n};\n\nconst LAYERS = ['integration', 'models', 'ui'] as const;\nconst SOURCE_FILES = ['**/*.ts', '**/*.tsx'];\nconst TEST_FILES = ['**/__tests__/**', '**/*.spec.ts', '**/*.spec.tsx'];\n\nconst plugin = {\n meta: { name: '@opetope/lint', version: '0.14.0' },\n rules: {\n 'capture-command-cleanup': captureCommandCleanup,\n 'define-feature-property-order': defineFeaturePropertyOrder,\n 'id-naming': idNaming,\n 'layer-placement': layerPlacement,\n 'no-command-in-deps': noCommandInDeps,\n 'no-internal-imports': noInternalImports,\n 'no-redundant-const-tuple': noRedundantConstTuple,\n 'no-retired-vocabulary': noRetiredVocabulary,\n 'no-snapshot-in-update': noSnapshotInUpdate,\n 'no-snapshot-read-in-render': noSnapshotReadInRender,\n 'no-subscribe-outside-models': noSubscribeOutsideModels,\n 'no-write-after-source-write': noWriteAfterSourceWrite,\n 'prefer-effect-current': preferEffectCurrent,\n 'prefer-lazy-body-record': preferLazyBodyRecord,\n 'prefer-model-selection': preferModelSelection,\n 'require-declared-models': requireDeclaredModels,\n 'require-literal-id': requireLiteralId,\n 'enabled-predicate': enabledPredicate,\n },\n};\n\n/**\n * The laws every Opetope author writes against, with no assumption about where a host keeps its files. A rule that\n * needs such an assumption is off here and arrives through `layers`. The namespace is `opetope`, so a rule reads\n * `opetope/enabled-predicate` wherever a host names it.\n */\n// Rules use the parser's typed AST internally. The public bridge exposes the\n// supported ESLint rule API; package smoke tests execute it under both linters.\ntype NativeRule = NonNullable<ESLint.Plugin['rules']>[string];\ntype NativeRules = {\n [Name in keyof typeof plugin.rules]: Omit<(typeof plugin.rules)[Name], 'create'> & NativeRule;\n};\nconst nativePlugin = plugin as unknown as { meta: typeof plugin.meta; rules: NativeRules };\n\nconst recommended = {\n name: 'opetope/recommended',\n plugins: { opetope: nativePlugin },\n rules: {\n 'opetope/capture-command-cleanup': 'error',\n 'opetope/define-feature-property-order': 'error',\n 'opetope/id-naming': 'error',\n 'opetope/layer-placement': 'off',\n 'opetope/no-command-in-deps': 'error',\n 'opetope/no-internal-imports': 'error',\n 'opetope/no-redundant-const-tuple': 'error',\n 'opetope/no-retired-vocabulary': 'error',\n 'opetope/no-snapshot-in-update': 'error',\n 'opetope/no-snapshot-read-in-render': 'error',\n 'opetope/no-subscribe-outside-models': 'off',\n 'opetope/no-write-after-source-write': 'error',\n 'opetope/prefer-effect-current': 'error',\n 'opetope/prefer-lazy-body-record': 'warn',\n 'opetope/prefer-model-selection': 'off',\n 'opetope/require-declared-models': 'error',\n 'opetope/require-literal-id': 'error',\n 'opetope/enabled-predicate': 'error',\n },\n} satisfies Linter.Config;\n\n/**\n * Placement is a convention of the project that names its layers, not a law of the framework: a layer without a\n * glob is a layer this host does not have, and it produces no configuration.\n */\nconst placement = (options: LayerOptions): readonly Linter.Config[] =>\n LAYERS.flatMap(layer => {\n const files = options[layer] ?? [];\n\n if (files.length === 0) return [];\n\n return [\n {\n files: [...files],\n name: `opetope/layers-${layer}`,\n plugins: { opetope: nativePlugin },\n rules: { 'opetope/layer-placement': ['error', { layer }] },\n } satisfies Linter.Config,\n ];\n });\n\n/**\n * A subscription is written where the state lives, so this pair arrives only with the model layer that owns it. The\n * restriction covers every source file and steps aside in that layer and in tests: a file no layer claims is\n * covered rather than forgotten.\n */\nconst subscriptions = ({ models = [], tests = TEST_FILES }: LayerOptions): readonly Linter.Config[] =>\n models.length === 0\n ? []\n : [\n {\n files: SOURCE_FILES,\n name: 'opetope/layers-subscriptions',\n plugins: { opetope: nativePlugin },\n rules: { 'opetope/no-subscribe-outside-models': 'error' },\n },\n {\n files: [...models, ...tests],\n name: 'opetope/layers-subscriptions-allowed',\n rules: { 'opetope/no-subscribe-outside-models': 'off' },\n },\n ];\n\nconst layers = (options: LayerOptions): readonly Linter.Config[] => [...placement(options), ...subscriptions(options)];\n\n/**\n * Only library implementation and explicitly named host integration can cross the internal ABI. A dedicated rule\n * leaves the project's `no-restricted-imports` untouched and also covers literal dynamic imports in JS tests.\n * Allowed files explicitly override `recommended`, which enables this rule as well.\n */\nconst internalImports = ({\n allow = [],\n files = ['**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}'],\n}: InternalImportOptions = {}): readonly Linter.Config[] => [\n {\n files: [...files],\n name: 'opetope/internal-imports',\n plugins: { opetope: nativePlugin },\n rules: { 'opetope/no-internal-imports': 'error' },\n },\n ...(allow.length === 0\n ? []\n : [\n {\n files: [...allow],\n name: 'opetope/internal-imports-allowed',\n rules: { 'opetope/no-internal-imports': 'off' as const },\n },\n ]),\n];\n\nconst configuredPlugin = Object.assign(nativePlugin, {\n configs: { internalImports, layers, recommended },\n});\n\n// ESLint consumes the rule map. Config factories are additional plugin helpers;\n// expose both contracts without requiring casts at native flat-config call sites.\n// oxlint-disable-next-line typescript/no-unnecessary-type-assertion -- Required by native ESLint config typetests.\nconst opetopeLint = configuredPlugin as unknown as typeof configuredPlugin & Pick<ESLint.Plugin, 'configs'>;\n\n/*\n * Two shapes of one object. The default is what a tool reads when it loads a plugin by path — Oxlint's `jsPlugins`\n * takes `(await import(path)).default` — and what an ESLint flat config imports by convention; the named export is\n * for a config that prefers to say which binding it takes.\n */\n// oxlint-disable-next-line import/no-default-export\n// eslint-disable-next-line import-x/no-default-export\nexport default opetopeLint;\nexport { opetopeLint };\n"],"names":["LAYERS","SOURCE_FILES","TEST_FILES","plugin","captureCommandCleanup","defineFeaturePropertyOrder","idNaming","layerPlacement","noCommandInDeps","noInternalImports","noRedundantConstTuple","noRetiredVocabulary","noSnapshotInUpdate","noSnapshotReadInRender","noSubscribeOutsideModels","noWriteAfterSourceWrite","preferEffectCurrent","preferLazyBodyRecord","preferModelSelection","requireDeclaredModels","requireLiteralId","enabledPredicate","nativePlugin","recommended","placement","options","layer","files","subscriptions","models","tests","layers","internalImports","allow","configuredPlugin","opetopeLint"],"mappings":"iwCAqCA,MAAMA,EAAS,CAAC,cAAe,SAAU,IAAI,EACvCC,EAAe,CAAC,UAAW,UAAU,EACrCC,EAAa,CAAC,kBAAmB,eAAgB,eAAe,EAEhEC,EAAS,CACb,KAAM,CAAE,KAAM,gBAAiB,QAAS,QAAQ,EAChD,MAAO,CACL,0BAA2BC,EAC3B,gCAAiCC,EACjC,YAAaC,EACb,kBAAmBC,EACnB,qBAAsBC,EACtB,sBAAuBC,EACvB,2BAA4BC,EAC5B,wBAAyBC,EACzB,wBAAyBC,EACzB,6BAA8BC,EAC9B,8BAA+BC,EAC/B,8BAA+BC,EAC/B,wBAAyBC,EACzB,0BAA2BC,EAC3B,yBAA0BC,EAC1B,0BAA2BC,EAC3B,qBAAsBC,EACtB,oBAAqBC,CACtB,GAcGC,EAAenB,EAEfoB,EAAc,CAClB,KAAM,sBACN,QAAS,CAAE,QAASD,CAAY,EAChC,MAAO,CACL,kCAAmC,QACnC,wCAAyC,QACzC,oBAAqB,QACrB,0BAA2B,MAC3B,6BAA8B,QAC9B,8BAA+B,QAC/B,mCAAoC,QACpC,gCAAiC,QACjC,gCAAiC,QACjC,qCAAsC,QACtC,sCAAuC,MACvC,sCAAuC,QACvC,gCAAiC,QACjC,kCAAmC,OACnC,iCAAkC,MAClC,kCAAmC,QACnC,6BAA8B,QAC9B,4BAA6B,OAC9B,GAOGE,EAAaC,GACjBzB,EAAO,QAAQ0B,GAAQ,CACrB,MAAMC,EAAQF,EAAQC,CAAK,GAAK,CAAA,EAEhC,OAAIC,EAAM,SAAW,EAAU,CAAA,EAExB,CACL,CACE,MAAO,CAAC,GAAGA,CAAK,EAChB,KAAM,kBAAkBD,CAAK,GAC7B,QAAS,CAAE,QAASJ,CAAY,EAChC,MAAO,CAAE,0BAA2B,CAAC,QAAS,CAAE,MAAAI,CAAK,CAAE,CAAC,CACjC,EAE7B,CAAC,EAOGE,EAAgB,CAAC,CAAE,OAAAC,EAAS,CAAA,EAAI,MAAAC,EAAQ5B,CAAU,IACtD2B,EAAO,SAAW,EACd,CAAA,EACA,CACE,CACE,MAAO5B,EACP,KAAM,+BACN,QAAS,CAAE,QAASqB,CAAY,EAChC,MAAO,CAAE,sCAAuC,OAAO,CACxD,EACD,CACE,MAAO,CAAC,GAAGO,EAAQ,GAAGC,CAAK,EAC3B,KAAM,uCACN,MAAO,CAAE,sCAAuC,KAAK,CACtD,GAGHC,EAAUN,GAAoD,CAAC,GAAGD,EAAUC,CAAO,EAAG,GAAGG,EAAcH,CAAO,CAAC,EAO/GO,EAAkB,CAAC,CACvB,MAAAC,EAAQ,CAAA,EACR,MAAAN,EAAQ,CAAC,sCAAsC,CAAC,EACvB,KAAiC,CAC1D,CACE,MAAO,CAAC,GAAGA,CAAK,EAChB,KAAM,2BACN,QAAS,CAAE,QAASL,CAAY,EAChC,MAAO,CAAE,8BAA+B,OAAO,CAChD,EACD,GAAIW,EAAM,SAAW,EACjB,CAAA,EACA,CACE,CACE,MAAO,CAAC,GAAGA,CAAK,EAChB,KAAM,mCACN,MAAO,CAAE,8BAA+B,KAAc,CACvD,IAIHC,EAAmB,OAAO,OAAOZ,EAAc,CACnD,QAAS,CAAE,gBAAAU,EAAiB,OAAAD,EAAQ,YAAAR,CAAW,CAChD,CAAA,EAKKY,EAAcD"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import type { ESLint, Linter } from 'eslint';\n\nimport { captureCommandCleanup } from './rules/capture-command-cleanup';\nimport { defineFeaturePropertyOrder } from './rules/define-feature-property-order';\nimport { idNaming } from './rules/id-naming';\nimport { layerPlacement } from './rules/layer-placement';\nimport { noBehaviorInIntegration } from './rules/no-behavior-in-integration';\nimport { noCommandInDeps } from './rules/no-command-in-deps';\nimport { noDeadAbortCheck } from './rules/no-dead-abort-check';\nimport { noEventWithoutEmit } from './rules/no-event-without-emit';\nimport { noInlineRequiresModels } from './rules/no-inline-requires-models';\nimport { noInternalImports } from './rules/no-internal-imports';\nimport { noRedundantConstTuple } from './rules/no-redundant-const-tuple';\nimport { noRetiredVocabulary } from './rules/no-retired-vocabulary';\nimport { noSingleCommandLane } from './rules/no-single-command-lane';\nimport { noSnapshotInUpdate } from './rules/no-snapshot-in-update';\nimport { noSnapshotReadInRender } from './rules/no-snapshot-read-in-render';\nimport { noSubscribeOutsideModels } from './rules/no-subscribe-outside-models';\nimport { noWriteAfterSourceWrite } from './rules/no-write-after-source-write';\nimport { preferDerive } from './rules/prefer-derive';\nimport { preferEffectCurrent } from './rules/prefer-effect-current';\nimport { preferLazyBodyRecord } from './rules/prefer-lazy-body-record';\nimport { preferModelSelection } from './rules/prefer-model-selection';\nimport { preferRead } from './rules/prefer-read';\nimport { preferWhenOverEnabled } from './rules/prefer-when-over-enabled';\nimport { requireDeclaredModels } from './rules/require-declared-models';\nimport { requireLiteralId } from './rules/require-literal-id';\nimport { requireStaticFeature } from './rules/require-static-feature';\nimport { scopeBuilderReleasesSubscriptions } from './rules/scope-builder-releases-subscriptions';\nimport { enabledPredicate } from './rules/enabled-predicate';\n\n/**\n * The layers a host names for itself, as globs of the files that hold each one, with the tests that are allowed\n * to reach past a layer. `tests` defaults to the usual two shapes of a test path.\n */\ntype LayerOptions = {\n /**\n * Globs of the layer that composes features: `layer-placement` holds there, and `no-behavior-in-integration` warns\n * there, except in the files `tests` names. Omitted, the project has no such layer.\n */\n readonly integration?: readonly string[];\n /**\n * Globs of the model layer, where `layer-placement` holds. Naming them turns on `no-subscribe-outside-models` for\n * every source file except this layer and `tests`, and `scope-builder-releases-subscriptions` for every source file.\n */\n readonly models?: readonly string[];\n /**\n * The tests that may subscribe outside the model layer and declare behavior inside the integration layer; an empty\n * list leaves no exception, and `layer-placement` never steps aside for them. Omitted, every `__tests__` directory\n * and every `.spec.ts` and `.spec.tsx` file.\n */\n readonly tests?: readonly string[];\n /** Globs of the UI layer, where `layer-placement` holds. Omitted, the project has no such layer. */\n readonly ui?: readonly string[];\n};\n\ntype InternalImportOptions = {\n /**\n * Trusted library implementation and host integration files, where this rule alone is switched off; place the\n * helper's blocks after `recommended`, which re-enables it.\n * @default []\n */\n readonly allow?: readonly string[];\n /**\n * The files the rule covers. Omitted, every JavaScript and TypeScript file: `js`, `jsx`, `mjs`, `cjs`, `ts`, `tsx`,\n * `mts` and `cts`.\n */\n readonly files?: readonly string[];\n};\n\nconst LAYERS = ['integration', 'models', 'ui'] as const;\nconst SOURCE_FILES = ['**/*.ts', '**/*.tsx'];\nconst TEST_FILES = ['**/__tests__/**', '**/*.spec.ts', '**/*.spec.tsx'];\n\nconst plugin = {\n meta: { name: '@opetope/lint', version: '0.16.0' },\n rules: {\n 'capture-command-cleanup': captureCommandCleanup,\n 'define-feature-property-order': defineFeaturePropertyOrder,\n 'id-naming': idNaming,\n 'layer-placement': layerPlacement,\n 'no-behavior-in-integration': noBehaviorInIntegration,\n 'no-command-in-deps': noCommandInDeps,\n 'no-dead-abort-check': noDeadAbortCheck,\n 'no-event-without-emit': noEventWithoutEmit,\n 'no-inline-requires-models': noInlineRequiresModels,\n 'no-internal-imports': noInternalImports,\n 'no-redundant-const-tuple': noRedundantConstTuple,\n 'no-retired-vocabulary': noRetiredVocabulary,\n 'no-single-command-lane': noSingleCommandLane,\n 'no-snapshot-in-update': noSnapshotInUpdate,\n 'no-snapshot-read-in-render': noSnapshotReadInRender,\n 'no-subscribe-outside-models': noSubscribeOutsideModels,\n 'no-write-after-source-write': noWriteAfterSourceWrite,\n 'prefer-derive': preferDerive,\n 'prefer-effect-current': preferEffectCurrent,\n 'prefer-lazy-body-record': preferLazyBodyRecord,\n 'prefer-model-selection': preferModelSelection,\n 'prefer-read': preferRead,\n 'prefer-when-over-enabled': preferWhenOverEnabled,\n 'require-declared-models': requireDeclaredModels,\n 'require-literal-id': requireLiteralId,\n 'require-static-feature': requireStaticFeature,\n 'scope-builder-releases-subscriptions': scopeBuilderReleasesSubscriptions,\n 'enabled-predicate': enabledPredicate,\n },\n};\n\n/**\n * The laws every Opetope author writes against, with no assumption about where a host keeps its files. A rule that\n * needs such an assumption is off here and arrives through `layers`. The namespace is `opetope`, so a rule reads\n * `opetope/enabled-predicate` wherever a host names it.\n */\n// Rules use the parser's typed AST internally. The public bridge exposes the\n// supported ESLint rule API; package smoke tests execute it under both linters.\ntype NativeRule = NonNullable<ESLint.Plugin['rules']>[string];\ntype NativeRules = {\n [Name in keyof typeof plugin.rules]: Omit<(typeof plugin.rules)[Name], 'create'> & NativeRule;\n};\nconst nativePlugin = plugin as unknown as { meta: typeof plugin.meta; rules: NativeRules };\n\nconst recommended = {\n name: 'opetope/recommended',\n plugins: { opetope: nativePlugin },\n rules: {\n 'opetope/capture-command-cleanup': 'error',\n 'opetope/define-feature-property-order': 'error',\n 'opetope/id-naming': 'error',\n 'opetope/layer-placement': 'off',\n 'opetope/no-behavior-in-integration': 'off',\n 'opetope/no-command-in-deps': 'error',\n 'opetope/no-dead-abort-check': 'warn',\n 'opetope/no-event-without-emit': 'warn',\n 'opetope/no-inline-requires-models': 'warn',\n 'opetope/no-internal-imports': 'error',\n 'opetope/no-redundant-const-tuple': 'error',\n 'opetope/no-retired-vocabulary': 'error',\n 'opetope/no-single-command-lane': 'warn',\n 'opetope/no-snapshot-in-update': 'error',\n 'opetope/no-snapshot-read-in-render': 'error',\n 'opetope/no-subscribe-outside-models': 'off',\n 'opetope/no-write-after-source-write': 'error',\n 'opetope/prefer-derive': 'warn',\n 'opetope/prefer-effect-current': 'error',\n 'opetope/prefer-lazy-body-record': 'warn',\n 'opetope/prefer-model-selection': 'off',\n 'opetope/prefer-read': 'warn',\n 'opetope/prefer-when-over-enabled': 'warn',\n 'opetope/require-declared-models': 'error',\n 'opetope/require-literal-id': 'error',\n 'opetope/require-static-feature': 'warn',\n 'opetope/scope-builder-releases-subscriptions': 'error',\n 'opetope/enabled-predicate': 'error',\n },\n} satisfies Linter.Config;\n\n/**\n * Placement is a convention of the project that names its layers, not a law of the framework: a layer without a\n * glob is a layer this host does not have, and it produces no configuration.\n */\nconst placement = (options: LayerOptions): readonly Linter.Config[] =>\n LAYERS.flatMap(layer => {\n const files = options[layer] ?? [];\n\n if (files.length === 0) return [];\n\n return [\n {\n files: [...files],\n name: `opetope/layers-${layer}`,\n plugins: { opetope: nativePlugin },\n rules: { 'opetope/layer-placement': ['error', { layer }] },\n } satisfies Linter.Config,\n ];\n });\n\n/**\n * A subscription is written where the state lives, so this pair arrives only with the model layer that owns it. The\n * restriction covers every source file and steps aside in that layer and in tests: a file no layer claims is\n * covered rather than forgotten. The body of a model scope builder is the exception to the exception: it returns\n * fields, not a disposer, so `scope-builder-releases-subscriptions` stays on in the model layer too (D470).\n */\nconst subscriptions = ({ models = [], tests = TEST_FILES }: LayerOptions): readonly Linter.Config[] =>\n models.length === 0\n ? []\n : [\n {\n files: SOURCE_FILES,\n name: 'opetope/layers-subscriptions',\n plugins: { opetope: nativePlugin },\n rules: {\n 'opetope/no-subscribe-outside-models': 'error',\n 'opetope/scope-builder-releases-subscriptions': 'error',\n },\n },\n {\n files: [...models, ...tests],\n name: 'opetope/layers-subscriptions-allowed',\n rules: { 'opetope/no-subscribe-outside-models': 'off' },\n },\n ];\n\n/**\n * The integration layer composes and declares no model behaviour, which is the same kind of convention, so it arrives\n * here too, as a warning. A test builds its fixtures where it stands, so the block leaves out the integration files\n * that are tests, and only those: a host that turns the rule on for its tests elsewhere keeps it there (D494).\n */\nconst behaviour = ({ integration = [], tests = TEST_FILES }: LayerOptions): readonly Linter.Config[] =>\n integration.length === 0\n ? []\n : [\n {\n files: [...integration],\n ...(tests.length === 0 ? {} : { ignores: [...tests] }),\n name: 'opetope/layers-integration-behavior',\n plugins: { opetope: nativePlugin },\n rules: { 'opetope/no-behavior-in-integration': 'warn' },\n },\n ];\n\nconst layers = (options: LayerOptions): readonly Linter.Config[] => [\n ...placement(options),\n ...behaviour(options),\n ...subscriptions(options),\n];\n\n/**\n * Only library implementation and explicitly named host integration can cross the internal ABI. A dedicated rule\n * leaves the project's `no-restricted-imports` untouched and also covers literal dynamic imports in JS tests.\n * Allowed files explicitly override `recommended`, which enables this rule as well.\n */\nconst internalImports = ({\n allow = [],\n files = ['**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}'],\n}: InternalImportOptions = {}): readonly Linter.Config[] => [\n {\n files: [...files],\n name: 'opetope/internal-imports',\n plugins: { opetope: nativePlugin },\n rules: { 'opetope/no-internal-imports': 'error' },\n },\n ...(allow.length === 0\n ? []\n : [\n {\n files: [...allow],\n name: 'opetope/internal-imports-allowed',\n rules: { 'opetope/no-internal-imports': 'off' as const },\n },\n ]),\n];\n\nconst configuredPlugin = Object.assign(nativePlugin, {\n configs: { internalImports, layers, recommended },\n});\n\n// ESLint consumes the rule map. Config factories are additional plugin helpers;\n// expose both contracts without requiring casts at native flat-config call sites.\n// oxlint-disable-next-line typescript/no-unnecessary-type-assertion -- Required by native ESLint config typetests.\nconst opetopeLint = configuredPlugin as unknown as typeof configuredPlugin & Pick<ESLint.Plugin, 'configs'>;\n\n/*\n * Two shapes of one object. The default is what a tool reads when it loads a plugin by path — Oxlint's `jsPlugins`\n * takes `(await import(path)).default` — and what an ESLint flat config imports by convention; the named export is\n * for a config that prefers to say which binding it takes.\n */\n// oxlint-disable-next-line import/no-default-export\n// eslint-disable-next-line import-x/no-default-export\nexport default opetopeLint;\nexport { opetopeLint };\n"],"names":["LAYERS","SOURCE_FILES","TEST_FILES","plugin","captureCommandCleanup","defineFeaturePropertyOrder","idNaming","layerPlacement","noBehaviorInIntegration","noCommandInDeps","noDeadAbortCheck","noEventWithoutEmit","noInlineRequiresModels","noInternalImports","noRedundantConstTuple","noRetiredVocabulary","noSingleCommandLane","noSnapshotInUpdate","noSnapshotReadInRender","noSubscribeOutsideModels","noWriteAfterSourceWrite","preferDerive","preferEffectCurrent","preferLazyBodyRecord","preferModelSelection","preferRead","preferWhenOverEnabled","requireDeclaredModels","requireLiteralId","requireStaticFeature","scopeBuilderReleasesSubscriptions","enabledPredicate","nativePlugin","recommended","placement","options","layer","files","subscriptions","models","tests","behaviour","integration","layers","internalImports","allow","configuredPlugin","opetopeLint"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import type { TSESTree } from '@typescript-eslint/utils';
2
- import { TSESLint } from '@typescript-eslint/utils';
1
+ import type { TSESTree } from '@typescript-eslint/types';
2
+ import type { SourceCode } from './rule.js';
3
3
  declare const constructors: {
4
4
  readonly condition: readonly ["@opetope/runtime", "defineCondition"];
5
5
  readonly pipe: readonly ["@opetope/core", "definePipe"];
@@ -17,10 +17,10 @@ type Entry = {
17
17
  readonly priority: number;
18
18
  readonly enabled: TSESTree.Node | undefined;
19
19
  };
20
- declare function bodyCallback(source: TSESLint.SourceCode, call: TSESTree.CallExpression): {
20
+ declare function bodyCallback(source: SourceCode, call: TSESTree.CallExpression): {
21
21
  readonly fn: TSESTree.ArrowFunctionExpression;
22
22
  readonly entries: readonly Entry[];
23
23
  } | undefined;
24
- declare function headerRecord(source: TSESLint.SourceCode, node: TSESTree.Node | undefined): TSESTree.ObjectExpression | undefined;
25
- declare function recordReplacement(source: TSESLint.SourceCode, call: TSESTree.CallExpression, fn: TSESTree.ArrowFunctionExpression, entries: readonly Entry[]): string | undefined;
24
+ declare function headerRecord(source: SourceCode, node: TSESTree.Node | undefined): TSESTree.ObjectExpression | undefined;
25
+ declare function recordReplacement(source: SourceCode, call: TSESTree.CallExpression, fn: TSESTree.ArrowFunctionExpression, entries: readonly Entry[]): string | undefined;
26
26
  export { bodyCallback, headerRecord, recordReplacement };
@@ -1,2 +1,2 @@
1
- import{AST_NODE_TYPES as u,TSESLint as b}from"@typescript-eslint/utils";import{findProperty as c,propertyName as s}from"./ast.js";import{variableOf as l,modelBinding as E,localValue as T,isApi as h,definitionOf as O}from"./model-bindings.js";const g={condition:["@opetope/runtime","defineCondition"],pipe:["@opetope/core","definePipe"],port:["@opetope/core","definePort"],register:["@opetope/core","defineRegistry"],slot:["@opetope/react","defineSlot"]};function p(e){if(e?.type!==u.ObjectExpression)return;const n=e.properties.filter(t=>t.type===u.Property&&t.kind==="init"&&!t.method&&s(t)!==void 0),r=n.map(s);return n.length===e.properties.length&&new Set(r).size===r.length?n:void 0}function A(e){return e.type===u.Literal&&typeof e.value=="number"?e.value:void 0}function F(e){if(e===void 0)return 0;if(e.type!==u.UnaryExpression)return A(e);const n=A(e.argument);return e.operator==="-"&&n!==void 0?-n:void 0}function y(e,n){return e.find(r=>s(r)===n)?.value}function k(e){const n=e===void 0?[]:p(e);if(n===void 0||n.some(t=>!["priority","enabled"].includes(s(t))))return;const r=F(y(n,"priority"));if(!(r===void 0||!Number.isFinite(r)))return{priority:r,enabled:y(n,"enabled")}}function P(e){if(e.body.type!==u.BlockStatement)return e.body;if(e.body.body.length!==1)return;const n=e.body.body[0];return n.type===u.ReturnStatement?n.argument??void 0:void 0}function v(e){const n=P(e);return n?.type===u.ObjectExpression?n:void 0}function w(e){const n=e.params[0];return e.params.length===1&&n?.type===u.ObjectPattern?n:void 0}function I(e,n,r){const t=w(n);if(t===void 0||r.type!==u.Identifier)return;const i=l(e,r),o=t.properties.find(f=>f.type===u.Property&&f.value.type===u.Identifier&&l(e,f.value)===i);if(o===void 0)return;const d=s(o);return d!==void 0&&Object.hasOwn(g,d)?d:void 0}function V(e,n){if(["port","condition"].includes(e))return n.type===u.ArrowFunctionExpression;const r=n.type===u.ArrowFunctionExpression?v(n):n;if(r?.type!==u.ObjectExpression)return!1;const t={slot:"Component",pipe:"fold",register:"key",port:"",condition:""}[e];return c(r,t)!==void 0}function D(e){const n=e.value;if(!(n.type!==u.CallExpression||n.optional))return[2,3].includes(n.arguments.length)?n:void 0}function R(e,n){const r=e.arguments[0],t=e.arguments[1],i=e.arguments[2];if(r.type!==u.Identifier||!V(n,t)||["port","condition"].includes(n)&&i!==void 0)return;const o=k(i);return o===void 0?void 0:{target:r,value:t,...o}}function N(e,n,r){const t=D(r);if(t===void 0)return;const i=I(e,n,t.callee);if(i===void 0)return;const o=R(t,i);return o===void 0?void 0:{property:r,call:t,builder:i,...o}}function $(e,n,r){const[t]=n.params;return t?.type!==u.ObjectPattern||t.properties.some(i=>!Object.hasOwn(g,s(i)??""))?!1:t.properties.every(i=>i.type!==u.Property||i.value.type!==u.Identifier?!1:l(e,i.value)?.references.every(d=>r.some(f=>f.call.callee===d.identifier))??!1)}function B(e){if(!(e?.type!==u.MemberExpression||e.computed))return e.property.type===u.Identifier&&e.property.name==="body"?e.object:void 0}function L(e){return e?.type===u.ArrowFunctionExpression&&!e.async&&!e.typeParameters?e:void 0}function z(e,n){const r=O(e,n);if(r?.type!==b.Scope.DefinitionType.Variable)return n;if(!(r.parent.kind!=="const"||r.node.id.typeAnnotation))return r.node.init??void 0}function a(e,n,r=new Set){if(n.type!==u.Identifier)return n;if(r.has(n))return;r.add(n);const t=z(e,n);return t===void 0||t===n?t:a(e,t,r)}function _(e,n,r){if(r===void 0||!h(e,r,"@opetope/runtime","defineFeature",!0))return;const t=n.arguments[1];if(t?.type!==u.ObjectExpression||p(t)===void 0)return;const i=c(t,"provides")?.value;return L(i)}function S(e,n,r=!1){const t=r?a:T,i=B(t(e,n.callee));return i===void 0?void 0:_(e,n,t(e,i))}function M(e,n){const r=S(e,n);if(r===void 0)return;const t=p(v(r));if(t===void 0||t.length===0)return;const i=t.map(d=>N(e,r,d));if(i.some(d=>d===void 0))return;const o=i;return $(e,r,o)?{fn:r,entries:o}:void 0}function j(e,n,r,t){const i=a(e,n);return i!==void 0&&h(e,i,r,t,!0)}function U(e){return e?.type===u.CallExpression&&!e.typeArguments}function W(e,n){if(n===void 0)return;const r=a(e,n);if(!U(r)||!j(e,r.callee,"@opetope/runtime","defineFeature"))return;const t=r.arguments[1];return t?.type===u.ObjectExpression&&p(t)!==void 0?t:void 0}function C(e,n){const r=W(e,n);if(r===void 0||c(r,"body")===void 0)return;const t=c(r,"provides")?.value;return t?.type===u.ObjectExpression&&p(t)!==void 0?t:void 0}function Y(e){const n=p(e),r=n===void 0?e:y(n,"target"),t=n===void 0?0:F(y(n,"priority"));return r?.type===u.Identifier?{target:r,priority:t}:void 0}function q(e,n,r){const t=Y(r);if(t===void 0||t.priority!==n.priority||E(e,t.target)!==E(e,n.target))return!1;const i=a(e,t.target),[o,d]=g[n.builder];return i!==a(e,n.target)?!1:i?.type===u.CallExpression&&j(e,i.callee,o,d)}function G(e,n,r){const t=O(e,n);return t?.type===b.Scope.DefinitionType.FunctionName?!l(e,n)?.references.some(i=>i.isWrite()):t?.type===b.Scope.DefinitionType.Variable&&t.parent.kind==="const"&&t.node.range[1]<r}function x(e,n,r){return[u.Literal,u.ArrowFunctionExpression,u.FunctionExpression].includes(n.type)?!0:n.type===u.Identifier?G(e,n,r):p(n)?.every(i=>x(e,i.value,r))??!1}function H(e){return e.type!==u.ArrowFunctionExpression?e:e.returnType||e.typeParameters?void 0:v(e)}function J(e){if(e.call.typeArguments)return!1;if(["port","condition"].includes(e.builder))return!0;const n=H(e.value),r={slot:["Component","props","models"],pipe:["fold"],register:["key","value"],port:[],condition:[]}[e.builder];return p(n)?.every(t=>r.includes(s(t)))??!1}function K(e,n,r){return n.typeArguments||e.getCommentsInside(r).length>0||S(e,n,!0)===void 0||w(r)?.typeAnnotation?!1:!e.getAncestors(n).some(t=>[u.ArrowFunctionExpression,u.FunctionExpression,u.FunctionDeclaration].includes(t.type))}function Q(e,n,r,t){if(!K(e,n,r))return;const i=p(C(e,n.arguments[0]));if(!(i===void 0||i.length!==t.length||!t.every(d=>{const f=i.find(m=>s(m)===s(d.property));return f!==void 0&&J(d)&&q(e,d,f.value)}))&&t.every(d=>x(e,d.value,n.range[0])&&(d.enabled===void 0||x(e,d.enabled,n.range[0]))))return`{ ${t.map(d=>{const f=e.getText(d.value),m=d.enabled===void 0?f:`[${f}, { enabled: ${e.getText(d.enabled)} }]`;return`${e.getText(d.property.key)}: ${m}`}).join(", ")} }`}export{M as bodyCallback,C as headerRecord,Q as recordReplacement};
1
+ import{DefinitionType as b}from"@typescript-eslint/scope-manager";import{AST_NODE_TYPES as u}from"@typescript-eslint/types";import{findProperty as c,propertyName as s}from"./ast.js";import{variableOf as l,modelBinding as h,localValue as P,isApi as E,definitionOf as O}from"./model-bindings.js";const g={condition:["@opetope/runtime","defineCondition"],pipe:["@opetope/core","definePipe"],port:["@opetope/core","definePort"],register:["@opetope/core","defineRegistry"],slot:["@opetope/react","defineSlot"]};function p(e){if(e?.type!==u.ObjectExpression)return;const n=e.properties.filter(t=>t.type===u.Property&&t.kind==="init"&&!t.method&&s(t)!==void 0),r=n.map(s);return n.length===e.properties.length&&new Set(r).size===r.length?n:void 0}function A(e){return e.type===u.Literal&&typeof e.value=="number"?e.value:void 0}function F(e){if(e===void 0)return 0;if(e.type!==u.UnaryExpression)return A(e);const n=A(e.argument);return e.operator==="-"&&n!==void 0?-n:void 0}function y(e,n){return e.find(r=>s(r)===n)?.value}function I(e){const n=e===void 0?[]:p(e);if(n===void 0||n.some(t=>!["priority","enabled"].includes(s(t))))return;const r=F(y(n,"priority"));if(!(r===void 0||!Number.isFinite(r)))return{priority:r,enabled:y(n,"enabled")}}function T(e){if(e.body.type!==u.BlockStatement)return e.body;if(e.body.body.length!==1)return;const n=e.body.body[0];return n.type===u.ReturnStatement?n.argument??void 0:void 0}function v(e){const n=T(e);return n?.type===u.ObjectExpression?n:void 0}function w(e){const n=e.params[0];return e.params.length===1&&n?.type===u.ObjectPattern?n:void 0}function S(e,n,r){const t=w(n);if(t===void 0||r.type!==u.Identifier)return;const i=l(e,r),o=t.properties.find(f=>f.type===u.Property&&f.value.type===u.Identifier&&l(e,f.value)===i);if(o===void 0)return;const d=s(o);return d!==void 0&&Object.hasOwn(g,d)?d:void 0}function V(e,n){if(["port","condition"].includes(e))return n.type===u.ArrowFunctionExpression;const r=n.type===u.ArrowFunctionExpression?v(n):n;if(r?.type!==u.ObjectExpression)return!1;const t={slot:"Component",pipe:"fold",register:"key",port:"",condition:""}[e];return c(r,t)!==void 0}function R(e){const n=e.value;if(!(n.type!==u.CallExpression||n.optional))return[2,3].includes(n.arguments.length)?n:void 0}function N(e,n){const r=e.arguments[0],t=e.arguments[1],i=e.arguments[2];if(r.type!==u.Identifier||!V(n,t)||["port","condition"].includes(n)&&i!==void 0)return;const o=I(i);return o===void 0?void 0:{target:r,value:t,...o}}function $(e,n,r){const t=R(r);if(t===void 0)return;const i=S(e,n,t.callee);if(i===void 0)return;const o=N(t,i);return o===void 0?void 0:{property:r,call:t,builder:i,...o}}function B(e,n,r){const[t]=n.params;return t?.type!==u.ObjectPattern||t.properties.some(i=>!Object.hasOwn(g,s(i)??""))?!1:t.properties.every(i=>i.type!==u.Property||i.value.type!==u.Identifier?!1:l(e,i.value)?.references.every(d=>r.some(f=>f.call.callee===d.identifier))??!1)}function D(e){if(!(e?.type!==u.MemberExpression||e.computed))return e.property.type===u.Identifier&&e.property.name==="body"?e.object:void 0}function L(e){return e?.type===u.ArrowFunctionExpression&&!e.async&&!e.typeParameters?e:void 0}function z(e,n){const r=O(e,n);if(r?.type!==b.Variable)return n;if(!(r.parent.kind!=="const"||r.node.id.typeAnnotation))return r.node.init??void 0}function a(e,n,r=new Set){if(n.type!==u.Identifier)return n;if(r.has(n))return;r.add(n);const t=z(e,n);return t===void 0||t===n?t:a(e,t,r)}function _(e,n,r){if(r===void 0||!E(e,r,"@opetope/runtime","defineFeature",!0))return;const t=n.arguments[1];if(t?.type!==u.ObjectExpression||p(t)===void 0)return;const i=c(t,"provides")?.value;return L(i)}function j(e,n,r=!1){const t=r?a:P,i=D(t(e,n.callee));return i===void 0?void 0:_(e,n,t(e,i))}function M(e,n){const r=j(e,n);if(r===void 0)return;const t=p(v(r));if(t===void 0||t.length===0)return;const i=t.map(d=>$(e,r,d));if(i.some(d=>d===void 0))return;const o=i;return B(e,r,o)?{fn:r,entries:o}:void 0}function C(e,n,r,t){const i=a(e,n);return i!==void 0&&E(e,i,r,t,!0)}function U(e){return e?.type===u.CallExpression&&!e.typeArguments}function W(e,n){if(n===void 0)return;const r=a(e,n);if(!U(r)||!C(e,r.callee,"@opetope/runtime","defineFeature"))return;const t=r.arguments[1];return t?.type===u.ObjectExpression&&p(t)!==void 0?t:void 0}function k(e,n){const r=W(e,n);if(r===void 0||c(r,"body")===void 0)return;const t=c(r,"provides")?.value;return t?.type===u.ObjectExpression&&p(t)!==void 0?t:void 0}function Y(e){const n=p(e),r=n===void 0?e:y(n,"target"),t=n===void 0?0:F(y(n,"priority"));return r?.type===u.Identifier?{target:r,priority:t}:void 0}function q(e,n,r){const t=Y(r);if(t===void 0||t.priority!==n.priority||h(e,t.target)!==h(e,n.target))return!1;const i=a(e,t.target),[o,d]=g[n.builder];return i!==a(e,n.target)?!1:i?.type===u.CallExpression&&C(e,i.callee,o,d)}function G(e,n,r){const t=O(e,n);return t?.type===b.FunctionName?!l(e,n)?.references.some(i=>i.isWrite()):t?.type===b.Variable&&t.parent.kind==="const"&&t.node.range[1]<r}function x(e,n,r){return[u.Literal,u.ArrowFunctionExpression,u.FunctionExpression].includes(n.type)?!0:n.type===u.Identifier?G(e,n,r):p(n)?.every(i=>x(e,i.value,r))??!1}function H(e){return e.type!==u.ArrowFunctionExpression?e:e.returnType||e.typeParameters?void 0:v(e)}function J(e){if(e.call.typeArguments)return!1;if(["port","condition"].includes(e.builder))return!0;const n=H(e.value),r={slot:["Component","props","models"],pipe:["fold"],register:["key","value"],port:[],condition:[]}[e.builder];return p(n)?.every(t=>r.includes(s(t)))??!1}function K(e,n,r){return n.typeArguments||e.getCommentsInside(r).length>0||j(e,n,!0)===void 0||w(r)?.typeAnnotation?!1:!e.getAncestors(n).some(t=>[u.ArrowFunctionExpression,u.FunctionExpression,u.FunctionDeclaration].includes(t.type))}function Q(e,n,r,t){if(!K(e,n,r))return;const i=p(k(e,n.arguments[0]));if(!(i===void 0||i.length!==t.length||!t.every(d=>{const f=i.find(m=>s(m)===s(d.property));return f!==void 0&&J(d)&&q(e,d,f.value)}))&&t.every(d=>x(e,d.value,n.range[0])&&(d.enabled===void 0||x(e,d.enabled,n.range[0]))))return`{ ${t.map(d=>{const f=e.getText(d.value),m=d.enabled===void 0?f:`[${f}, { enabled: ${e.getText(d.enabled)} }]`;return`${e.getText(d.property.key)}: ${m}`}).join(", ")} }`}export{M as bodyCallback,k as headerRecord,Q as recordReplacement};
2
2
  //# sourceMappingURL=lazy-body-migration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-body-migration.js","sources":["../src/lazy-body-migration.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { AST_NODE_TYPES, TSESLint } from '@typescript-eslint/utils';\n\nimport { findProperty, propertyName } from './ast';\nimport { definitionOf, isApi, localValue, modelBinding, variableOf } from './model-bindings';\n\nconst constructors = {\n condition: ['@opetope/runtime', 'defineCondition'],\n pipe: ['@opetope/core', 'definePipe'],\n port: ['@opetope/core', 'definePort'],\n register: ['@opetope/core', 'defineRegistry'],\n slot: ['@opetope/react', 'defineSlot'],\n} as const;\ntype Builder = keyof typeof constructors;\ntype Entry = {\n readonly property: TSESTree.Property;\n readonly call: TSESTree.CallExpression;\n readonly builder: Builder;\n readonly target: TSESTree.Identifier;\n readonly value: TSESTree.Expression;\n readonly priority: number;\n readonly enabled: TSESTree.Node | undefined;\n};\n\nfunction properties(node: TSESTree.Node | undefined): readonly TSESTree.Property[] | undefined {\n if (node?.type !== AST_NODE_TYPES.ObjectExpression) return undefined;\n const fields = node.properties.filter(\n (field): field is TSESTree.Property =>\n field.type === AST_NODE_TYPES.Property &&\n field.kind === 'init' &&\n !field.method &&\n propertyName(field) !== undefined,\n );\n const names = fields.map(propertyName);\n return fields.length === node.properties.length && new Set(names).size === names.length ? fields : undefined;\n}\n\nfunction literalNumber(node: TSESTree.Node): number | undefined {\n return node.type === AST_NODE_TYPES.Literal && typeof node.value === 'number' ? node.value : undefined;\n}\nfunction numeric(node: TSESTree.Node | undefined): number | undefined {\n if (node === undefined) return 0;\n if (node.type !== AST_NODE_TYPES.UnaryExpression) return literalNumber(node);\n const value = literalNumber(node.argument);\n return node.operator === '-' && value !== undefined ? -value : undefined;\n}\nfunction fieldValue(fields: readonly TSESTree.Property[], name: string): TSESTree.Node | undefined {\n return fields.find(field => propertyName(field) === name)?.value;\n}\n\nfunction modifiers(node: TSESTree.Node | undefined): Pick<Entry, 'priority' | 'enabled'> | undefined {\n const fields = node === undefined ? [] : properties(node);\n if (fields === undefined) return undefined;\n if (fields.some(field => !['priority', 'enabled'].includes(propertyName(field)!))) return undefined;\n const priority = numeric(fieldValue(fields, 'priority'));\n if (priority === undefined || !Number.isFinite(priority)) return undefined;\n return { priority, enabled: fieldValue(fields, 'enabled') };\n}\n\nfunction returnedValue(fn: TSESTree.ArrowFunctionExpression): TSESTree.Node | undefined {\n if (fn.body.type !== AST_NODE_TYPES.BlockStatement) return fn.body;\n if (fn.body.body.length !== 1) return undefined;\n const first = fn.body.body[0]!;\n return first.type === AST_NODE_TYPES.ReturnStatement ? (first.argument ?? undefined) : undefined;\n}\nfunction returnedRecord(fn: TSESTree.ArrowFunctionExpression): TSESTree.ObjectExpression | undefined {\n const value = returnedValue(fn);\n return value?.type === AST_NODE_TYPES.ObjectExpression ? value : undefined;\n}\nfunction parameterOf(fn: TSESTree.ArrowFunctionExpression): TSESTree.ObjectPattern | undefined {\n const parameter = fn.params[0];\n return fn.params.length === 1 && parameter?.type === AST_NODE_TYPES.ObjectPattern ? parameter : undefined;\n}\n\nfunction builderOf(\n source: TSESLint.SourceCode,\n fn: TSESTree.ArrowFunctionExpression,\n callee: TSESTree.Node,\n): Builder | undefined {\n const parameter = parameterOf(fn);\n if (parameter === undefined || callee.type !== AST_NODE_TYPES.Identifier) return undefined;\n const binding = variableOf(source, callee);\n const field = parameter.properties.find(\n field =>\n field.type === AST_NODE_TYPES.Property &&\n field.value.type === AST_NODE_TYPES.Identifier &&\n variableOf(source, field.value) === binding,\n );\n if (field === undefined) return undefined;\n const name = propertyName(field);\n return name !== undefined && Object.hasOwn(constructors, name) ? (name as Builder) : undefined;\n}\n\nfunction recordValue(builder: Builder, value: TSESTree.Node): value is TSESTree.Expression {\n if (['port', 'condition'].includes(builder)) return value.type === AST_NODE_TYPES.ArrowFunctionExpression;\n const record = value.type === AST_NODE_TYPES.ArrowFunctionExpression ? returnedRecord(value) : value;\n if (record?.type !== AST_NODE_TYPES.ObjectExpression) return false;\n const key = { slot: 'Component', pipe: 'fold', register: 'key', port: '', condition: '' }[builder];\n return findProperty(record, key) !== undefined;\n}\nfunction entryCall(property: TSESTree.Property): TSESTree.CallExpression | undefined {\n const call = property.value;\n if (call.type !== AST_NODE_TYPES.CallExpression || call.optional) return undefined;\n return [2, 3].includes(call.arguments.length) ? call : undefined;\n}\nfunction entryArguments(call: TSESTree.CallExpression, builder: Builder) {\n const target = call.arguments[0]!;\n const value = call.arguments[1]!;\n const options = call.arguments[2];\n if (target.type !== AST_NODE_TYPES.Identifier) return undefined;\n if (!recordValue(builder, value)) return undefined;\n if (['port', 'condition'].includes(builder) && options !== undefined) return undefined;\n const parsed = modifiers(options);\n return parsed === undefined ? undefined : { target, value, ...parsed };\n}\n\nfunction entryOf(\n source: TSESLint.SourceCode,\n fn: TSESTree.ArrowFunctionExpression,\n property: TSESTree.Property,\n): Entry | undefined {\n const call = entryCall(property);\n if (call === undefined) return undefined;\n const builder = builderOf(source, fn, call.callee);\n if (builder === undefined) return undefined;\n const args = entryArguments(call, builder);\n return args === undefined ? undefined : { property, call, builder, ...args };\n}\n\nfunction onlyBuilderCalls(\n source: TSESLint.SourceCode,\n fn: TSESTree.ArrowFunctionExpression,\n entries: readonly Entry[],\n): boolean {\n const [parameter] = fn.params;\n if (parameter?.type !== AST_NODE_TYPES.ObjectPattern) return false;\n if (parameter.properties.some(field => !Object.hasOwn(constructors, propertyName(field) ?? ''))) return false;\n return parameter.properties.every(field => {\n if (field.type !== AST_NODE_TYPES.Property || field.value.type !== AST_NODE_TYPES.Identifier) return false;\n const variable = variableOf(source, field.value);\n return (\n variable?.references.every(reference => entries.some(entry => entry.call.callee === reference.identifier)) ??\n false\n );\n });\n}\n\nfunction bodyOwner(node: TSESTree.Node | undefined): TSESTree.Node | undefined {\n if (node?.type !== AST_NODE_TYPES.MemberExpression || node.computed) return undefined;\n return node.property.type === AST_NODE_TYPES.Identifier && node.property.name === 'body' ? node.object : undefined;\n}\nfunction synchronousArrow(node: TSESTree.Node | undefined): TSESTree.ArrowFunctionExpression | undefined {\n return node?.type === AST_NODE_TYPES.ArrowFunctionExpression && !node.async && !node.typeParameters\n ? node\n : undefined;\n}\nfunction inferredInitializer(source: TSESLint.SourceCode, node: TSESTree.Identifier): TSESTree.Node | undefined {\n const definition = definitionOf(source, node);\n if (definition?.type !== TSESLint.Scope.DefinitionType.Variable) return node;\n if (definition.parent.kind !== 'const' || Boolean(definition.node.id.typeAnnotation)) return undefined;\n return definition.node.init ?? undefined;\n}\n\nfunction stableLocal(\n source: TSESLint.SourceCode,\n node: TSESTree.Node,\n seen = new Set<TSESTree.Node>(),\n): TSESTree.Node | undefined {\n if (node.type !== AST_NODE_TYPES.Identifier) return node;\n if (seen.has(node)) return undefined;\n seen.add(node);\n const initial = inferredInitializer(source, node);\n if (initial === undefined || initial === node) return initial;\n return stableLocal(source, initial, seen);\n}\nfunction bodyFunctionOf(\n source: TSESLint.SourceCode,\n call: TSESTree.CallExpression,\n owner: TSESTree.Node | undefined,\n): TSESTree.ArrowFunctionExpression | undefined {\n if (owner === undefined || !isApi(source, owner, '@opetope/runtime', 'defineFeature', true)) return undefined;\n const sections = call.arguments[1];\n if (sections?.type !== AST_NODE_TYPES.ObjectExpression || properties(sections) === undefined) return undefined;\n const fn = findProperty(sections, 'provides')?.value;\n return synchronousArrow(fn);\n}\nfunction bodyFunction(\n source: TSESLint.SourceCode,\n call: TSESTree.CallExpression,\n stable = false,\n): TSESTree.ArrowFunctionExpression | undefined {\n const resolve = stable ? stableLocal : localValue;\n const owner = bodyOwner(resolve(source, call.callee));\n return owner === undefined ? undefined : bodyFunctionOf(source, call, resolve(source, owner));\n}\n\nfunction bodyCallback(\n source: TSESLint.SourceCode,\n call: TSESTree.CallExpression,\n): { readonly fn: TSESTree.ArrowFunctionExpression; readonly entries: readonly Entry[] } | undefined {\n const fn = bodyFunction(source, call);\n if (fn === undefined) return undefined;\n const fields = properties(returnedRecord(fn));\n if (fields === undefined || fields.length === 0) return undefined;\n const entries = fields.map(field => entryOf(source, fn, field));\n if (entries.some(entry => entry === undefined)) return undefined;\n const known = entries as Entry[];\n return onlyBuilderCalls(source, fn, known) ? { fn, entries: known } : undefined;\n}\nfunction stableApi(source: TSESLint.SourceCode, callee: TSESTree.Node, module: string, name: string): boolean {\n const resolved = stableLocal(source, callee);\n return resolved !== undefined && isApi(source, resolved, module, name, true);\n}\nfunction inferredCall(node: TSESTree.Node | undefined): node is TSESTree.CallExpression {\n // The Oxlint bridge represents absent AST annotations as null; ESLint omits them.\n return node?.type === AST_NODE_TYPES.CallExpression && !node.typeArguments;\n}\nfunction headerSections(\n source: TSESLint.SourceCode,\n node: TSESTree.Node | undefined,\n): TSESTree.ObjectExpression | undefined {\n if (node === undefined) return undefined;\n const header = stableLocal(source, node);\n if (!inferredCall(header)) return undefined;\n if (!stableApi(source, header.callee, '@opetope/runtime', 'defineFeature')) return undefined;\n const sections = header.arguments[1];\n return sections?.type === AST_NODE_TYPES.ObjectExpression && properties(sections) !== undefined\n ? sections\n : undefined;\n}\n\nfunction headerRecord(\n source: TSESLint.SourceCode,\n node: TSESTree.Node | undefined,\n): TSESTree.ObjectExpression | undefined {\n const sections = headerSections(source, node);\n if (sections === undefined || findProperty(sections, 'body') === undefined) return undefined;\n const provided = findProperty(sections, 'provides')?.value;\n return provided?.type === AST_NODE_TYPES.ObjectExpression && properties(provided) !== undefined\n ? provided\n : undefined;\n}\nfunction declaredTarget(declared: TSESTree.Node) {\n const fields = properties(declared);\n const target = fields === undefined ? declared : fieldValue(fields, 'target');\n const priority = fields === undefined ? 0 : numeric(fieldValue(fields, 'priority'));\n return target?.type === AST_NODE_TYPES.Identifier ? { target, priority } : undefined;\n}\n\nfunction matchingTarget(source: TSESLint.SourceCode, entry: Entry, declared: TSESTree.Node): boolean {\n const metadata = declaredTarget(declared);\n if (metadata === undefined || metadata.priority !== entry.priority) return false;\n if (modelBinding(source, metadata.target) !== modelBinding(source, entry.target)) return false;\n const declaration = stableLocal(source, metadata.target);\n const [module, name] = constructors[entry.builder];\n if (declaration !== stableLocal(source, entry.target)) return false;\n return declaration?.type === AST_NODE_TYPES.CallExpression && stableApi(source, declaration.callee, module, name);\n}\nfunction stableReference(source: TSESLint.SourceCode, node: TSESTree.Identifier, at: number): boolean {\n const definition = definitionOf(source, node);\n if (definition?.type === TSESLint.Scope.DefinitionType.FunctionName)\n return !variableOf(source, node)?.references.some(reference => reference.isWrite());\n return (\n definition?.type === TSESLint.Scope.DefinitionType.Variable &&\n definition.parent.kind === 'const' &&\n definition.node.range[1] < at\n );\n}\n\nfunction pureValue(source: TSESLint.SourceCode, node: TSESTree.Node, at: number): boolean {\n if (\n [AST_NODE_TYPES.Literal, AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression].includes(\n node.type,\n )\n )\n return true;\n if (node.type === AST_NODE_TYPES.Identifier) return stableReference(source, node, at);\n const fields = properties(node);\n return fields?.every(field => pureValue(source, field.value, at)) ?? false;\n}\n\nfunction descriptorOf(value: TSESTree.Expression): TSESTree.Node | undefined {\n if (value.type !== AST_NODE_TYPES.ArrowFunctionExpression) return value;\n return value.returnType || value.typeParameters ? undefined : returnedRecord(value);\n}\nfunction exactDescriptor(entry: Entry): boolean {\n if (entry.call.typeArguments) return false;\n if (['port', 'condition'].includes(entry.builder)) return true;\n const record = descriptorOf(entry.value);\n const allowed: readonly string[] = {\n slot: ['Component', 'props', 'models'],\n pipe: ['fold'],\n register: ['key', 'value'],\n port: [],\n condition: [],\n }[entry.builder];\n return properties(record)?.every(field => allowed.includes(propertyName(field)!)) ?? false;\n}\n\nfunction movableCallback(\n source: TSESLint.SourceCode,\n call: TSESTree.CallExpression,\n fn: TSESTree.ArrowFunctionExpression,\n): boolean {\n if (call.typeArguments || source.getCommentsInside(fn).length > 0 || bodyFunction(source, call, true) === undefined)\n return false;\n if (parameterOf(fn)?.typeAnnotation) return false;\n return !source\n .getAncestors(call)\n .some(node =>\n [\n AST_NODE_TYPES.ArrowFunctionExpression,\n AST_NODE_TYPES.FunctionExpression,\n AST_NODE_TYPES.FunctionDeclaration,\n ].includes(node.type),\n );\n}\nfunction recordReplacement(\n source: TSESLint.SourceCode,\n call: TSESTree.CallExpression,\n fn: TSESTree.ArrowFunctionExpression,\n entries: readonly Entry[],\n): string | undefined {\n if (!movableCallback(source, call, fn)) return undefined;\n const fields = properties(headerRecord(source, call.arguments[0]));\n if (fields === undefined || fields.length !== entries.length) return undefined;\n const matches = entries.every(entry => {\n const declared = fields.find(field => propertyName(field) === propertyName(entry.property));\n return declared !== undefined && exactDescriptor(entry) && matchingTarget(source, entry, declared.value);\n });\n if (!matches) return undefined;\n if (\n !entries.every(\n entry =>\n pureValue(source, entry.value, call.range[0]) &&\n (entry.enabled === undefined || pureValue(source, entry.enabled, call.range[0])),\n )\n )\n return undefined;\n return `{ ${entries\n .map(entry => {\n const value = source.getText(entry.value);\n const implementation =\n entry.enabled === undefined ? value : `[${value}, { enabled: ${source.getText(entry.enabled)} }]`;\n return `${source.getText(entry.property.key)}: ${implementation}`;\n })\n .join(', ')} }`;\n}\n\nexport { bodyCallback, headerRecord, recordReplacement };\n"],"names":["constructors","properties","node","AST_NODE_TYPES","fields","field","propertyName","names","literalNumber","numeric","value","fieldValue","name","modifiers","priority","returnedValue","fn","first","returnedRecord","parameterOf","parameter","builderOf","source","callee","binding","variableOf","recordValue","builder","record","key","findProperty","entryCall","property","call","entryArguments","target","options","parsed","entryOf","args","onlyBuilderCalls","entries","reference","entry","bodyOwner","synchronousArrow","inferredInitializer","definition","definitionOf","TSESLint","stableLocal","seen","initial","bodyFunctionOf","owner","isApi","sections","bodyFunction","stable","resolve","localValue","bodyCallback","known","stableApi","module","resolved","inferredCall","headerSections","header","headerRecord","provided","declaredTarget","declared","matchingTarget","metadata","modelBinding","declaration","stableReference","at","pureValue","descriptorOf","exactDescriptor","allowed","movableCallback","recordReplacement","implementation"],"mappings":"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"}
1
+ {"version":3,"file":"lazy-body-migration.js","sources":["../src/lazy-body-migration.ts"],"sourcesContent":["import { DefinitionType } from '@typescript-eslint/scope-manager';\nimport { AST_NODE_TYPES } from '@typescript-eslint/types';\nimport type { TSESTree } from '@typescript-eslint/types';\n\nimport { findProperty, propertyName } from './ast';\nimport { definitionOf, isApi, localValue, modelBinding, variableOf } from './model-bindings';\nimport type { SourceCode } from './rule';\n\nconst constructors = {\n condition: ['@opetope/runtime', 'defineCondition'],\n pipe: ['@opetope/core', 'definePipe'],\n port: ['@opetope/core', 'definePort'],\n register: ['@opetope/core', 'defineRegistry'],\n slot: ['@opetope/react', 'defineSlot'],\n} as const;\ntype Builder = keyof typeof constructors;\ntype Entry = {\n readonly property: TSESTree.Property;\n readonly call: TSESTree.CallExpression;\n readonly builder: Builder;\n readonly target: TSESTree.Identifier;\n readonly value: TSESTree.Expression;\n readonly priority: number;\n readonly enabled: TSESTree.Node | undefined;\n};\n\nfunction properties(node: TSESTree.Node | undefined): readonly TSESTree.Property[] | undefined {\n if (node?.type !== AST_NODE_TYPES.ObjectExpression) return undefined;\n const fields = node.properties.filter(\n (field): field is TSESTree.Property =>\n field.type === AST_NODE_TYPES.Property &&\n field.kind === 'init' &&\n !field.method &&\n propertyName(field) !== undefined,\n );\n const names = fields.map(propertyName);\n return fields.length === node.properties.length && new Set(names).size === names.length ? fields : undefined;\n}\n\nfunction literalNumber(node: TSESTree.Node): number | undefined {\n return node.type === AST_NODE_TYPES.Literal && typeof node.value === 'number' ? node.value : undefined;\n}\nfunction numeric(node: TSESTree.Node | undefined): number | undefined {\n if (node === undefined) return 0;\n if (node.type !== AST_NODE_TYPES.UnaryExpression) return literalNumber(node);\n const value = literalNumber(node.argument);\n return node.operator === '-' && value !== undefined ? -value : undefined;\n}\nfunction fieldValue(fields: readonly TSESTree.Property[], name: string): TSESTree.Node | undefined {\n return fields.find(field => propertyName(field) === name)?.value;\n}\n\nfunction modifiers(node: TSESTree.Node | undefined): Pick<Entry, 'priority' | 'enabled'> | undefined {\n const fields = node === undefined ? [] : properties(node);\n if (fields === undefined) return undefined;\n if (fields.some(field => !['priority', 'enabled'].includes(propertyName(field)!))) return undefined;\n const priority = numeric(fieldValue(fields, 'priority'));\n if (priority === undefined || !Number.isFinite(priority)) return undefined;\n return { priority, enabled: fieldValue(fields, 'enabled') };\n}\n\nfunction returnedValue(fn: TSESTree.ArrowFunctionExpression): TSESTree.Node | undefined {\n if (fn.body.type !== AST_NODE_TYPES.BlockStatement) return fn.body;\n if (fn.body.body.length !== 1) return undefined;\n const first = fn.body.body[0]!;\n return first.type === AST_NODE_TYPES.ReturnStatement ? (first.argument ?? undefined) : undefined;\n}\nfunction returnedRecord(fn: TSESTree.ArrowFunctionExpression): TSESTree.ObjectExpression | undefined {\n const value = returnedValue(fn);\n return value?.type === AST_NODE_TYPES.ObjectExpression ? value : undefined;\n}\nfunction parameterOf(fn: TSESTree.ArrowFunctionExpression): TSESTree.ObjectPattern | undefined {\n const parameter = fn.params[0];\n return fn.params.length === 1 && parameter?.type === AST_NODE_TYPES.ObjectPattern ? parameter : undefined;\n}\n\nfunction builderOf(\n source: SourceCode,\n fn: TSESTree.ArrowFunctionExpression,\n callee: TSESTree.Node,\n): Builder | undefined {\n const parameter = parameterOf(fn);\n if (parameter === undefined || callee.type !== AST_NODE_TYPES.Identifier) return undefined;\n const binding = variableOf(source, callee);\n const field = parameter.properties.find(\n field =>\n field.type === AST_NODE_TYPES.Property &&\n field.value.type === AST_NODE_TYPES.Identifier &&\n variableOf(source, field.value) === binding,\n );\n if (field === undefined) return undefined;\n const name = propertyName(field);\n return name !== undefined && Object.hasOwn(constructors, name) ? (name as Builder) : undefined;\n}\n\nfunction recordValue(builder: Builder, value: TSESTree.Node): value is TSESTree.Expression {\n if (['port', 'condition'].includes(builder)) return value.type === AST_NODE_TYPES.ArrowFunctionExpression;\n const record = value.type === AST_NODE_TYPES.ArrowFunctionExpression ? returnedRecord(value) : value;\n if (record?.type !== AST_NODE_TYPES.ObjectExpression) return false;\n const key = { slot: 'Component', pipe: 'fold', register: 'key', port: '', condition: '' }[builder];\n return findProperty(record, key) !== undefined;\n}\nfunction entryCall(property: TSESTree.Property): TSESTree.CallExpression | undefined {\n const call = property.value;\n if (call.type !== AST_NODE_TYPES.CallExpression || call.optional) return undefined;\n return [2, 3].includes(call.arguments.length) ? call : undefined;\n}\nfunction entryArguments(call: TSESTree.CallExpression, builder: Builder) {\n const target = call.arguments[0]!;\n const value = call.arguments[1]!;\n const options = call.arguments[2];\n if (target.type !== AST_NODE_TYPES.Identifier) return undefined;\n if (!recordValue(builder, value)) return undefined;\n if (['port', 'condition'].includes(builder) && options !== undefined) return undefined;\n const parsed = modifiers(options);\n return parsed === undefined ? undefined : { target, value, ...parsed };\n}\n\nfunction entryOf(\n source: SourceCode,\n fn: TSESTree.ArrowFunctionExpression,\n property: TSESTree.Property,\n): Entry | undefined {\n const call = entryCall(property);\n if (call === undefined) return undefined;\n const builder = builderOf(source, fn, call.callee);\n if (builder === undefined) return undefined;\n const args = entryArguments(call, builder);\n return args === undefined ? undefined : { property, call, builder, ...args };\n}\n\nfunction onlyBuilderCalls(\n source: SourceCode,\n fn: TSESTree.ArrowFunctionExpression,\n entries: readonly Entry[],\n): boolean {\n const [parameter] = fn.params;\n if (parameter?.type !== AST_NODE_TYPES.ObjectPattern) return false;\n if (parameter.properties.some(field => !Object.hasOwn(constructors, propertyName(field) ?? ''))) return false;\n return parameter.properties.every(field => {\n if (field.type !== AST_NODE_TYPES.Property || field.value.type !== AST_NODE_TYPES.Identifier) return false;\n const variable = variableOf(source, field.value);\n return (\n variable?.references.every(reference => entries.some(entry => entry.call.callee === reference.identifier)) ??\n false\n );\n });\n}\n\nfunction bodyOwner(node: TSESTree.Node | undefined): TSESTree.Node | undefined {\n if (node?.type !== AST_NODE_TYPES.MemberExpression || node.computed) return undefined;\n return node.property.type === AST_NODE_TYPES.Identifier && node.property.name === 'body' ? node.object : undefined;\n}\nfunction synchronousArrow(node: TSESTree.Node | undefined): TSESTree.ArrowFunctionExpression | undefined {\n return node?.type === AST_NODE_TYPES.ArrowFunctionExpression && !node.async && !node.typeParameters\n ? node\n : undefined;\n}\nfunction inferredInitializer(source: SourceCode, node: TSESTree.Identifier): TSESTree.Node | undefined {\n const definition = definitionOf(source, node);\n if (definition?.type !== DefinitionType.Variable) return node;\n if (definition.parent.kind !== 'const' || Boolean(definition.node.id.typeAnnotation)) return undefined;\n return definition.node.init ?? undefined;\n}\n\nfunction stableLocal(\n source: SourceCode,\n node: TSESTree.Node,\n seen = new Set<TSESTree.Node>(),\n): TSESTree.Node | undefined {\n if (node.type !== AST_NODE_TYPES.Identifier) return node;\n if (seen.has(node)) return undefined;\n seen.add(node);\n const initial = inferredInitializer(source, node);\n if (initial === undefined || initial === node) return initial;\n return stableLocal(source, initial, seen);\n}\nfunction bodyFunctionOf(\n source: SourceCode,\n call: TSESTree.CallExpression,\n owner: TSESTree.Node | undefined,\n): TSESTree.ArrowFunctionExpression | undefined {\n if (owner === undefined || !isApi(source, owner, '@opetope/runtime', 'defineFeature', true)) return undefined;\n const sections = call.arguments[1];\n if (sections?.type !== AST_NODE_TYPES.ObjectExpression || properties(sections) === undefined) return undefined;\n const fn = findProperty(sections, 'provides')?.value;\n return synchronousArrow(fn);\n}\nfunction bodyFunction(\n source: SourceCode,\n call: TSESTree.CallExpression,\n stable = false,\n): TSESTree.ArrowFunctionExpression | undefined {\n const resolve = stable ? stableLocal : localValue;\n const owner = bodyOwner(resolve(source, call.callee));\n return owner === undefined ? undefined : bodyFunctionOf(source, call, resolve(source, owner));\n}\n\nfunction bodyCallback(\n source: SourceCode,\n call: TSESTree.CallExpression,\n): { readonly fn: TSESTree.ArrowFunctionExpression; readonly entries: readonly Entry[] } | undefined {\n const fn = bodyFunction(source, call);\n if (fn === undefined) return undefined;\n const fields = properties(returnedRecord(fn));\n if (fields === undefined || fields.length === 0) return undefined;\n const entries = fields.map(field => entryOf(source, fn, field));\n if (entries.some(entry => entry === undefined)) return undefined;\n const known = entries as Entry[];\n return onlyBuilderCalls(source, fn, known) ? { fn, entries: known } : undefined;\n}\nfunction stableApi(source: SourceCode, callee: TSESTree.Node, module: string, name: string): boolean {\n const resolved = stableLocal(source, callee);\n return resolved !== undefined && isApi(source, resolved, module, name, true);\n}\nfunction inferredCall(node: TSESTree.Node | undefined): node is TSESTree.CallExpression {\n // The Oxlint bridge represents absent AST annotations as null; ESLint omits them.\n return node?.type === AST_NODE_TYPES.CallExpression && !node.typeArguments;\n}\nfunction headerSections(source: SourceCode, node: TSESTree.Node | undefined): TSESTree.ObjectExpression | undefined {\n if (node === undefined) return undefined;\n const header = stableLocal(source, node);\n if (!inferredCall(header)) return undefined;\n if (!stableApi(source, header.callee, '@opetope/runtime', 'defineFeature')) return undefined;\n const sections = header.arguments[1];\n return sections?.type === AST_NODE_TYPES.ObjectExpression && properties(sections) !== undefined\n ? sections\n : undefined;\n}\n\nfunction headerRecord(source: SourceCode, node: TSESTree.Node | undefined): TSESTree.ObjectExpression | undefined {\n const sections = headerSections(source, node);\n if (sections === undefined || findProperty(sections, 'body') === undefined) return undefined;\n const provided = findProperty(sections, 'provides')?.value;\n return provided?.type === AST_NODE_TYPES.ObjectExpression && properties(provided) !== undefined\n ? provided\n : undefined;\n}\nfunction declaredTarget(declared: TSESTree.Node) {\n const fields = properties(declared);\n const target = fields === undefined ? declared : fieldValue(fields, 'target');\n const priority = fields === undefined ? 0 : numeric(fieldValue(fields, 'priority'));\n return target?.type === AST_NODE_TYPES.Identifier ? { target, priority } : undefined;\n}\n\nfunction matchingTarget(source: SourceCode, entry: Entry, declared: TSESTree.Node): boolean {\n const metadata = declaredTarget(declared);\n if (metadata === undefined || metadata.priority !== entry.priority) return false;\n if (modelBinding(source, metadata.target) !== modelBinding(source, entry.target)) return false;\n const declaration = stableLocal(source, metadata.target);\n const [module, name] = constructors[entry.builder];\n if (declaration !== stableLocal(source, entry.target)) return false;\n return declaration?.type === AST_NODE_TYPES.CallExpression && stableApi(source, declaration.callee, module, name);\n}\nfunction stableReference(source: SourceCode, node: TSESTree.Identifier, at: number): boolean {\n const definition = definitionOf(source, node);\n if (definition?.type === DefinitionType.FunctionName)\n return !variableOf(source, node)?.references.some(reference => reference.isWrite());\n return (\n definition?.type === DefinitionType.Variable && definition.parent.kind === 'const' && definition.node.range[1] < at\n );\n}\n\nfunction pureValue(source: SourceCode, node: TSESTree.Node, at: number): boolean {\n if (\n [AST_NODE_TYPES.Literal, AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression].includes(\n node.type,\n )\n )\n return true;\n if (node.type === AST_NODE_TYPES.Identifier) return stableReference(source, node, at);\n const fields = properties(node);\n return fields?.every(field => pureValue(source, field.value, at)) ?? false;\n}\n\nfunction descriptorOf(value: TSESTree.Expression): TSESTree.Node | undefined {\n if (value.type !== AST_NODE_TYPES.ArrowFunctionExpression) return value;\n return value.returnType || value.typeParameters ? undefined : returnedRecord(value);\n}\nfunction exactDescriptor(entry: Entry): boolean {\n if (entry.call.typeArguments) return false;\n if (['port', 'condition'].includes(entry.builder)) return true;\n const record = descriptorOf(entry.value);\n const allowed: readonly string[] = {\n slot: ['Component', 'props', 'models'],\n pipe: ['fold'],\n register: ['key', 'value'],\n port: [],\n condition: [],\n }[entry.builder];\n return properties(record)?.every(field => allowed.includes(propertyName(field)!)) ?? false;\n}\n\nfunction movableCallback(\n source: SourceCode,\n call: TSESTree.CallExpression,\n fn: TSESTree.ArrowFunctionExpression,\n): boolean {\n if (call.typeArguments || source.getCommentsInside(fn).length > 0 || bodyFunction(source, call, true) === undefined)\n return false;\n if (parameterOf(fn)?.typeAnnotation) return false;\n return !source\n .getAncestors(call)\n .some(node =>\n [\n AST_NODE_TYPES.ArrowFunctionExpression,\n AST_NODE_TYPES.FunctionExpression,\n AST_NODE_TYPES.FunctionDeclaration,\n ].includes(node.type),\n );\n}\nfunction recordReplacement(\n source: SourceCode,\n call: TSESTree.CallExpression,\n fn: TSESTree.ArrowFunctionExpression,\n entries: readonly Entry[],\n): string | undefined {\n if (!movableCallback(source, call, fn)) return undefined;\n const fields = properties(headerRecord(source, call.arguments[0]));\n if (fields === undefined || fields.length !== entries.length) return undefined;\n const matches = entries.every(entry => {\n const declared = fields.find(field => propertyName(field) === propertyName(entry.property));\n return declared !== undefined && exactDescriptor(entry) && matchingTarget(source, entry, declared.value);\n });\n if (!matches) return undefined;\n if (\n !entries.every(\n entry =>\n pureValue(source, entry.value, call.range[0]) &&\n (entry.enabled === undefined || pureValue(source, entry.enabled, call.range[0])),\n )\n )\n return undefined;\n return `{ ${entries\n .map(entry => {\n const value = source.getText(entry.value);\n const implementation =\n entry.enabled === undefined ? value : `[${value}, { enabled: ${source.getText(entry.enabled)} }]`;\n return `${source.getText(entry.property.key)}: ${implementation}`;\n })\n .join(', ')} }`;\n}\n\nexport { bodyCallback, headerRecord, recordReplacement };\n"],"names":["constructors","properties","node","AST_NODE_TYPES","fields","field","propertyName","names","literalNumber","numeric","value","fieldValue","name","modifiers","priority","returnedValue","fn","first","returnedRecord","parameterOf","parameter","builderOf","source","callee","binding","variableOf","recordValue","builder","record","key","findProperty","entryCall","property","call","entryArguments","target","options","parsed","entryOf","args","onlyBuilderCalls","entries","reference","entry","bodyOwner","synchronousArrow","inferredInitializer","definition","definitionOf","DefinitionType","stableLocal","seen","initial","bodyFunctionOf","owner","isApi","sections","bodyFunction","stable","resolve","localValue","bodyCallback","known","stableApi","module","resolved","inferredCall","headerSections","header","headerRecord","provided","declaredTarget","declared","matchingTarget","metadata","modelBinding","declaration","stableReference","at","pureValue","descriptorOf","exactDescriptor","allowed","movableCallback","recordReplacement","implementation"],"mappings":"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"}
@@ -1,20 +1,28 @@
1
- import type { TSESTree } from '@typescript-eslint/utils';
2
- import { TSESLint } from '@typescript-eslint/utils';
1
+ import type { TSESTree } from '@typescript-eslint/types';
2
+ import type { Definition, SourceCode, Variable } from './rule.js';
3
3
  type FunctionNode = TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression;
4
- type ModelBinding = TSESLint.Scope.Variable | string;
4
+ type ModelBinding = Variable | string;
5
5
  declare function isFunction(node: TSESTree.Node): node is FunctionNode;
6
6
  declare function unwrap(node: TSESTree.Node): TSESTree.Node;
7
- declare function variableOf(source: TSESLint.SourceCode, node: TSESTree.Identifier): TSESLint.Scope.Variable | null;
8
- declare function definitionOf(source: TSESLint.SourceCode, node: TSESTree.Identifier): TSESLint.Scope.Definition | undefined;
7
+ declare function variableOf(source: SourceCode, node: TSESTree.Identifier): Variable | null;
8
+ declare function definitionOf(source: SourceCode, node: TSESTree.Identifier): Definition | undefined;
9
+ /** An initializer proves provenance only while no other write can replace its binding. */
10
+ declare function hasWritesBeyondDefinition(variable: Variable, definition: Definition): boolean;
9
11
  /** Local values only: an imported component or a parameter has no inspectable implementation here. */
10
- declare function localValue(source: TSESLint.SourceCode, node: TSESTree.Node, seen?: Set<TSESTree.Node>): TSESTree.Node;
12
+ declare function localValue(source: SourceCode, node: TSESTree.Node, seen?: Set<TSESTree.Node>): TSESTree.Node;
13
+ declare function importName(node: TSESTree.ImportSpecifier): string;
11
14
  /** The name an API carries where it is exported, whichever way this file took it in. */
12
- declare function apiName(source: TSESLint.SourceCode, node: TSESTree.Node, module: string, exact?: boolean): string | undefined;
13
- declare function isApi(source: TSESLint.SourceCode, node: TSESTree.Node, module: string, name: string, exact?: boolean): boolean;
14
- declare function modelBinding(source: TSESLint.SourceCode, node: TSESTree.Node, seen?: Set<TSESTree.Node>): ModelBinding | undefined;
15
+ declare function apiName(source: SourceCode, node: TSESTree.Node, module: string, exact?: boolean): string | undefined;
16
+ declare function isApi(source: SourceCode, node: TSESTree.Node, module: string, name: string, exact?: boolean): boolean;
17
+ declare function modelBinding(source: SourceCode, node: TSESTree.Node, seen?: Set<TSESTree.Node>): ModelBinding | undefined;
15
18
  /** A section written as a callback right where `defineFeature` takes it: `provides: (…) => …`, `own: (…) => …`. */
16
- declare function isFeatureSection(source: TSESLint.SourceCode, fn: FunctionNode, section: string, exact?: boolean): boolean;
17
- declare function isSlot(source: TSESLint.SourceCode, node: TSESTree.Node): boolean;
18
- declare function enclosingFunction(source: TSESLint.SourceCode, node: TSESTree.Node): FunctionNode | undefined;
19
+ declare function isFeatureSection(source: SourceCode, fn: FunctionNode, section: string, exact?: boolean): boolean;
20
+ declare function isSlot(source: SourceCode, node: TSESTree.Node): boolean;
21
+ /**
22
+ * The identifiers `node` reads as references, in the scope of `holder` and every scope under it: a key of a record, a
23
+ * member after `.` and a name a pattern binds are not among them.
24
+ */
25
+ declare function referencesWithin(source: SourceCode, holder: TSESTree.Node, node: TSESTree.Node): TSESTree.Identifier[];
26
+ declare function enclosingFunction(source: SourceCode, node: TSESTree.Node): FunctionNode | undefined;
19
27
  export type { FunctionNode, ModelBinding };
20
- export { apiName, definitionOf, enclosingFunction, isApi, isFeatureSection, isFunction, isSlot, localValue, modelBinding, unwrap, variableOf, };
28
+ export { apiName, definitionOf, enclosingFunction, hasWritesBeyondDefinition, importName, isApi, isFeatureSection, isFunction, isSlot, localValue, modelBinding, referencesWithin, unwrap, variableOf, };
@@ -1,2 +1,2 @@
1
- import{AST_NODE_TYPES as i,TSESLint as f,ASTUtils as j}from"@typescript-eslint/utils";import{propertyName as m}from"./ast.js";function s(e){return e.type===i.ArrowFunctionExpression||e.type===i.FunctionDeclaration||e.type===i.FunctionExpression}function a(e){return e.type===i.TSAsExpression||e.type===i.TSSatisfiesExpression||e.type===i.TSNonNullExpression?a(e.expression):e}function d(e,t){return j.findVariable(e.getScope(t),t)}function o(e,t){return d(e,t)?.defs[0]}function l(e){if(e?.type===f.Scope.DefinitionType.FunctionName)return e.node;if(e?.type===f.Scope.DefinitionType.Variable)return e.node.init??void 0}function c(e,t,r=new Set){const n=a(t);if(n.type!==i.Identifier||r.has(n))return n;r.add(n);const p=l(o(e,n));return p===void 0?n:c(e,p,r)}function y(e){return e.imported.type===i.Identifier?e.imported.name:e.imported.value}function S(e,t,r){return e.type!==i.ImportDeclaration?!1:e.source.value===t?!0:!r&&t.startsWith("@opetope/")&&e.source.value.startsWith(".")}function x(e,t,r,n){if(t.type!==i.Identifier)return;const p=o(e,t);if(!(p?.type!==f.Scope.DefinitionType.ImportBinding||!S(p.parent,r,n)))return p.node.type===i.ImportSpecifier?y(p.node):void 0}function b(e){if(!(e.type!==i.MemberExpression||e.computed)&&!(e.property.type!==i.Identifier||e.object.type!==i.Identifier))return{name:e.property.name,object:e.object}}function F(e,t){const r=b(e);return r?.name===t?r.object:void 0}function N(e,t,r,n){const p=o(e,t);return p?.type!==f.Scope.DefinitionType.ImportBinding||!S(p.parent,r,n)?!1:p.node.type===i.ImportNamespaceSpecifier?!0:r==="react"&&p.node.type===i.ImportDefaultSpecifier}function I(e,t,r,n=!1){const p=c(e,t),u=b(p);return u===void 0?x(e,p,r,n):N(e,u.object,r,n)?u.name:void 0}function v(e,t,r,n,p=!1){return I(e,t,r,p)===n}function g(e){if(!(e?.type!==f.Scope.DefinitionType.ImportBinding||e.node.type!==i.ImportSpecifier||e.parent.type!==i.ImportDeclaration))return`import:${e.parent.source.value}:${y(e.node)}`}function A(e,t){return g(o(e,t))??d(e,t)??`unbound:${t.name}`}function T(e,t,r=new Set){const n=a(t);if(n.type!==i.Identifier)return;const p=o(e,n),u=l(p);return u?.type===i.Identifier&&!r.has(n)?(r.add(n),T(e,u,r)):A(e,n)}function P(e,t,r){if(t.type!==i.CallExpression)return!1;let n=t.callee;return n.type===i.MemberExpression&&!n.computed&&n.property.type===i.Identifier&&n.property.name==="body"&&(n=n.object),v(e,n,"@opetope/runtime","defineFeature",r)}function E(e,t,r,n=!1){const p=t.parent;return p.type===i.Property&&m(p)===r&&p.parent.type===i.ObjectExpression&&P(e,p.parent.parent,n)}function D(e,t,r){const n=o(e,t);if(!(n?.type!==f.Scope.DefinitionType.Parameter||!s(n.node)||!E(e,n.node,r)))return n.node}function M(e,t){const r=D(e,t,"provides")?.params[0];return r?.type!==i.ObjectPattern?!1:r.properties.some(n=>n.type===i.Property&&m(n)==="slot"&&n.value.type===i.Identifier&&n.value.name===t.name)}function O(e,t){const r=F(t,"slot");if(r===void 0)return!1;const p=D(e,r,"provides")?.params[0];return p?.type===i.Identifier&&p.name===r.name}function h(e,t){const r=c(e,t);return r.type===i.Identifier?M(e,r):O(e,r)}function B(e,t){return e.getAncestors(t).reverse().find(s)}export{I as apiName,o as definitionOf,B as enclosingFunction,v as isApi,E as isFeatureSection,s as isFunction,h as isSlot,c as localValue,T as modelBinding,a as unwrap,d as variableOf};
1
+ import{DefinitionType as u}from"@typescript-eslint/scope-manager";import{AST_NODE_TYPES as i}from"@typescript-eslint/types";import{propertyName as l,within as F}from"./ast.js";import{findVariable as N}from"./rule.js";function d(e){return e.type===i.ArrowFunctionExpression||e.type===i.FunctionDeclaration||e.type===i.FunctionExpression}function a(e){return e.type===i.TSAsExpression||e.type===i.TSSatisfiesExpression||e.type===i.TSNonNullExpression?a(e.expression):e}function s(e,t){return N(e.getScope(t),t)}function p(e,t){return s(e,t)?.defs[0]}function y(e){if(e?.type===u.FunctionName)return e.node;if(e?.type===u.Variable)return e.node.init??void 0}function b(e,t){const r=t.type===u.Variable?t.node.id:void 0;return e.references.some(n=>n.isWrite()&&n.identifier!==r)}function D(e,t){const r=s(e,t);if(r?.defs.length!==1)return;const n=r.defs[0];return b(r,n)?void 0:y(n)}function c(e,t,r=new Set){const n=a(t);if(n.type!==i.Identifier||r.has(n))return n;r.add(n);const o=D(e,n);return o===void 0?n:c(e,o,r)}function m(e){return e.imported.type===i.Identifier?e.imported.name:e.imported.value}function I(e,t,r){return e.type!==i.ImportDeclaration?!1:e.source.value===t?!0:!r&&t.startsWith("@opetope/")&&e.source.value.startsWith(".")}function P(e,t,r,n){if(t.type!==i.Identifier)return;const o=p(e,t);if(!(o?.type!==u.ImportBinding||!I(o.parent,r,n)))return o.node.type===i.ImportSpecifier?m(o.node):void 0}function S(e){if(!(e.type!==i.MemberExpression||e.computed)&&!(e.property.type!==i.Identifier||e.object.type!==i.Identifier))return{name:e.property.name,object:e.object}}function A(e,t){const r=S(e);return r?.name===t?r.object:void 0}function B(e,t,r,n){const o=p(e,t);return o?.type!==u.ImportBinding||!I(o.parent,r,n)?!1:o.node.type===i.ImportNamespaceSpecifier?!0:r==="react"&&o.node.type===i.ImportDefaultSpecifier}function v(e,t,r,n=!1){const o=c(e,t),f=S(o);return f===void 0?P(e,o,r,n):B(e,f.object,r,n)?f.name:void 0}function h(e,t,r,n,o=!1){return v(e,t,r,o)===n}function M(e){if(!(e?.type!==u.ImportBinding||e.node.type!==i.ImportSpecifier||e.parent.type!==i.ImportDeclaration))return`import:${e.parent.source.value}:${m(e.node)}`}function O(e,t){return M(p(e,t))??s(e,t)??`unbound:${t.name}`}function E(e,t,r=new Set){const n=a(t);if(n.type!==i.Identifier)return;const o=p(e,n),f=y(o);return f?.type===i.Identifier&&!r.has(n)?(r.add(n),E(e,f,r)):O(e,n)}function T(e,t,r){if(t.type!==i.CallExpression)return!1;let n=t.callee;return n.type===i.MemberExpression&&!n.computed&&n.property.type===i.Identifier&&n.property.name==="body"&&(n=n.object),h(e,n,"@opetope/runtime","defineFeature",r)}function g(e,t,r,n=!1){const o=t.parent;return o.type===i.Property&&l(o)===r&&o.parent.type===i.ObjectExpression&&T(e,o.parent.parent,n)}function j(e,t,r){const n=p(e,t);if(!(n?.type!==u.Parameter||!d(n.node)||!g(e,n.node,r)))return n.node}function V(e,t){const r=j(e,t,"provides")?.params[0];return r?.type!==i.ObjectPattern?!1:r.properties.some(n=>n.type===i.Property&&l(n)==="slot"&&n.value.type===i.Identifier&&n.value.name===t.name)}function W(e,t){const r=A(t,"slot");if(r===void 0)return!1;const o=j(e,r,"provides")?.params[0];return o?.type===i.Identifier&&o.name===r.name}function w(e,t){const r=c(e,t);return r.type===i.Identifier?V(e,r):W(e,r)}function x(e,t=[]){t.push(e);for(const r of e.childScopes)x(r,t);return t}function $(e,t,r){const n=[];for(const o of x(e.getScope(t)))for(const{identifier:f}of o.references)f.type===i.Identifier&&F(f,r)&&n.push(f);return n}function C(e,t){return e.getAncestors(t).reverse().find(d)}export{v as apiName,p as definitionOf,C as enclosingFunction,b as hasWritesBeyondDefinition,m as importName,h as isApi,g as isFeatureSection,d as isFunction,w as isSlot,c as localValue,E as modelBinding,$ as referencesWithin,a as unwrap,s as variableOf};
2
2
  //# sourceMappingURL=model-bindings.js.map