@suss/extractor 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -148,7 +148,7 @@ function httpRouteDiscovery(opts) {
148
148
  position: "methodName",
149
149
  nameMap: { all: "*" }
150
150
  },
151
- path: { type: "fromRegistration", position: 0 }
151
+ path: { type: "fromArgument", position: 0 }
152
152
  },
153
153
  ...opts.mount !== void 0 ? { mount: opts.mount } : {},
154
154
  requiresImport: [opts.importModule]
package/dist/index.d.cts CHANGED
@@ -23,10 +23,6 @@ type DiscoveryMatch = {
23
23
  importModule: string;
24
24
  importName: string;
25
25
  registrationChain: string[];
26
- } | {
27
- type: "decorator";
28
- decoratorModule: string;
29
- decoratorName: string;
30
26
  } | {
31
27
  type: "fileConvention";
32
28
  filePattern: string;
@@ -312,7 +308,7 @@ type DiscoveryMatch = {
312
308
  * bound to a `const` one hop away, gets expanded. Cross-file and
313
309
  * computed iterables are outside v0.
314
310
  *
315
- * Pack-author docs: `docs/internal/proposals/dynamic-registration.md`.
311
+ * Pack-author docs: `design/proposals/dynamic-registration.md`.
316
312
  */
317
313
  type: "registrationLoop";
318
314
  elementShape: {
@@ -340,7 +336,7 @@ type DiscoveryMatch = {
340
336
  * one specific module, which helps when two packages happen to export
341
337
  * a function with the same name.
342
338
  *
343
- * Pack-author docs: `docs/internal/proposals/dynamic-registration.md`.
339
+ * Pack-author docs: `design/proposals/dynamic-registration.md`.
344
340
  */
345
341
  type: "registrationTemplate";
346
342
  helperName: string;
@@ -471,7 +467,7 @@ type BindingExtraction = {
471
467
  value: string;
472
468
  };
473
469
  path: {
474
- type: "fromRegistration";
470
+ type: "fromArgument";
475
471
  position: number;
476
472
  } | {
477
473
  type: "fromArgumentProperty";
@@ -521,9 +517,6 @@ type BindingExtraction = {
521
517
  type: "fromContract";
522
518
  } | {
523
519
  type: "fromClientMethod";
524
- } | {
525
- type: "fromArgumentLiteral";
526
- position: number;
527
520
  };
528
521
  };
529
522
  interface DiscoveryPattern {
@@ -727,12 +720,6 @@ interface ContractPattern {
727
720
  };
728
721
  }
729
722
  type InputMappingPattern = {
730
- /** Single object parameter, e.g. React Router LoaderFunctionArgs */
731
- type: "singleObjectParam";
732
- paramPosition: number;
733
- /** Property name → role, e.g. { params: "pathParams", request: "request" } */
734
- knownProperties: Record<string, string>;
735
- } | {
736
723
  /** Positional parameters, e.g. Express (req, res, next) */
737
724
  type: "positionalParams";
738
725
  params: Array<{
@@ -740,10 +727,21 @@ type InputMappingPattern = {
740
727
  role: string;
741
728
  }>;
742
729
  } | {
743
- /** Destructured from framework call, e.g. ts-rest { params, body, query } */
744
- type: "destructuredObject";
745
- /** Property name → role, e.g. { params: "pathParams", body: "requestBody" } */
730
+ /**
731
+ * One object parameter whose properties are the inputs, the way
732
+ * ts-rest passes `{ params, body, query }` and React Router passes
733
+ * `{ params, request }`. A handler that destructures it gets one
734
+ * input per name it binds; a handler that takes it whole gets a
735
+ * single input, since the source does not say which properties it
736
+ * reads.
737
+ */
738
+ type: "objectParam";
739
+ /** Defaults to the first parameter. */
740
+ paramPosition?: number;
741
+ /** Property name mapped to the role it takes, e.g. `{ params: "pathParams" }`. A name not here keeps the name it was bound under. */
746
742
  knownProperties: Record<string, string>;
743
+ /** The role for a parameter taken whole. Defaults to "request". */
744
+ wholeParamRole?: string;
747
745
  } | {
748
746
  /**
749
747
  * Component props, React / Vue / Svelte-style: one parameter that
@@ -753,10 +751,10 @@ type InputMappingPattern = {
753
751
  * not destructured (`function X(props) {...}`), a single Input comes
754
752
  * out with `wholeParamRole`, which defaults to `"props"`.
755
753
  *
756
- * This differs from `destructuredObject` because the pack does not
757
- * declare the prop names up front; they are whatever the component
758
- * author wrote. It differs from `singleObjectParam` because the
759
- * destructuring pattern is respected when there is one.
754
+ * This differs from `objectParam` in two ways. The pack declares no
755
+ * prop names up front, since they are whatever the component author
756
+ * wrote, and each input records the type text of the prop, which a
757
+ * component's shape comparison reads.
760
758
  */
761
759
  type: "componentProps";
762
760
  paramPosition: number;
@@ -769,7 +767,7 @@ type InputMappingPattern = {
769
767
  * reachable-closure pass for internal library functions, where no
770
768
  * framework declares a set of roles, so the name a caller sees IS
771
769
  * the role. Destructured parameters are captured the
772
- * same way `destructuredObject` captures them, so `(ctx, { userId })`
770
+ * same way `objectParam` captures them, so `(ctx, { userId })`
773
771
  * gives two inputs, `ctx` and `userId`.
774
772
  */
775
773
  type: "allPositional";
@@ -1127,6 +1125,41 @@ interface PatternPack {
1127
1125
  * same reason as in invocationRecognizers.
1128
1126
  */
1129
1127
  accessRecognizers?: AccessRecognizer[];
1128
+ /**
1129
+ * What the pack wrote as data rather than as code, for the health
1130
+ * report. Absent for a pack written as a hand-rolled walk, which is
1131
+ * itself the thing the report says.
1132
+ */
1133
+ declarations?: PackDeclarations;
1134
+ }
1135
+ /**
1136
+ * The price a pack paid for what it matches, so the migration onto the
1137
+ * declared surface can be measured rather than asserted.
1138
+ *
1139
+ * Expressiveness is bought link by link: a link answered with data is
1140
+ * inspectable, serializable and runs on any adapter, while a link
1141
+ * answered with a function is code that only its own language runs.
1142
+ * Both are allowed, and the report says which is which.
1143
+ */
1144
+ interface PackDeclarations {
1145
+ declarations: DeclaredMatch[];
1146
+ }
1147
+ /** One thing a pack declared it matches. */
1148
+ interface DeclaredMatch {
1149
+ /** What it matches, in the pack's own words. */
1150
+ name: string;
1151
+ /** Links whose answer is data. */
1152
+ dataLinks: number;
1153
+ /** Links answered with a function, by the question each one asks. */
1154
+ functionLinks: string[];
1155
+ /**
1156
+ * Links whose function reaches the adapter's own syntax tree, by the
1157
+ * question each one asks. Reaching the tree needs a separate import,
1158
+ * so a pack cannot arrive here without saying so.
1159
+ */
1160
+ astLinks: string[];
1161
+ /** A line of code the pack says this matches, or null when it says none. */
1162
+ example: string | null;
1130
1163
  }
1131
1164
  /**
1132
1165
  * Per-call-site recognizer hook. See `PatternPack.invocationRecognizers`
@@ -1755,7 +1788,14 @@ type EffectArg = {
1755
1788
  } | {
1756
1789
  kind: "object";
1757
1790
  fields: Record<string, EffectArg>;
1758
- } | {
1791
+ }
1792
+ /**
1793
+ * The element shapes the adapter could read, which is not always one
1794
+ * per runtime element. An array a callback builds,
1795
+ * `tags.map((tag) => ({ name: tag }))`, arrives with a single item,
1796
+ * because every element it produces has that one shape.
1797
+ */
1798
+ | {
1759
1799
  kind: "array";
1760
1800
  items: EffectArg[];
1761
1801
  } | {
@@ -1964,4 +2004,4 @@ declare function terminalToOutput(terminal: RawTerminal): Output;
1964
2004
  declare function effectToIR(effect: RawEffect): Effect;
1965
2005
  declare function paramToInput(param: RawParameter): Input;
1966
2006
 
1967
- export { type AccessRecognizer, type BindingExtraction, type BodyContent, type CaseGroup, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ContractPattern, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExitKind, type ExtractorOptions, type FailureDelivery, IdMap, IdSet, type Identified, type InputMappingPattern, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, PathBudgetExceeded, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ResponsePropertyMapping, type ResponsePropertyMeaning, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, sharedGatingConditions, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, writtenReading };
2007
+ export { type AccessRecognizer, type BindingExtraction, type BodyContent, type CaseGroup, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ContractPattern, type DeclaredMatch, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExitKind, type ExtractorOptions, type FailureDelivery, IdMap, IdSet, type Identified, type InputMappingPattern, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, type PackDeclarations, PathBudgetExceeded, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ResponsePropertyMapping, type ResponsePropertyMeaning, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, sharedGatingConditions, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, writtenReading };
package/dist/index.d.ts CHANGED
@@ -23,10 +23,6 @@ type DiscoveryMatch = {
23
23
  importModule: string;
24
24
  importName: string;
25
25
  registrationChain: string[];
26
- } | {
27
- type: "decorator";
28
- decoratorModule: string;
29
- decoratorName: string;
30
26
  } | {
31
27
  type: "fileConvention";
32
28
  filePattern: string;
@@ -312,7 +308,7 @@ type DiscoveryMatch = {
312
308
  * bound to a `const` one hop away, gets expanded. Cross-file and
313
309
  * computed iterables are outside v0.
314
310
  *
315
- * Pack-author docs: `docs/internal/proposals/dynamic-registration.md`.
311
+ * Pack-author docs: `design/proposals/dynamic-registration.md`.
316
312
  */
317
313
  type: "registrationLoop";
318
314
  elementShape: {
@@ -340,7 +336,7 @@ type DiscoveryMatch = {
340
336
  * one specific module, which helps when two packages happen to export
341
337
  * a function with the same name.
342
338
  *
343
- * Pack-author docs: `docs/internal/proposals/dynamic-registration.md`.
339
+ * Pack-author docs: `design/proposals/dynamic-registration.md`.
344
340
  */
345
341
  type: "registrationTemplate";
346
342
  helperName: string;
@@ -471,7 +467,7 @@ type BindingExtraction = {
471
467
  value: string;
472
468
  };
473
469
  path: {
474
- type: "fromRegistration";
470
+ type: "fromArgument";
475
471
  position: number;
476
472
  } | {
477
473
  type: "fromArgumentProperty";
@@ -521,9 +517,6 @@ type BindingExtraction = {
521
517
  type: "fromContract";
522
518
  } | {
523
519
  type: "fromClientMethod";
524
- } | {
525
- type: "fromArgumentLiteral";
526
- position: number;
527
520
  };
528
521
  };
529
522
  interface DiscoveryPattern {
@@ -727,12 +720,6 @@ interface ContractPattern {
727
720
  };
728
721
  }
729
722
  type InputMappingPattern = {
730
- /** Single object parameter, e.g. React Router LoaderFunctionArgs */
731
- type: "singleObjectParam";
732
- paramPosition: number;
733
- /** Property name → role, e.g. { params: "pathParams", request: "request" } */
734
- knownProperties: Record<string, string>;
735
- } | {
736
723
  /** Positional parameters, e.g. Express (req, res, next) */
737
724
  type: "positionalParams";
738
725
  params: Array<{
@@ -740,10 +727,21 @@ type InputMappingPattern = {
740
727
  role: string;
741
728
  }>;
742
729
  } | {
743
- /** Destructured from framework call, e.g. ts-rest { params, body, query } */
744
- type: "destructuredObject";
745
- /** Property name → role, e.g. { params: "pathParams", body: "requestBody" } */
730
+ /**
731
+ * One object parameter whose properties are the inputs, the way
732
+ * ts-rest passes `{ params, body, query }` and React Router passes
733
+ * `{ params, request }`. A handler that destructures it gets one
734
+ * input per name it binds; a handler that takes it whole gets a
735
+ * single input, since the source does not say which properties it
736
+ * reads.
737
+ */
738
+ type: "objectParam";
739
+ /** Defaults to the first parameter. */
740
+ paramPosition?: number;
741
+ /** Property name mapped to the role it takes, e.g. `{ params: "pathParams" }`. A name not here keeps the name it was bound under. */
746
742
  knownProperties: Record<string, string>;
743
+ /** The role for a parameter taken whole. Defaults to "request". */
744
+ wholeParamRole?: string;
747
745
  } | {
748
746
  /**
749
747
  * Component props, React / Vue / Svelte-style: one parameter that
@@ -753,10 +751,10 @@ type InputMappingPattern = {
753
751
  * not destructured (`function X(props) {...}`), a single Input comes
754
752
  * out with `wholeParamRole`, which defaults to `"props"`.
755
753
  *
756
- * This differs from `destructuredObject` because the pack does not
757
- * declare the prop names up front; they are whatever the component
758
- * author wrote. It differs from `singleObjectParam` because the
759
- * destructuring pattern is respected when there is one.
754
+ * This differs from `objectParam` in two ways. The pack declares no
755
+ * prop names up front, since they are whatever the component author
756
+ * wrote, and each input records the type text of the prop, which a
757
+ * component's shape comparison reads.
760
758
  */
761
759
  type: "componentProps";
762
760
  paramPosition: number;
@@ -769,7 +767,7 @@ type InputMappingPattern = {
769
767
  * reachable-closure pass for internal library functions, where no
770
768
  * framework declares a set of roles, so the name a caller sees IS
771
769
  * the role. Destructured parameters are captured the
772
- * same way `destructuredObject` captures them, so `(ctx, { userId })`
770
+ * same way `objectParam` captures them, so `(ctx, { userId })`
773
771
  * gives two inputs, `ctx` and `userId`.
774
772
  */
775
773
  type: "allPositional";
@@ -1127,6 +1125,41 @@ interface PatternPack {
1127
1125
  * same reason as in invocationRecognizers.
1128
1126
  */
1129
1127
  accessRecognizers?: AccessRecognizer[];
1128
+ /**
1129
+ * What the pack wrote as data rather than as code, for the health
1130
+ * report. Absent for a pack written as a hand-rolled walk, which is
1131
+ * itself the thing the report says.
1132
+ */
1133
+ declarations?: PackDeclarations;
1134
+ }
1135
+ /**
1136
+ * The price a pack paid for what it matches, so the migration onto the
1137
+ * declared surface can be measured rather than asserted.
1138
+ *
1139
+ * Expressiveness is bought link by link: a link answered with data is
1140
+ * inspectable, serializable and runs on any adapter, while a link
1141
+ * answered with a function is code that only its own language runs.
1142
+ * Both are allowed, and the report says which is which.
1143
+ */
1144
+ interface PackDeclarations {
1145
+ declarations: DeclaredMatch[];
1146
+ }
1147
+ /** One thing a pack declared it matches. */
1148
+ interface DeclaredMatch {
1149
+ /** What it matches, in the pack's own words. */
1150
+ name: string;
1151
+ /** Links whose answer is data. */
1152
+ dataLinks: number;
1153
+ /** Links answered with a function, by the question each one asks. */
1154
+ functionLinks: string[];
1155
+ /**
1156
+ * Links whose function reaches the adapter's own syntax tree, by the
1157
+ * question each one asks. Reaching the tree needs a separate import,
1158
+ * so a pack cannot arrive here without saying so.
1159
+ */
1160
+ astLinks: string[];
1161
+ /** A line of code the pack says this matches, or null when it says none. */
1162
+ example: string | null;
1130
1163
  }
1131
1164
  /**
1132
1165
  * Per-call-site recognizer hook. See `PatternPack.invocationRecognizers`
@@ -1755,7 +1788,14 @@ type EffectArg = {
1755
1788
  } | {
1756
1789
  kind: "object";
1757
1790
  fields: Record<string, EffectArg>;
1758
- } | {
1791
+ }
1792
+ /**
1793
+ * The element shapes the adapter could read, which is not always one
1794
+ * per runtime element. An array a callback builds,
1795
+ * `tags.map((tag) => ({ name: tag }))`, arrives with a single item,
1796
+ * because every element it produces has that one shape.
1797
+ */
1798
+ | {
1759
1799
  kind: "array";
1760
1800
  items: EffectArg[];
1761
1801
  } | {
@@ -1964,4 +2004,4 @@ declare function terminalToOutput(terminal: RawTerminal): Output;
1964
2004
  declare function effectToIR(effect: RawEffect): Effect;
1965
2005
  declare function paramToInput(param: RawParameter): Input;
1966
2006
 
1967
- export { type AccessRecognizer, type BindingExtraction, type BodyContent, type CaseGroup, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ContractPattern, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExitKind, type ExtractorOptions, type FailureDelivery, IdMap, IdSet, type Identified, type InputMappingPattern, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, PathBudgetExceeded, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ResponsePropertyMapping, type ResponsePropertyMeaning, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, sharedGatingConditions, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, writtenReading };
2007
+ export { type AccessRecognizer, type BindingExtraction, type BodyContent, type CaseGroup, type ChosenReading, type ConditionHandle, type ConditionInfo, type ConditionSource, type ContractPattern, type DeclaredMatch, type DefaultedReading, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExitKind, type ExtractorOptions, type FailureDelivery, IdMap, IdSet, type Identified, type InputMappingPattern, type InvocationRecognizer, type LanguageAdapter, type LoweredStatementParts, type PackDeclarations, PathBudgetExceeded, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type Reading, type ResponsePropertyMapping, type ResponsePropertyMeaning, type SourceRange, type StatementBlock, type StructuredPathConditionsInput, type StructuredPathConditionsResult, type StructuredStatement, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, UnmodeledFlow, absentReading, ambiguousReading, andThenReading, assembleSummary, assessConfidence, detectGaps, effectToIR, enumerateOrDegrade, enumerateStructuredPaths, firstWrittenReading, httpRouteDiscovery, makeTransitionId, mapReading, paramToInput, sharedGatingConditions, terminalToOutput, unreadableReading, unwrapJsonStringify, valueToReadFurtherFrom, writtenReading };
package/dist/index.js CHANGED
@@ -106,7 +106,7 @@ function httpRouteDiscovery(opts) {
106
106
  position: "methodName",
107
107
  nameMap: { all: "*" }
108
108
  },
109
- path: { type: "fromRegistration", position: 0 }
109
+ path: { type: "fromArgument", position: 0 }
110
110
  },
111
111
  ...opts.mount !== void 0 ? { mount: opts.mount } : {},
112
112
  requiresImport: [opts.importModule]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/extractor",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic extraction pipeline that turns raw extractions into suss behavioral summaries.",
6
6
  "keywords": [
@@ -45,7 +45,7 @@
45
45
  "typecheck": "tsc --noEmit"
46
46
  },
47
47
  "dependencies": {
48
- "@suss/behavioral-ir": "0.11.0"
48
+ "@suss/behavioral-ir": "0.13.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "tsup": "*",