@shrkcrft/boundaries 0.1.0-alpha.26 → 0.1.0-alpha.27
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/wiring/registration-graph.d.ts +27 -2
- package/dist/wiring/registration-graph.d.ts.map +1 -1
- package/dist/wiring/registration-graph.js +51 -2
- package/dist/wiring/trace-literal.d.ts +6 -0
- package/dist/wiring/trace-literal.d.ts.map +1 -1
- package/dist/wiring/trace-literal.js +22 -0
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { IRegistrationIdiom } from '@shrkcrft/core';
|
|
2
|
+
import { type IWiringFileEntry } from './evaluate-wiring.js';
|
|
2
3
|
export declare const REGISTRATION_GRAPH_SCHEMA: "sharkcraft.registration-graph/v1";
|
|
3
4
|
/** A token role-site: which idiom + file:line it was found at. */
|
|
4
5
|
export interface IRegistrationSite {
|
|
@@ -54,6 +55,14 @@ export declare function buildRegistrationGraph(projectRoot: string, idioms: read
|
|
|
54
55
|
* only (no file reads), so it stays far cheaper than a full build. Never throws.
|
|
55
56
|
*/
|
|
56
57
|
export declare function registrationGraphSignature(projectRoot: string, idioms: readonly IRegistrationIdiom[], options?: IBuildRegistrationGraphOptions): string;
|
|
58
|
+
/**
|
|
59
|
+
* The set of tokens the given file entries PROVIDE under any idiom. Used to diff
|
|
60
|
+
* a base-ref snapshot against the worktree: a REMOVED provider leaves NO site in
|
|
61
|
+
* the changed file (so post-change site-scoping can't see it), but the base
|
|
62
|
+
* content still shows the token was provided there — so a provider deletion
|
|
63
|
+
* (the most common way DI wiring silently breaks) stays change-attributable.
|
|
64
|
+
*/
|
|
65
|
+
export declare function providedTokensFromEntries(idioms: readonly IRegistrationIdiom[], entries: readonly IWiringFileEntry[]): Set<string>;
|
|
57
66
|
/** A token's full registration chain, with role presence flags. */
|
|
58
67
|
export interface IRegistrationChain extends IRegistrationNode {
|
|
59
68
|
readonly isDeclared: boolean;
|
|
@@ -71,13 +80,26 @@ export interface IUnprovidedToken {
|
|
|
71
80
|
readonly declared: readonly IRegistrationSite[];
|
|
72
81
|
readonly consumed: readonly IRegistrationSite[];
|
|
73
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Does the changed-file set touch ANY role-site of ANY token in the graph? Lets
|
|
85
|
+
* a changed-only gate tell "evaluated the registration scope, found it clean"
|
|
86
|
+
* (a real pass) apart from "the change touched no wiring at all" (nothing to
|
|
87
|
+
* verify → the caller should skip, never paint green). An empty `changedFiles`
|
|
88
|
+
* is vacuously false.
|
|
89
|
+
*/
|
|
90
|
+
export declare function registrationTouchesChanged(graph: IRegistrationGraph, changedFiles: readonly string[]): boolean;
|
|
74
91
|
/**
|
|
75
92
|
* `wiring unprovided` — tokens that are DECLARED or CONSUMED but have ZERO
|
|
76
93
|
* provided sites. This is the silent-at-runtime class: typecheck/AOT-green, but
|
|
77
94
|
* the provider is never registered (or the injected token has no provider
|
|
78
95
|
* anywhere), so it resolves to undefined at runtime. The thing imports can't see.
|
|
96
|
+
*
|
|
97
|
+
* When `changedFiles` is supplied the result is CHANGESET-SCOPED: a token is
|
|
98
|
+
* kept only if one of its declared/consumed sites is in the changed set — i.e.
|
|
99
|
+
* "did THIS change leave a token unprovided", the change-attributed question a
|
|
100
|
+
* `wiring unprovided --changed-only` gate needs.
|
|
79
101
|
*/
|
|
80
|
-
export declare function registrationUnprovided(graph: IRegistrationGraph): readonly IUnprovidedToken[];
|
|
102
|
+
export declare function registrationUnprovided(graph: IRegistrationGraph, changedFiles?: readonly string[]): readonly IUnprovidedToken[];
|
|
81
103
|
/** A token provided/registered that nothing consumes — a dead registration. */
|
|
82
104
|
export interface IOrphanRegistration {
|
|
83
105
|
readonly token: string;
|
|
@@ -87,6 +109,9 @@ export interface IOrphanRegistration {
|
|
|
87
109
|
* `wiring orphans` — tokens that ARE provided/registered but have ZERO consumed
|
|
88
110
|
* sites: a provider/registration nothing injects (a build-clean no-op, or a
|
|
89
111
|
* sign the consumer was renamed/removed).
|
|
112
|
+
*
|
|
113
|
+
* `changedFiles`, when supplied, scopes the result to orphans whose provided
|
|
114
|
+
* site is in the changed set (the registration THIS change added/touched).
|
|
90
115
|
*/
|
|
91
|
-
export declare function registrationOrphans(graph: IRegistrationGraph): readonly IOrphanRegistration[];
|
|
116
|
+
export declare function registrationOrphans(graph: IRegistrationGraph, changedFiles?: readonly string[]): readonly IOrphanRegistration[];
|
|
92
117
|
//# sourceMappingURL=registration-graph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration-graph.d.ts","sourceRoot":"","sources":["../../src/wiring/registration-graph.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"registration-graph.d.ts","sourceRoot":"","sources":["../../src/wiring/registration-graph.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,gBAAgB,CAAC;AAGxE,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEjF,eAAO,MAAM,yBAAyB,EAAG,kCAA2C,CAAC;AAErF,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACjD;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,yBAAyB,CAAC;IAClD,kDAAkD;IAClD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,8BAA8B;IAC7C,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1C;AAiBD;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,OAAO,GAAE,8BAAmC,GAC3C,kBAAkB,CAqDpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,OAAO,GAAE,8BAAmC,GAC3C,MAAM,CAiBR;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,kBAAkB,EAAE,EACrC,OAAO,EAAE,SAAS,gBAAgB,EAAE,GACnC,GAAG,CAAC,MAAM,CAAC,CAOb;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,MAAM,GACZ,kBAAkB,GAAG,SAAS,CAShC;AAED,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAChD,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACjD;AAeD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,kBAAkB,EACzB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,OAAO,CAMT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,kBAAkB,EACzB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAC/B,SAAS,gBAAgB,EAAE,CAM7B;AAED,+EAA+E;AAC/E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACjD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,kBAAkB,EACzB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAC/B,SAAS,mBAAmB,EAAE,CAMhC"}
|
|
@@ -86,6 +86,22 @@ export function registrationGraphSignature(projectRoot, idioms, options = {}) {
|
|
|
86
86
|
}
|
|
87
87
|
return createHash('sha1').update(parts.join('\n')).digest('hex').slice(0, 16);
|
|
88
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* The set of tokens the given file entries PROVIDE under any idiom. Used to diff
|
|
91
|
+
* a base-ref snapshot against the worktree: a REMOVED provider leaves NO site in
|
|
92
|
+
* the changed file (so post-change site-scoping can't see it), but the base
|
|
93
|
+
* content still shows the token was provided there — so a provider deletion
|
|
94
|
+
* (the most common way DI wiring silently breaks) stays change-attributable.
|
|
95
|
+
*/
|
|
96
|
+
export function providedTokensFromEntries(idioms, entries) {
|
|
97
|
+
const tokens = new Set();
|
|
98
|
+
for (const idiom of idioms) {
|
|
99
|
+
const files = entries.filter((f) => matchesAny(f.path, idiom.provided.files));
|
|
100
|
+
for (const s of collectSourceSites(idiom.provided, files).sites)
|
|
101
|
+
tokens.add(s.token);
|
|
102
|
+
}
|
|
103
|
+
return tokens;
|
|
104
|
+
}
|
|
89
105
|
/**
|
|
90
106
|
* `wiring chain <token>` — the declared → provided → consumed hops of one token
|
|
91
107
|
* with file:line at each, or `undefined` if the token is unknown to the graph.
|
|
@@ -101,24 +117,57 @@ export function registrationChain(graph, token) {
|
|
|
101
117
|
isConsumed: node.consumed.length > 0,
|
|
102
118
|
};
|
|
103
119
|
}
|
|
120
|
+
/** Project-relative path normalizer so site files and git changed-files compare. */
|
|
121
|
+
function normalizeRel(p) {
|
|
122
|
+
return p.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
123
|
+
}
|
|
124
|
+
/** True when ANY of `sites` falls in the changed-file scope. */
|
|
125
|
+
function anySiteInScope(sites, scope) {
|
|
126
|
+
return sites.some((s) => scope.has(normalizeRel(s.file)));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Does the changed-file set touch ANY role-site of ANY token in the graph? Lets
|
|
130
|
+
* a changed-only gate tell "evaluated the registration scope, found it clean"
|
|
131
|
+
* (a real pass) apart from "the change touched no wiring at all" (nothing to
|
|
132
|
+
* verify → the caller should skip, never paint green). An empty `changedFiles`
|
|
133
|
+
* is vacuously false.
|
|
134
|
+
*/
|
|
135
|
+
export function registrationTouchesChanged(graph, changedFiles) {
|
|
136
|
+
if (changedFiles.length === 0)
|
|
137
|
+
return false;
|
|
138
|
+
const scope = new Set(changedFiles.map(normalizeRel));
|
|
139
|
+
return graph.tokens.some((t) => anySiteInScope([...t.declared, ...t.provided, ...t.consumed], scope));
|
|
140
|
+
}
|
|
104
141
|
/**
|
|
105
142
|
* `wiring unprovided` — tokens that are DECLARED or CONSUMED but have ZERO
|
|
106
143
|
* provided sites. This is the silent-at-runtime class: typecheck/AOT-green, but
|
|
107
144
|
* the provider is never registered (or the injected token has no provider
|
|
108
145
|
* anywhere), so it resolves to undefined at runtime. The thing imports can't see.
|
|
146
|
+
*
|
|
147
|
+
* When `changedFiles` is supplied the result is CHANGESET-SCOPED: a token is
|
|
148
|
+
* kept only if one of its declared/consumed sites is in the changed set — i.e.
|
|
149
|
+
* "did THIS change leave a token unprovided", the change-attributed question a
|
|
150
|
+
* `wiring unprovided --changed-only` gate needs.
|
|
109
151
|
*/
|
|
110
|
-
export function registrationUnprovided(graph) {
|
|
152
|
+
export function registrationUnprovided(graph, changedFiles) {
|
|
153
|
+
const scope = changedFiles ? new Set(changedFiles.map(normalizeRel)) : undefined;
|
|
111
154
|
return graph.tokens
|
|
112
155
|
.filter((t) => t.provided.length === 0 && (t.declared.length > 0 || t.consumed.length > 0))
|
|
156
|
+
.filter((t) => !scope || anySiteInScope([...t.declared, ...t.consumed], scope))
|
|
113
157
|
.map((t) => ({ token: t.token, declared: t.declared, consumed: t.consumed }));
|
|
114
158
|
}
|
|
115
159
|
/**
|
|
116
160
|
* `wiring orphans` — tokens that ARE provided/registered but have ZERO consumed
|
|
117
161
|
* sites: a provider/registration nothing injects (a build-clean no-op, or a
|
|
118
162
|
* sign the consumer was renamed/removed).
|
|
163
|
+
*
|
|
164
|
+
* `changedFiles`, when supplied, scopes the result to orphans whose provided
|
|
165
|
+
* site is in the changed set (the registration THIS change added/touched).
|
|
119
166
|
*/
|
|
120
|
-
export function registrationOrphans(graph) {
|
|
167
|
+
export function registrationOrphans(graph, changedFiles) {
|
|
168
|
+
const scope = changedFiles ? new Set(changedFiles.map(normalizeRel)) : undefined;
|
|
121
169
|
return graph.tokens
|
|
122
170
|
.filter((t) => t.provided.length > 0 && t.consumed.length === 0)
|
|
171
|
+
.filter((t) => !scope || anySiteInScope(t.provided, scope))
|
|
123
172
|
.map((t) => ({ token: t.token, provided: t.provided }));
|
|
124
173
|
}
|
|
@@ -7,12 +7,18 @@ export declare const TRACE_DEFAULT_GLOBS: readonly string[];
|
|
|
7
7
|
* - `declare` — a canonical definition (`const X = 'lit'`, `kind: 'lit'`, an enum value).
|
|
8
8
|
* - `register` — added to a collection / mapping (`register('lit')`, an array element, `{ 'lit': … }`).
|
|
9
9
|
* - `consume` — compared / switched / handled (`=== 'lit'`, `case 'lit':`).
|
|
10
|
+
* - `render` — rendered / emitted at the boundary (JSX child `>{ 'lit' }`, template
|
|
11
|
+
* interpolation `${ 'lit' }`, a `render('lit')` / `res.send('lit')` call).
|
|
10
12
|
* - `reference`— an occurrence we can't confidently classify (still reported, with context).
|
|
13
|
+
*
|
|
14
|
+
* `render` only ever refines what would otherwise be a `reference`; it never
|
|
15
|
+
* steals a site from `declare` / `register` / `consume`.
|
|
11
16
|
*/
|
|
12
17
|
export declare enum TraceRole {
|
|
13
18
|
Declare = "declare",
|
|
14
19
|
Register = "register",
|
|
15
20
|
Consume = "consume",
|
|
21
|
+
Render = "render",
|
|
16
22
|
Reference = "reference"
|
|
17
23
|
}
|
|
18
24
|
/** One occurrence of the traced literal (or a const aliased to it). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trace-literal.d.ts","sourceRoot":"","sources":["../../src/wiring/trace-literal.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,EAAG,qBAA8B,CAAC;AAE3D,sEAAsE;AACtE,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAShD,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"trace-literal.d.ts","sourceRoot":"","sources":["../../src/wiring/trace-literal.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,EAAG,qBAA8B,CAAC;AAE3D,sEAAsE;AACtE,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAShD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,oBAAY,SAAS;IACnB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,SAAS,cAAc;CACxB;AAED,uEAAuE;AACvE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uFAAuF;IACvF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,OAAO,YAAY,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AA6ED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAuFd"}
|
|
@@ -17,13 +17,19 @@ export const TRACE_DEFAULT_GLOBS = [
|
|
|
17
17
|
* - `declare` — a canonical definition (`const X = 'lit'`, `kind: 'lit'`, an enum value).
|
|
18
18
|
* - `register` — added to a collection / mapping (`register('lit')`, an array element, `{ 'lit': … }`).
|
|
19
19
|
* - `consume` — compared / switched / handled (`=== 'lit'`, `case 'lit':`).
|
|
20
|
+
* - `render` — rendered / emitted at the boundary (JSX child `>{ 'lit' }`, template
|
|
21
|
+
* interpolation `${ 'lit' }`, a `render('lit')` / `res.send('lit')` call).
|
|
20
22
|
* - `reference`— an occurrence we can't confidently classify (still reported, with context).
|
|
23
|
+
*
|
|
24
|
+
* `render` only ever refines what would otherwise be a `reference`; it never
|
|
25
|
+
* steals a site from `declare` / `register` / `consume`.
|
|
21
26
|
*/
|
|
22
27
|
export var TraceRole;
|
|
23
28
|
(function (TraceRole) {
|
|
24
29
|
TraceRole["Declare"] = "declare";
|
|
25
30
|
TraceRole["Register"] = "register";
|
|
26
31
|
TraceRole["Consume"] = "consume";
|
|
32
|
+
TraceRole["Render"] = "render";
|
|
27
33
|
TraceRole["Reference"] = "reference";
|
|
28
34
|
})(TraceRole || (TraceRole = {}));
|
|
29
35
|
function escapeRegex(s) {
|
|
@@ -89,6 +95,20 @@ function classifyRole(before, after) {
|
|
|
89
95
|
if (/\b(kind|type|id|name|slug|key|tag|code|token|permission|route|event|action|channel|topic|status|provide|providerToken)\s*[:=]$/i.test(b)) {
|
|
90
96
|
return TraceRole.Declare;
|
|
91
97
|
}
|
|
98
|
+
// Render/handle site — REACHED ONLY after every higher-precision rule above
|
|
99
|
+
// has declined, so this can only refine an occurrence that would otherwise be
|
|
100
|
+
// `reference`; it never steals from declare/register/consume:
|
|
101
|
+
// - JSX child interpolation: `<tag>{ 'lit' }` (before ends `>{`).
|
|
102
|
+
// - template-literal interpolation: `` `${ 'lit' }` `` (before ends `${`).
|
|
103
|
+
// - a render / send-to-client call: `render('lit')`, `res.render('lit')`, `res.send('lit')`.
|
|
104
|
+
if (/>\s*\{$/.test(b))
|
|
105
|
+
return TraceRole.Render;
|
|
106
|
+
if (/\$\{$/.test(b))
|
|
107
|
+
return TraceRole.Render;
|
|
108
|
+
if (/\brender\w*\s*\($/i.test(b))
|
|
109
|
+
return TraceRole.Render;
|
|
110
|
+
if (/\bsend\w*\s*\($/i.test(b))
|
|
111
|
+
return TraceRole.Render;
|
|
92
112
|
return TraceRole.Reference;
|
|
93
113
|
}
|
|
94
114
|
/** A const name is alias-resolvable only if Pascal/SCREAMING-cased (low collision risk). */
|
|
@@ -167,6 +187,7 @@ export function traceLiteral(projectRoot, literal, options = {}) {
|
|
|
167
187
|
[TraceRole.Declare]: [],
|
|
168
188
|
[TraceRole.Register]: [],
|
|
169
189
|
[TraceRole.Consume]: [],
|
|
190
|
+
[TraceRole.Render]: [],
|
|
170
191
|
[TraceRole.Reference]: [],
|
|
171
192
|
};
|
|
172
193
|
for (const s of sites)
|
|
@@ -180,6 +201,7 @@ export function traceLiteral(projectRoot, literal, options = {}) {
|
|
|
180
201
|
[TraceRole.Declare]: sortSites(byRole[TraceRole.Declare]),
|
|
181
202
|
[TraceRole.Register]: sortSites(byRole[TraceRole.Register]),
|
|
182
203
|
[TraceRole.Consume]: sortSites(byRole[TraceRole.Consume]),
|
|
204
|
+
[TraceRole.Render]: sortSites(byRole[TraceRole.Render]),
|
|
183
205
|
[TraceRole.Reference]: sortSites(byRole[TraceRole.Reference]),
|
|
184
206
|
},
|
|
185
207
|
aliases: [...aliasNames].sort(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shrkcrft/boundaries",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.27",
|
|
4
4
|
"description": "SharkCraft boundary rules: detect when a repository violates its own architecture (forbidden imports across folder/package/layer boundaries).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SharkCraft contributors",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@shrkcrft/core": "^0.1.0-alpha.
|
|
46
|
+
"@shrkcrft/core": "^0.1.0-alpha.27"
|
|
47
47
|
},
|
|
48
48
|
"publishConfig": {
|
|
49
49
|
"access": "public"
|