eslint-plugin-use-agnostic 0.9.0 → 0.9.2

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/README.md CHANGED
@@ -85,9 +85,9 @@ Only the first line of code in a file is observed for the presence of a directiv
85
85
 
86
86
  Aliased import paths are resolved only if your ESLint config file and your `tsconfig.json` file are in the same directory. (At least to my knowledge.)
87
87
 
88
- It is up to you to confirm that your Agnostic Modules are indeed agnostic, meaning that they do not have neither server- nor client-side code. `eslint-plugin-use-agnostic`, at least at this time, does not do this verification for you.
88
+ It is up to you to confirm that your Agnostic Modules are indeed agnostic, meaning that they have neither server- nor client-side code. `eslint-plugin-use-agnostic`, at least at this time, does not do this verification for you.
89
89
 
90
- It is also up to you to ensure, as outlined above, that **you do not mix** exporting React components with exporting other logics within the same module. Separating exporting React components from their own modules ending with a JSX extension, from other logics from modules that don't end with a JSX extension, is crucial for distinguishing between Logics Modules and Components Modules.
90
+ It is also up to you to ensure, as outlined above, that **you do not mix** exporting React components with exporting other logics within the same module. Separating exporting React components within their own modules ending with a JSX extension, from exporting other logics within modules that don't end with a JSX extension, is crucial for distinguishing between Logics Modules and Components Modules.
91
91
 
92
92
  The import rules are designed to be as permissive as possible, allowing for more obscure use cases as long as they are non-breaking. However, it is still your responsibility as a developer to, within a file, not mix in incompatible ways code that cannot compose.
93
93
 
@@ -95,13 +95,13 @@ The import rules are designed to be as permissive as possible, allowing for more
95
95
 
96
96
  I believe the core issue hindering the comprehension of React Server Components is the fact that the Fullstack React Architecture has entirely erased its own roots since the introduction of directives by disregarding the architecture's primordial realities I have detailed above: its Modules. Server Modules. Client Modules. Agnostic Modules.
97
97
 
98
- 'use client' may denote to the server that a module's exports are to be imported as client references. But then that effectively makes it a "'use client' module", and it's only natural that a "'use client' module" would behave in a 'use client' way.
98
+ 'use client' may denote to the server that a module's exports are to be imported as client references. But that effectively makes said module a "'use client' module", and it's only natural that a "'use client' module" would behave in a 'use client' way.
99
99
 
100
- 'use server' may denote to the client that a module's exports are to be imported as server references. But then that effectively makes it a "'use server' module", and it's only natural that a "'use server' module" would behave in a 'use server' way.
100
+ 'use server' may denote to the client that a module's exports are to be imported as server references. But that effectively makes said module a "'use server' module", and it's only natural that a "'use server' module" would behave in a 'use server' way.
101
101
 
102
102
  React can easily understand that a 'use client' module is, from a primordial standpoint, a Client Module. And it can also understand that a 'use server' module is a Server Module, albeit a special one.
103
103
 
104
- But not having a directive to distinguish between 1. non-special Server Modules that are never meant to be imported on the client, even as references; and 2. actual Agnostic Modules, the Shared Modules that are still here at the heart of this system and are able to run anywhere; that creates a confusion that is detrimental to every single stackholder in the RSC ecosystem:
104
+ But not having a directive to distinguish between 1. non-special Server Modules that are never meant to be imported on the client, even as references; and 2. actual Agnostic Modules, the Shared Modules that are still here at the heart of this system and are able to run anywhere; this creates a confusion that is detrimental to every single stackholder in the RSC ecosystem:
105
105
 
106
106
  - Developers are confused and have no idea what "Server" or "Client" means, since React doesn't make it crystal clear.
107
107
  - LLMs are confused, because even they can't understand what 'use server' and 'use client' mean and therefore cannot explain it to developers facing their own specific concerns.
@@ -109,4 +109,4 @@ But not having a directive to distinguish between 1. non-special Server Modules
109
109
 
110
110
  This is what the 'use agnostic' directive solves. It clearly marks a module to be an Agnostic Module. And if a module that used to lack a directive can now be marked as an Agnostic Module, this allows modules without a directive to finally, truly be Server Modules by default. And eslint-plugin-use-agnostic can work from there.
111
111
 
112
- A lot more work needs to be done, and a lot of it unfortunately can only be optimized deeper into React's innerworkings. But if the introduction of 'use agnostic' can already create such powerful static analysis, imagine what it could produce if only it were incorporated into React as an official directive of the Fullstack React Architecture.
112
+ A lot more needs to be done, and a lot of it unfortunately can only be optimized deeper into React's innerworkings. But if the introduction of 'use agnostic' can already create such powerful static analysis, imagine what it could produce if only it were incorporated into React as an official directive of the Fullstack React Architecture.
@@ -1,7 +1,7 @@
1
1
  /* plugin names */
2
2
  // use-agnostic
3
3
  export const useAgnosticPluginName = "use-agnostic";
4
- // crossingStrategies
4
+ // crossingStrategies (canceled)
5
5
  export const strategiesPluginName = "strategies";
6
6
 
7
7
  /* config names */
@@ -18,7 +18,7 @@ export const enforceEffectiveDirectivesRuleName =
18
18
  export const enforceCommentedDirectivesRuleName =
19
19
  "enforce-commented-directives-import-rules";
20
20
 
21
- // crossingStrategies
21
+ // crossingStrategies (canceled)
22
22
  export const verifySpecifierImportRuleName =
23
23
  "verify-specifier-import-export-same-strategy";
24
24
  export const verifyDefaultImportRuleName =
@@ -44,6 +44,8 @@ export const exportNotStrategized =
44
44
  "export-from-use-agnostic-strategies-not-strategized";
45
45
 
46
46
  // all "resolved" directives (from AIA/agnostic20 & DFA/directive21)
47
+ // - AIA: Agnostic-Included Architecture (agnostic20)
48
+ // - DFA: Directive-First Architecture (directive21)
47
49
  export const USE_SERVER_LOGICS = "use server logics";
48
50
  export const USE_CLIENT_LOGICS = "use client logics";
49
51
  export const USE_AGNOSTIC_LOGICS = "use agnostic logics";
@@ -97,6 +97,18 @@ export const getImportedFileFirstLine = (resolvedImportPath) => {
97
97
  return importedFileFirstLine;
98
98
  };
99
99
 
100
+ /* highlightFirstLineOfCode */
101
+
102
+ /**
103
+ * Gets the coordinates for the first line of code of a file.
104
+ * @param {import('@typescript-eslint/utils').TSESLint.RuleContext} context An ESLint rule's `context` object.
105
+ * @returns The `context.report` `loc`-compatible coordinates for the first line of code of a file.
106
+ */
107
+ export const highlightFirstLineOfCode = (context) => ({
108
+ start: { line: 1, column: 0 },
109
+ end: { line: 1, column: context.sourceCode.lines[0].length },
110
+ });
111
+
100
112
  /* isImportBlocked */
101
113
 
102
114
  /**
@@ -110,7 +122,7 @@ export const isImportBlocked = (
110
122
  // Note: "Blocked" here is preferred over "not allowed" because a specific message will be shared for each of the blocked situations, explaining their reasons and the solutions needed.
111
123
  resolvedDirectives_blockedImports,
112
124
  currentFileResolvedDirective,
113
- importedFileResolvedDirective,
125
+ importedFileResolvedDirective
114
126
  ) =>
115
127
  resolvedDirectives_blockedImports[currentFileResolvedDirective]
116
128
  .map((e) => e.blockedImport)
@@ -123,12 +135,12 @@ export const isImportBlocked = (
123
135
  * @param {Readonly<{"use server logics": SERVER_LOGICS_MODULE; "use client logics": CLIENT_LOGICS_MODULE; "use agnostic logics": AGNOSTIC_LOGICS_MODULE; "use server components": SERVER_COMPONENTS_MODULE; "use client components": CLIENT_COMPONENTS_MODULE; "use agnostic components": AGNOSTIC_COMPONENTS_MODULE; "use server functions": SERVER_FUNCTIONS_MODULE; "use client contexts": CLIENT_CONTEXTS_MODULE; "use agnostic conditions": AGNOSTIC_CONDITIONS_MODULE; "use agnostic strategies": AGNOSTIC_STRATEGIES_MODULE;}>} resolvedDirectives_ResolvedModules The resolved modules object, either for agnostic20 or for directive21.
124
136
  * @param {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS | USE_AGNOSTIC_STRATEGIES} currentFileResolvedDirective The current file's "resolved" directive.
125
137
  * @param {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS} importedFileResolvedDirective The imported file's "resolved" directive.
126
- * @returns {string} Returns "[Current file 'resolved' modules] are not allowed to import [imported file 'resolved' modules]".
138
+ * @returns {string} Returns "[Current file 'resolved' modules] are not allowed to import [imported file 'resolved' modules]."
127
139
  */
128
140
  export const makeIntroForSpecificViolationMessage = (
129
141
  resolvedDirectives_ResolvedModules,
130
142
  currentFileResolvedDirective,
131
- importedFileResolvedDirective,
143
+ importedFileResolvedDirective
132
144
  ) =>
133
145
  `${resolvedDirectives_ResolvedModules[currentFileResolvedDirective]}s ${ARE_NOT_ALLOWED_TO_IMPORT} ${resolvedDirectives_ResolvedModules[importedFileResolvedDirective]}s.`;
134
146
 
@@ -144,14 +156,14 @@ export const makeIntroForSpecificViolationMessage = (
144
156
  export const makeMessageFromResolvedDirective = (
145
157
  resolvedDirectives_ResolvedModules,
146
158
  resolvedDirectives_blockedImports,
147
- resolvedDirective,
159
+ resolvedDirective
148
160
  ) => {
149
161
  const effectiveModule = resolvedDirectives_ResolvedModules[resolvedDirective];
150
162
  const effectiveModulesString = effectiveModule + "s"; // plural
151
163
 
152
164
  const blockedImports =
153
165
  resolvedDirectives_blockedImports[resolvedDirective].map(
154
- (e) => e.blockedImport,
166
+ (e) => e.blockedImport
155
167
  ) || [];
156
168
 
157
169
  if (blockedImports.length === 0) {
@@ -159,7 +171,7 @@ export const makeMessageFromResolvedDirective = (
159
171
  }
160
172
 
161
173
  const blockedEffectiveModules = blockedImports.map(
162
- (e) => resolvedDirectives_ResolvedModules[e] + "s", // plural
174
+ (e) => resolvedDirectives_ResolvedModules[e] + "s" // plural
163
175
  );
164
176
 
165
177
  const blockedEffectiveModulesString =
@@ -184,8 +196,8 @@ export const makeMessageFromResolvedDirective = (
184
196
  export const findSpecificViolationMessage = (
185
197
  resolvedDirectives_blockedImports,
186
198
  currentFileResolvedDirective,
187
- importedFileResolvedDirective,
199
+ importedFileResolvedDirective
188
200
  ) =>
189
201
  resolvedDirectives_blockedImports[currentFileResolvedDirective].find(
190
- (e) => e.blockedImport === importedFileResolvedDirective,
202
+ (e) => e.blockedImport === importedFileResolvedDirective
191
203
  ).message;
@@ -65,6 +65,7 @@ export const directivesSet = new Set([USE_SERVER, USE_CLIENT, USE_AGNOSTIC]);
65
65
 
66
66
  /* from the getDirectiveFromImportedModule utility */
67
67
 
68
+ /** @type {readonly [USE_SERVER, USE_CLIENT, USE_AGNOSTIC]} */
68
69
  export const directivesArray = Array.from(directivesSet);
69
70
 
70
71
  /* from the isImportBlocked utility */
@@ -75,7 +76,7 @@ export const directivesArray = Array.from(directivesSet);
75
76
  * Makes the intro for each specific import rule violation messages.
76
77
  * @param {USE_SERVER_LOGICS | USE_SERVER_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_LOGICS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_LOGICS | USE_AGNOSTIC_COMPONENTS} currentFileEffectiveDirective The current file's effective directive.
77
78
  * @param {USE_SERVER_LOGICS | USE_SERVER_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_LOGICS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_LOGICS | USE_AGNOSTIC_COMPONENTS} importedFileEffectiveDirective The imported file's effective directive.
78
- * @returns {string} Returns "[Current file effective modules] are not allowed to import [imported file effective modules]".
79
+ * @returns {string} Returns "[Current file effective modules] are not allowed to import [imported file effective modules]."
79
80
  */
80
81
  const makeIntroForSpecificViolationMessage = (
81
82
  currentFileEffectiveDirective,
@@ -94,13 +95,13 @@ export const effectiveDirectives_BlockedImports = Object.freeze({
94
95
  [USE_SERVER_LOGICS]: [
95
96
  // USE_SERVER_LOGICS allowed, because Server Logics can compose with one another.
96
97
  // USE_SERVER_COMPONENTS allowed, because Server Components are OK to be composed with Server Logics as long as the Server Logics Module, by convention, does not export React components.
97
- // USE_SERVER_FUNCTIONS allowed, because as Server Functions can import one another, it is only natural that they could compose through Server Logics.
98
+ // USE_SERVER_FUNCTIONS allowed, because Server Functions, being able to import one another, can compose and do so via Server Logics, despite this method seeming superfluous at first glance. (Perhaps a preferrable use case for this has been found or could be found either today or in the future.)
98
99
  {
99
100
  blockedImport: USE_CLIENT_LOGICS,
100
101
  message: `${makeIntroForSpecificViolationMessage(
101
102
  USE_SERVER_LOGICS,
102
103
  USE_CLIENT_LOGICS
103
- )} Client logic should never leak to the server.`,
104
+ )} Client Logics should never leak to the server.`,
104
105
  },
105
106
  {
106
107
  blockedImport: USE_CLIENT_COMPONENTS,
@@ -109,55 +110,55 @@ export const effectiveDirectives_BlockedImports = Object.freeze({
109
110
  USE_CLIENT_COMPONENTS
110
111
  )} Client Components cannot be tinkered with on the server.`,
111
112
  },
112
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the server just like it can on the client.
113
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the server just like they can on the client, again, as long at the Server Logics Module, by convention, does not export React components.
113
+ // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics can run safely on the server just like they can on the client.
114
+ // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the server just like they can on the client, as long at the Server Logics Module, by convention, does not export React components.
114
115
  ],
115
116
  [USE_SERVER_COMPONENTS]: [
116
- // USE_SERVER_LOGICS allowed, because logic from the server can safely support Server Components.
117
+ // USE_SERVER_LOGICS allowed, because Server Logics, being logic from the server, can safely support Server Components.
117
118
  // USE_SERVER_COMPONENTS allowed, because Server Components can compose with one another, assuming thanks to the inclusion of the 'use agnostic' directive that they are actual Server Components.
118
- // USE_SERVER_FUNCTIONS allowed, because as Server Components Modules can import Client Components, they are able to pass them Server Functions as props as well, even though indeed Server Components Modules can make their own Server Functions through inline 'use server' directives.
119
+ // USE_SERVER_FUNCTIONS allowed, because Server Functions can be passed to imported Client Components within Server Components Modules, even though indeed Server Components Modules and Server Components can make their own Server Functions through inline 'use server' directives.
119
120
  {
120
121
  blockedImport: USE_CLIENT_LOGICS,
121
122
  message: `${makeIntroForSpecificViolationMessage(
122
123
  USE_SERVER_COMPONENTS,
123
124
  USE_CLIENT_LOGICS
124
- )} Client logic should never leak to the server.`,
125
+ )} Client Logics should never leak to the server.`,
125
126
  },
126
127
  // USE_CLIENT_COMPONENTS allowed, because Client Components can be nested inside Server Components either to wrap some of the tree with client state accessible through child Client Components and pass through Server Components, or to create client boundaries when the root of the application is planted on the server.
127
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the server just like it can on the client.
128
+ // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics can run safely on the server just like they can on the client.
128
129
  // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can render safely on the server just like they can on the client.
129
130
  ],
130
131
  [USE_SERVER_FUNCTIONS]: [
131
- // USE_SERVER_LOGICS allowed, because logic from the server can safely support Server Functions.
132
+ // USE_SERVER_LOGICS allowed, because Server Logics, being logic from the server, can safely support Server Functions.
132
133
  {
133
134
  blockedImport: USE_SERVER_COMPONENTS,
134
135
  message: `${makeIntroForSpecificViolationMessage(
135
136
  USE_SERVER_FUNCTIONS,
136
137
  USE_SERVER_COMPONENTS
137
- )} Server Functions have no business working with React Components.`,
138
+ )} Server Components aren't allowed because Server Functions have no business working with React Components.`,
138
139
  },
139
- // USE_SERVER_FUNCTIONS allowed, because even though Server Functions don't need to import one another and the same results can be generated via Server Logic alone for the outcome of a single Server Function, a rational use case could be found for composing Server Functions with one another either today or in the future.
140
+ // USE_SERVER_FUNCTIONS allowed, because Server Functions, even though they don't need to import one another and the same results can be generated via Server Logics for the outcome of a single Server Function, can still compose with one another. (Perhaps a preferrable use case for this has been found or could be found either today or in the future.)
140
141
  {
141
142
  blockedImport: USE_CLIENT_LOGICS,
142
143
  message: `${makeIntroForSpecificViolationMessage(
143
144
  USE_SERVER_FUNCTIONS,
144
145
  USE_CLIENT_LOGICS
145
- )} Client logic should never leak to the server.`,
146
+ )} Client Logics should never leak to the server.`,
146
147
  },
147
148
  {
148
149
  blockedImport: USE_CLIENT_COMPONENTS,
149
150
  message: `${makeIntroForSpecificViolationMessage(
150
151
  USE_SERVER_FUNCTIONS,
151
152
  USE_CLIENT_COMPONENTS
152
- )} Server Functions have no business working with React Components.`,
153
+ )} Client Components aren't allowed because Server Functions have no business working with React Components.`,
153
154
  },
154
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the server just like it can on the client.
155
+ // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics can run safely on the server just like they can on the client.
155
156
  {
156
157
  blockedImport: USE_AGNOSTIC_COMPONENTS,
157
158
  message: `${makeIntroForSpecificViolationMessage(
158
159
  USE_SERVER_FUNCTIONS,
159
160
  USE_AGNOSTIC_COMPONENTS
160
- )} Server Functions have no business working with React Components.`,
161
+ )} Agnostic Components aren't allowed because Server Functions have no business working with React Components.`,
161
162
  },
162
163
  ],
163
164
  [USE_CLIENT_LOGICS]: [
@@ -166,7 +167,7 @@ export const effectiveDirectives_BlockedImports = Object.freeze({
166
167
  message: `${makeIntroForSpecificViolationMessage(
167
168
  USE_CLIENT_LOGICS,
168
169
  USE_SERVER_LOGICS
169
- )} Server logic should never leak to the client.
170
+ )} Server Logics should never leak to the client.
170
171
  ${SUGGEST_USE_AGNOSTIC}`,
171
172
  },
172
173
  {
@@ -177,11 +178,11 @@ ${SUGGEST_USE_AGNOSTIC}`,
177
178
  )} Server Components cannot be thinkered with on the client.
178
179
  ${SUGGEST_USE_AGNOSTIC}`,
179
180
  },
180
- // USE_SERVER_FUNCTIONS allowed, because it is technically feasible to tinker with a Client Component within a Client Logics Module and attach to said Client Component a Server Function to be triggered on the client.
181
+ // USE_SERVER_FUNCTIONS allowed, because Server Functions can technically be attached to Client Components that are being tinkered with within Client Logics Modules.
181
182
  // USE_CLIENT_LOGICS allowed, because Client Logics can compose with one another.
182
183
  // USE_CLIENT_COMPONENTS allowed, because Client Components are OK to be composed with Client Logics as long as the Client Logics Module, by convention, does not export React components.
183
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the client just like it can on the server.
184
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the client just like they can on the server, again, as long at the Client Logics Module, by convention, does not export React components.
184
+ // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics can run safely on the client just like they can on the server.
185
+ // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the client just like they can on the server, as long as the Client Logics Module, by convention, does not export React components.
185
186
  ],
186
187
  [USE_CLIENT_COMPONENTS]: [
187
188
  {
@@ -189,7 +190,7 @@ ${SUGGEST_USE_AGNOSTIC}`,
189
190
  message: `${makeIntroForSpecificViolationMessage(
190
191
  USE_CLIENT_COMPONENTS,
191
192
  USE_SERVER_LOGICS
192
- )} Server logic should never leak to the client.
193
+ )} Server Logics should never leak to the client.
193
194
  ${SUGGEST_USE_AGNOSTIC}`,
194
195
  },
195
196
  {
@@ -197,13 +198,13 @@ ${SUGGEST_USE_AGNOSTIC}`,
197
198
  message: `${makeIntroForSpecificViolationMessage(
198
199
  USE_CLIENT_COMPONENTS,
199
200
  USE_SERVER_COMPONENTS
200
- )} Server Components may only pass through Client Components through the children prop within Server Components Modules.
201
+ )} Server Components may only pass through Client Components via the children prop within Server Components Modules.
201
202
  ${SUGGEST_USE_AGNOSTIC}`,
202
203
  },
203
204
  // USE_SERVER_FUNCTIONS allowed, because Server Functions are specifically triggered by Client Components.
204
- // USE_CLIENT_LOGICS allowed, because logic from the client can safely support Client Components.
205
+ // USE_CLIENT_LOGICS allowed, because Client Logics, being logic from the client, can safely support Client Components.
205
206
  // USE_CLIENT_COMPONENTS allowed, because Client Components can compose with one another.
206
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the client just like it can on the server.
207
+ // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics can run safely on the client just like they can on the server.
207
208
  // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can render safely on the client just like they can on the server.
208
209
  ],
209
210
  [USE_AGNOSTIC_LOGICS]: [
@@ -212,7 +213,7 @@ ${SUGGEST_USE_AGNOSTIC}`,
212
213
  message: `${makeIntroForSpecificViolationMessage(
213
214
  USE_AGNOSTIC_LOGICS,
214
215
  USE_SERVER_LOGICS
215
- )} Server Logic cannot run in both the server and the client.
216
+ )} Server Logics cannot run on both the server and the client.
216
217
  ${SUGGEST_USE_AGNOSTIC}`,
217
218
  },
218
219
  {
@@ -228,14 +229,14 @@ ${SUGGEST_USE_AGNOSTIC}`,
228
229
  message: `${makeIntroForSpecificViolationMessage(
229
230
  USE_AGNOSTIC_LOGICS,
230
231
  USE_SERVER_FUNCTIONS
231
- )} Though Server Functions can be tinkered with on the server and on the client, use cases on both environments are not compatible.`,
232
+ )} Server Functions can be modified on the server and on the client, but their use cases on both environments are not one-to-one compatible, since they're being addressed as they are on the server and addressed as references on the client.`,
232
233
  },
233
234
  {
234
235
  blockedImport: USE_CLIENT_LOGICS,
235
236
  message: `${makeIntroForSpecificViolationMessage(
236
237
  USE_AGNOSTIC_LOGICS,
237
238
  USE_CLIENT_LOGICS
238
- )} Client Logic cannot run in both the server and the client.`,
239
+ )} Client Logics cannot run on both the server and the client.`,
239
240
  },
240
241
  {
241
242
  blockedImport: USE_CLIENT_COMPONENTS,
@@ -253,7 +254,7 @@ ${SUGGEST_USE_AGNOSTIC}`,
253
254
  message: `${makeIntroForSpecificViolationMessage(
254
255
  USE_AGNOSTIC_COMPONENTS,
255
256
  USE_SERVER_LOGICS
256
- )} Server Logic cannot run in both the server and the client.
257
+ )} Server Logics cannot run on both the server and the client.
257
258
  ${SUGGEST_USE_AGNOSTIC}`,
258
259
  },
259
260
  {
@@ -261,19 +262,19 @@ ${SUGGEST_USE_AGNOSTIC}`,
261
262
  message: `${makeIntroForSpecificViolationMessage(
262
263
  USE_AGNOSTIC_COMPONENTS,
263
264
  USE_SERVER_COMPONENTS
264
- )} Unlike Client Components, Server Components cannot make silos of their own once on the client, and can therefore not be executed from the client.
265
+ )} Server Components, unlike Client Components, cannot make silos of their own once on the opposing environment (the client in this case), and therefore cannot be executed from the client, making them unable to execute agnostically from both the server and the client.
265
266
  ${SUGGEST_USE_AGNOSTIC}`,
266
267
  },
267
- // USE_SERVER_FUNCTIONS allowed, because as Agnostic Components Modules can import Client Components, they are able to pass them Server Functions as props as well.
268
+ // USE_SERVER_FUNCTIONS allowed, because Server Functions can be passed to Client Components as props when Client Components are also legally imported into Agnostic Components Modules.
268
269
  {
269
270
  blockedImport: USE_CLIENT_LOGICS,
270
271
  message: `${makeIntroForSpecificViolationMessage(
271
272
  USE_AGNOSTIC_COMPONENTS,
272
273
  USE_CLIENT_LOGICS
273
- )} Client Logic cannot run in both the server and the client.`,
274
+ )} Client Logics cannot run on both the server and the client.`,
274
275
  },
275
276
  // USE_CLIENT_COMPONENTS allowed, because Client Components can be nested inside Agnostic Components either to wrap some of the tree with client state accessible through child Client Components and pass through Server Components (if still on the Server Tree), or to create client boundaries when the root of the application is planted on the server.
276
- // USE_AGNOSTIC_LOGICS allowed, because environment-agnostic logic can safely support Agnostic Components.
277
+ // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics, being environment-agnostic logic, can safely support Agnostic Components.
277
278
  // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can compose with one another.
278
279
  ],
279
280
  });
@@ -20,7 +20,10 @@ import {
20
20
  specificViolationMessage,
21
21
  } from "../constants/bases.js";
22
22
 
23
- import { resolveImportPath } from "../../../_commons/utilities/helpers.js";
23
+ import {
24
+ resolveImportPath,
25
+ highlightFirstLineOfCode,
26
+ } from "../../../_commons/utilities/helpers.js";
24
27
  import {
25
28
  getDirectiveFromCurrentModule,
26
29
  getDirectiveFromImportedModule,
@@ -61,10 +64,7 @@ export const currentFileFlow = (context) => {
61
64
  currentFileExtension.endsWith("x")
62
65
  ) {
63
66
  context.report({
64
- loc: {
65
- start: { line: 1, column: 0 },
66
- end: { line: 1, column: context.sourceCode.lines[0].length },
67
- },
67
+ loc: highlightFirstLineOfCode(context),
68
68
  messageId: useServerJSXMessageId,
69
69
  });
70
70
  return { skip: true };
@@ -91,9 +91,6 @@ export const currentFileFlow = (context) => {
91
91
 
92
92
  /**
93
93
  * The flow that is shared between import and re-export traversals to obtain the import file's effective directive.
94
- * @param {string} currentDir Directory of the file containing the import (from `path.dirname(context.filename)`).
95
- * @param {string} importPath The import specifier (e.g., `@/components/Button` or `./utils`).
96
- * @param {string} cwd Project root (from `context.cwd`). Caveat: only as an assumption currently.
97
94
  * @param {Readonly<import('@typescript-eslint/utils').TSESLint.RuleContext<typeof reExportNotSameMessageId | typeof importBreaksEffectiveImportRulesMessageId | typeof useServerJSXMessageId, []>>} context The ESLint rule's `context` object.
98
95
  * @param {import('@typescript-eslint/types').TSESTree.ImportDeclaration} node The ESLint `node` of the rule's current traversal.
99
96
  * @returns {{skip: true; importedFileEffectiveDirective: undefined; resolvedImportPath: undefined;} | {skip: undefined; importedFileEffectiveDirective: USE_SERVER_LOGICS | USE_SERVER_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_LOGICS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_LOGICS | USE_AGNOSTIC_COMPONENTS; resolvedImportPath: string;}} Returns either an object with `skip: true` to disregard or one with the non-null `importedFileEffectiveDirective`.
@@ -202,9 +199,9 @@ export const reExportsFlow = (context, node, currentFileEffectiveDirective) => {
202
199
  node,
203
200
  messageId: reExportNotSameMessageId,
204
201
  data: {
205
- // currentFileEffectiveDirective
202
+ // currentFileEffectiveDirective:
206
203
  currentFileEffectiveDirective,
207
- // importedFileEffectiveDirective
204
+ // importedFileEffectiveDirective:
208
205
  importedFileEffectiveDirective,
209
206
  },
210
207
  });
@@ -9,6 +9,8 @@ import {
9
9
 
10
10
  /**
11
11
  * Makes the agnostic20 config for the use-agnostic ESLint plugin.
12
+ * @param {import('eslint').ESLint.Plugin} plugin The use-agnostic ESLint plugin itself.
13
+ * @returns The agnostic20 config's name as a key and its config as its value.
12
14
  */
13
15
  export const makeAgnostic20Config = (plugin) => ({
14
16
  [agnostic20ConfigName]: defineConfig([
@@ -86,27 +86,29 @@ export const directivesSet = new Set([
86
86
 
87
87
  /* from the getCommentedDirectiveFromImportedModule utility */
88
88
 
89
+ /** @type {readonly [USE_SERVER_LOGICS, USE_CLIENT_LOGICS, USE_AGNOSTIC_LOGICS, USE_SERVER_COMPONENTS, USE_CLIENT_COMPONENTS, USE_AGNOSTIC_COMPONENTS, USE_SERVER_FUNCTIONS, USE_CLIENT_CONTEXTS, USE_AGNOSTIC_CONDITIONS, USE_AGNOSTIC_STRATEGIES]} */
89
90
  export const directivesArray = Array.from(directivesSet);
90
91
 
91
92
  /* commentedDirectives_4RawImplementations */
92
93
 
93
- // make all four accepted commented directive implementations
94
- const makeRawCommentedDirectiveV1of4 = (directive) => `// '${directive}'`;
95
- const makeRawCommentedDirectiveV2of4 = (directive) => `// "${directive}"`;
96
- const makeRawCommentedDirectiveV3of4 = (directive) => `/* '${directive}' */`;
97
- const makeRawCommentedDirectiveV4of4 = (directive) => `/* "${directive}" */`;
94
+ // all formatting styles as an array of [prefix, quote, suffix]
95
+ const commentStyles = [
96
+ [`// `, `'`, ``], // V1: `// 'directive'`
97
+ [`// `, `"`, ``], // V2: `// "directive"`
98
+ [`/* `, `'`, ` */`], // V3: `/* 'directive' */`
99
+ [`/* `, `"`, ` */`], // V4: `/* "directive" */`
100
+ ];
98
101
 
99
102
  /**
100
103
  * Makes the array of all four accepted commented directive implementations on a directive basis.
101
- * @param {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS | USE_AGNOSTIC_STRATEGIES} directive
102
- * @returns
104
+ * @param {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS | USE_AGNOSTIC_STRATEGIES} directive The commented directive.
105
+ * @returns {string[]} The array of formatted commented directives.
103
106
  */
104
- const make4RawImplementations = (directive) => [
105
- makeRawCommentedDirectiveV1of4(directive),
106
- makeRawCommentedDirectiveV2of4(directive),
107
- makeRawCommentedDirectiveV3of4(directive),
108
- makeRawCommentedDirectiveV4of4(directive),
109
- ];
107
+ const make4RawImplementations = (directive) =>
108
+ commentStyles.map(
109
+ ([prefix, quote, suffix]) =>
110
+ `${prefix}${quote}${directive}${quote}${suffix}`
111
+ );
110
112
 
111
113
  // mapped commented directives to their 4 raw implementations
112
114
  export const commentedDirectives_4RawImplementations = Object.freeze({
@@ -152,7 +154,7 @@ export const commentedStrategies_CommentedDirectives = Object.freeze({
152
154
  * Makes the intro for each specific import rule violation messages.
153
155
  * @param {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS | USE_AGNOSTIC_STRATEGIES} currentFileCommentedDirective The current file's commented directive.
154
156
  * @param {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS} importedFileCommentedDirective The imported file's commented directive.
155
- * @returns {string} Returns "[Current file commented modules] are not allowed to import [imported file commented modules]".
157
+ * @returns {string} Returns "[Current file commented modules] are not allowed to import [imported file commented modules]."
156
158
  */
157
159
  const makeIntroForSpecificViolationMessage = (
158
160
  currentFileCommentedDirective,
@@ -166,33 +168,33 @@ const makeIntroForSpecificViolationMessage = (
166
168
 
167
169
  export const commentedDirectives_BlockedImports = Object.freeze({
168
170
  [USE_SERVER_LOGICS]: [
169
- // USE_SERVER_LOGICS allowed, because Server Logics can compose with one another.
171
+ // USE_SERVER_LOGICS allowed, because Prime Server Logics can compose with one another.
170
172
  {
171
173
  blockedImport: USE_CLIENT_LOGICS,
172
174
  message: `${makeIntroForSpecificViolationMessage(
173
175
  USE_SERVER_LOGICS,
174
176
  USE_CLIENT_LOGICS
175
- )} Client logic should never leak to the server.`,
177
+ )} Prime Client Logics should never leak to the server.`,
176
178
  },
177
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the server just like it can on the client.
178
- // USE_SERVER_COMPONENTS allowed, because Server Components are OK to be composed with Server Logics as long as the Server Logics Module, by convention, does not export React components.
179
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics can run safely on the server just like they can on the client.
180
+ // USE_SERVER_COMPONENTS allowed, because Lineal Server Components are OK to be composed with Prime Server Logics as long as the Prime Server Logics Module, by convention, does not export React components.
179
181
  {
180
182
  blockedImport: USE_CLIENT_COMPONENTS,
181
183
  message: `${makeIntroForSpecificViolationMessage(
182
184
  USE_SERVER_LOGICS,
183
185
  USE_CLIENT_COMPONENTS
184
- )} Client Components cannot be tinkered with on the server.`,
186
+ )} Lineal Client Components, like any Client Components, cannot be tinkered with on the server.`,
185
187
  },
186
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the server just like they can on the client, again, as long at the Server Logics Module, by convention, does not export React components.
187
- // USE_SERVER_FUNCTIONS allowed, because as Server Functions can import one another, it is only natural that they could compose through Server Logics.
188
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components can be composed with any Prime Environment Logics agnostically as long as the Prime Environment Logics Module, by convention, does not export React components.
189
+ // USE_SERVER_FUNCTIONS allowed, because (Special) Server Functions, being able to import one another, can compose and do so via Prime Server Logics, despite this method seeming superfluous at first glance. (Perhaps a preferrable use case for this has been found or could be found either today or in the future.)
188
190
  {
189
191
  blockedImport: USE_CLIENT_CONTEXTS,
190
192
  message: `${makeIntroForSpecificViolationMessage(
191
193
  USE_SERVER_LOGICS,
192
194
  USE_CLIENT_CONTEXTS
193
- )} Client Components cannot be tinkered with on the server, including Client Contexts Components.`,
195
+ )} (Special) Client Contexts Components, like any Client Components, cannot be tinkered with on the server.`,
194
196
  },
195
- // USE_AGNOSTIC_CONDITIONS allowed, because though it would make sense to import their own `ComponentForServer` instead, Agnostic Conditions Components are still able to safely render on the server, guaranteeing that only their `ComponentForServer` will be effectively involved in Server Logics Modules.
197
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components are able to safely render on the server, guaranteeing that only their `ComponentForServer` will be effectively involved in Prime Server Logics Modules.
196
198
  ],
197
199
  [USE_CLIENT_LOGICS]: [
198
200
  {
@@ -200,22 +202,22 @@ export const commentedDirectives_BlockedImports = Object.freeze({
200
202
  message: `${makeIntroForSpecificViolationMessage(
201
203
  USE_CLIENT_LOGICS,
202
204
  USE_SERVER_LOGICS
203
- )} Server logic should never leak to the client.`,
205
+ )} Prime Server Logics should never leak to the client.`,
204
206
  },
205
- // USE_CLIENT_LOGICS allowed, because Client Logics can compose with one another.
206
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the client just like it can on the server.
207
+ // USE_CLIENT_LOGICS allowed, because Prime Client Logics can compose with one another.
208
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics can run safely on the client just like they can on the server.
207
209
  {
208
210
  blockedImport: USE_SERVER_COMPONENTS,
209
211
  message: `${makeIntroForSpecificViolationMessage(
210
212
  USE_CLIENT_LOGICS,
211
213
  USE_SERVER_COMPONENTS
212
- )} Server Components cannot be thinkered with on the client.`,
214
+ )} Lineal Server Components cannot be thinkered with on the client.`,
213
215
  },
214
- // USE_CLIENT_COMPONENTS allowed, because Client Components are OK to be composed with Client Logics as long as the Client Logics Module, by convention, does not export React components.
215
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the client just like they can on the server, again, as long at the Client Logics Module, by convention, does not export React components.
216
- // USE_SERVER_FUNCTIONS allowed, because it is technically feasible to tinker with a Client Component within a Client Logics Module and attach to said Client Component a Server Function to be triggered on the client.
217
- // USE_CLIENT_CONTEXTS allowed, because Client Components are OK to be composed with Client Logics as long as the Client Logics Module, by convention, does not export React components, including Client Contexts Components.
218
- // USE_AGNOSTIC_CONDITIONS allowed, because though it would make sense to import their own `ComponentForClient` instead, Agnostic Conditions Components are still able to safely render on the client, guaranteeing that only their `ComponentForClient` will be effectively involved in Client Logics Modules.
216
+ // USE_CLIENT_COMPONENTS allowed, because Lineal Client Components, like any Client Components, are OK to be composed with Prime Client Logics as long as the Prime Client Logics Module, by convention, does not export React components.
217
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components can be composed with any Prime Environment Logics agnostically as long as the Prime Environment Logics Module, by convention, does not export React components.
218
+ // USE_SERVER_FUNCTIONS allowed, because (Special) Server Functions can technically be attached to Client Components that are being tinkered with within Client Logics Modules.
219
+ // USE_CLIENT_CONTEXTS allowed, because (Special) Client Contexts Components, like any Client Components, are OK to be composed with Prime Client Logics as long as the Prime Client Logics Module, by convention, does not export React components.
220
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components are able to safely render on the client, guaranteeing that only their `ComponentForClient` will be effectively involved in Prime Client Logics Modules.
219
221
  ],
220
222
  [USE_AGNOSTIC_LOGICS]: [
221
223
  {
@@ -223,63 +225,63 @@ export const commentedDirectives_BlockedImports = Object.freeze({
223
225
  message: `${makeIntroForSpecificViolationMessage(
224
226
  USE_AGNOSTIC_LOGICS,
225
227
  USE_SERVER_LOGICS
226
- )} Server Logic cannot run in both the server and the client.`,
228
+ )} Prime Server Logics cannot run on both the server and the client.`,
227
229
  },
228
230
  {
229
231
  blockedImport: USE_CLIENT_LOGICS,
230
232
  message: `${makeIntroForSpecificViolationMessage(
231
233
  USE_AGNOSTIC_LOGICS,
232
234
  USE_CLIENT_LOGICS
233
- )} Client Logic cannot run in both the server and the client.`,
235
+ )} Prime Client Logics cannot run on both the server and the client.`,
234
236
  },
235
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics can compose with one another.
237
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics can compose with one another.
236
238
  {
237
239
  blockedImport: USE_SERVER_COMPONENTS,
238
240
  message: `${makeIntroForSpecificViolationMessage(
239
241
  USE_AGNOSTIC_LOGICS,
240
242
  USE_SERVER_COMPONENTS
241
- )} Server Components cannot be tinkered with on both the server and the client.`,
243
+ )} Lineal Server Components cannot be tinkered with on both the server and the client.`,
242
244
  },
243
245
  {
244
246
  blockedImport: USE_CLIENT_COMPONENTS,
245
247
  message: `${makeIntroForSpecificViolationMessage(
246
248
  USE_AGNOSTIC_LOGICS,
247
249
  USE_CLIENT_COMPONENTS
248
- )} Client Components cannot be tinkered with on both the server and the client.`,
250
+ )} Lineal Client Components, like any Client Components, cannot be tinkered with on both the server and the client.`,
249
251
  },
250
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics agnostically as long as the Agnostic Logics Module, by convention, does not export React components.
252
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components can be composed with any Prime Environment Logics agnostically as long as the Prime Environment Logics Module, by convention, does not export React components.
251
253
  {
252
254
  blockedImport: USE_SERVER_FUNCTIONS,
253
255
  message: `${makeIntroForSpecificViolationMessage(
254
256
  USE_AGNOSTIC_LOGICS,
255
257
  USE_SERVER_FUNCTIONS
256
- )} Though Server Functions can be tinkered with on the server and on the client, use cases on both environments are not compatible.`,
258
+ )} (Special) Server Functions can be modified on the server and on the client, but their use cases on both environments are not one-to-one compatible, since they're being addressed as they are on the server and addressed as references on the client.`,
257
259
  },
258
260
  {
259
261
  blockedImport: USE_CLIENT_CONTEXTS,
260
262
  message: `${makeIntroForSpecificViolationMessage(
261
263
  USE_AGNOSTIC_LOGICS,
262
264
  USE_CLIENT_CONTEXTS
263
- )} Client Components cannot be tinkered with on both the server and the client, including Client Contexts Components.`,
265
+ )} (Special) Client Contexts Components, like any Client Components, cannot be tinkered with on both the server and the client.`,
264
266
  },
265
- // USE_AGNOSTIC_CONDITIONS allowed, because Agnostic Components can be composed with Logics agnostically as long as the Agnostic Logics Module, by convention, does not export React components, including Agnostic Conditions Components.
267
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components, as if they were Lineal Agnostic Components themselves, can be composed with any Prime Environment Logics agnostically as long as the Prime Environment Logics Module, by convention, does not export React components.
266
268
  ],
267
269
  [USE_SERVER_COMPONENTS]: [
268
- // USE_SERVER_LOGICS allowed, because logic from the server can safely support Server Components.
270
+ // USE_SERVER_LOGICS allowed, because Prime Server Logics, being logic from the server, can safely support Lineal Server Components.
269
271
  {
270
272
  blockedImport: USE_CLIENT_LOGICS,
271
273
  message: `${makeIntroForSpecificViolationMessage(
272
274
  USE_SERVER_COMPONENTS,
273
275
  USE_CLIENT_LOGICS
274
- )} Client logic should never leak to the server.`,
276
+ )} Prime Client Logics should never leak to the server.`,
275
277
  },
276
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the server just like it can on the client.
277
- // USE_SERVER_COMPONENTS allowed, because Server Components can compose with one another, now that thanks to the inclusion of Agnostic Components they are actual Server Components.
278
- // USE_CLIENT_COMPONENTS allowed, because Client Components (Lineal Client Components) can be nested inside Server Components to create client boundaries when the root of the application is planted on the server.
279
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can render safely on the server just like they can on the client.
280
- // USE_SERVER_FUNCTIONS allowed, because as Server Components Modules can import Client Components, they are able to pass them Server Functions as props as well, even though indeed Server Components Modules can make their own Server Functions through inline 'use server' directives.
281
- // USE_CLIENT_CONTEXTS allowed, because Client Components (Client Contexts Components) can be nested inside Server Components to wrap some of the tree with client state accessible through child Client Components and pass through Server Components when the root of the application is planted on the server.
282
- // USE_AGNOSTIC_CONDITIONS allowed, because Agnostic Components can render safely on the server just like they can on the client, including Agnostic Conditions Components.
278
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics can run safely on the server just like they can on the client.
279
+ // USE_SERVER_COMPONENTS allowed, because Lineal Server Components can compose with one another, now that thanks to the inclusion of Agnostic Components they are actual Server Components.
280
+ // USE_CLIENT_COMPONENTS allowed, because Lineal Client Components can be nested inside Server Components to create client boundaries when the root of the application is planted on the server.
281
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components can render safely on the server just like they can on the client.
282
+ // USE_SERVER_FUNCTIONS allowed, because (Special) Server Functions can be passed to imported Client Components within Lineal Server Components Modules, even though indeed Lineal Server Components Modules and Lineal Server Components can make their own Server Functions through inline 'use server' directives.
283
+ // USE_CLIENT_CONTEXTS allowed, because (Special) Client Contexts Components can be nested inside Server Components to wrap some of the tree with client state accessible through child Client Components, and to pass through Server Components when the root of the application is planted on the server.
284
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components, as if they were Lineal Agnostic Components themselves, can render safely on the server just like they can on the client.
283
285
  ],
284
286
  [USE_CLIENT_COMPONENTS]: [
285
287
  {
@@ -287,22 +289,22 @@ export const commentedDirectives_BlockedImports = Object.freeze({
287
289
  message: `${makeIntroForSpecificViolationMessage(
288
290
  USE_CLIENT_COMPONENTS,
289
291
  USE_SERVER_LOGICS
290
- )} Server logic should never leak to the client.`,
292
+ )} Prime Server Logics should never leak to the client.`,
291
293
  },
292
- // USE_CLIENT_LOGICS allowed, because logic from the client can safely support Client Components.
293
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the client just like it can on the server.
294
+ // USE_CLIENT_LOGICS allowed, because Prime Client Logics, being logic from the client, can safely support Lineal Client Components, like any Client Components.
295
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics can run safely on the client just like they can on the server.
294
296
  {
295
297
  blockedImport: USE_SERVER_COMPONENTS,
296
298
  message: `${makeIntroForSpecificViolationMessage(
297
299
  USE_CLIENT_COMPONENTS,
298
300
  USE_SERVER_COMPONENTS
299
- )} Server Components cannot be the children of Lineal Client Components.`,
301
+ )} Lineal Server Components cannot be the children of Lineal Client Components.`,
300
302
  },
301
- // USE_CLIENT_COMPONENTS allowed, because Client Components can compose with one another.
302
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can render safely on the client just like they can on the server.
303
- // USE_SERVER_FUNCTIONS allowed, because Server Functions are specifically triggered by Client Components.
304
- // USE_CLIENT_CONTEXTS allowed, because that mechanism allows Client Contexts Components to effectively become Lineal and only render their children on the client since they would be the grand-children of a grand-parent Lineal Client Component.
305
- // USE_AGNOSTIC_CONDITIONS allowed, because Agnostic Components can render safely on the client just like they can on the server, including Agnostic Conditions Components.
303
+ // USE_CLIENT_COMPONENTS allowed, because Lineal Client Components can compose with one another.
304
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components can render safely on the client just like they can on the server.
305
+ // USE_SERVER_FUNCTIONS allowed, because (Special) Server Functions are specifically triggered by Client Components.
306
+ // USE_CLIENT_CONTEXTS allowed, because (Special) Client Contexts Components can effectively become Lineal and only render their children on the client via this mechanism since, by a Client Contexts Component being the child of a Lineal Client Component, the Client Contexts Component's children become the grand-children of an ancestor Lineal Client Component, enforcing them to render exclusively on the client.
307
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components, as if they were Lineal Agnostic Components themselves, can render safely on the client just like they can on the server.
306
308
  ],
307
309
  [USE_AGNOSTIC_COMPONENTS]: [
308
310
  {
@@ -310,74 +312,74 @@ export const commentedDirectives_BlockedImports = Object.freeze({
310
312
  message: `${makeIntroForSpecificViolationMessage(
311
313
  USE_AGNOSTIC_COMPONENTS,
312
314
  USE_SERVER_LOGICS
313
- )} Server Logic cannot run in both the server and the client.`,
315
+ )} Prime Server Logics cannot run on both the server and the client.`,
314
316
  },
315
317
  {
316
318
  blockedImport: USE_CLIENT_LOGICS,
317
319
  message: `${makeIntroForSpecificViolationMessage(
318
320
  USE_AGNOSTIC_COMPONENTS,
319
321
  USE_CLIENT_LOGICS
320
- )} Client Logic cannot run in both the server and the client.`,
322
+ )} Prime Client Logics cannot run on both the server and the client.`,
321
323
  },
322
- // USE_AGNOSTIC_LOGICS allowed, because environment-agnostic logic can safely support Agnostic Components.
324
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics, being environment-agnostic logic, can safely support Agnostic Components.
323
325
  {
324
326
  blockedImport: USE_SERVER_COMPONENTS,
325
327
  message: `${makeIntroForSpecificViolationMessage(
326
328
  USE_AGNOSTIC_COMPONENTS,
327
329
  USE_SERVER_COMPONENTS
328
- )} Unlike Client Components, Server Components cannot make silos of their own once on the client, and can therefore not be executed from the client.`,
330
+ )} Lineal Server Components, unlike Lineal Client Components, cannot make silos of their own once on the opposing environment (the client in this case), and therefore cannot be executed from the client, making them unable to execute agnostically from both the server and the client.`,
329
331
  },
330
- // USE_CLIENT_COMPONENTS allowed, because Client Components (Lineal Client Components) can be nested inside Agnostic Components to create client boundaries when the root of the application is planted on the server.
331
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can compose with one another.
332
- // USE_SERVER_FUNCTIONS allowed, because as Agnostic Components Modules can import Client Components, they are able to pass them Server Functions as props as well.
333
- // USE_CLIENT_CONTEXTS allowed, because Client Components (Client Contexts Components) can be nested inside Agnostic Components to wrap some of the tree with client state accessible through child Client Components and pass through Server Components (if still on the Server Tree) when the root of the application is planted on the server.
334
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can compose with one another, including with Agnostic Conditions Components, making this a necessary mechanism for Server Components to be nested in Agnostic Components.
332
+ // USE_CLIENT_COMPONENTS allowed, because Lineal Client Components can be nested inside Agnostic Components to create client boundaries when the root of the application is planted on the server.
333
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components, can compose with one another.
334
+ // USE_SERVER_FUNCTIONS allowed, because (Special) Server Functions can be passed to Client Components as props when Client Components are also legally imported into Agnostic Components Modules.
335
+ // USE_CLIENT_CONTEXTS allowed, because (Special) Client Contexts Components can be nested inside Agnostic Components to wrap some of the tree with client state accessible through child Client Components, and to pass through Server Components (if still on the Server Tree) when the root of the application is planted on the server.
336
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components can compose with Lineal Agnostic Components as if they were Lineal Agnostic Components themselves, making them a necessary mechanism for Server Components to be nested in Agnostic Components.
335
337
  ],
336
338
  [USE_SERVER_FUNCTIONS]: [
337
- // USE_SERVER_LOGICS allowed, because logic from the server can safely support Server Functions.
339
+ // USE_SERVER_LOGICS allowed, because Prime Server Logics, being logic from the server, can safely support (Special) Server Functions.
338
340
  {
339
341
  blockedImport: USE_CLIENT_LOGICS,
340
342
  message: `${makeIntroForSpecificViolationMessage(
341
343
  USE_SERVER_FUNCTIONS,
342
344
  USE_CLIENT_LOGICS
343
- )} Client logic should never leak to the server.`,
345
+ )} Prime Client Logics should never leak to the server.`,
344
346
  },
345
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the server just like it can on the client.
347
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics can run safely on the server just like they can on the client.
346
348
  {
347
349
  blockedImport: USE_SERVER_COMPONENTS,
348
350
  message: `${makeIntroForSpecificViolationMessage(
349
351
  USE_SERVER_FUNCTIONS,
350
352
  USE_SERVER_COMPONENTS
351
- )} Server Functions have no business working with React Components.`,
353
+ )} Lineal Server Components aren't allowed because (Special) Server Functions have no business working with React Components.`,
352
354
  },
353
355
  {
354
356
  blockedImport: USE_CLIENT_COMPONENTS,
355
357
  message: `${makeIntroForSpecificViolationMessage(
356
358
  USE_SERVER_FUNCTIONS,
357
359
  USE_CLIENT_COMPONENTS
358
- )} Server Functions have no business working with React Components.`,
360
+ )} Lineal Client Components aren't allowed because (Special) Server Functions have no business working with React Components.`,
359
361
  },
360
362
  {
361
363
  blockedImport: USE_AGNOSTIC_COMPONENTS,
362
364
  message: `${makeIntroForSpecificViolationMessage(
363
365
  USE_SERVER_FUNCTIONS,
364
366
  USE_AGNOSTIC_COMPONENTS
365
- )} Server Functions have no business working with React Components.`,
367
+ )} Lineal Agnostic Components aren't allowed because (Special) Server Functions have no business working with React Components.`,
366
368
  },
367
- // USE_SERVER_FUNCTIONS allowed, because even though Server Functions don't need to import one another and the same results can be generated via Server Logic alone for the outcome of a single Server Function, a rational use case could be found for composing Server Functions with one another either today or in the future.
369
+ // USE_SERVER_FUNCTIONS allowed, because (Special) Server Functions, even though they don't need to import one another and the same results can be generated via Prime Server Logics for the outcome of a single Server Function, can still compose with one another. (Perhaps a preferrable use case for this has been found or could be found either today or in the future.)
368
370
  {
369
371
  blockedImport: USE_CLIENT_CONTEXTS,
370
372
  message: `${makeIntroForSpecificViolationMessage(
371
373
  USE_SERVER_FUNCTIONS,
372
374
  USE_CLIENT_CONTEXTS
373
- )} Server Functions have no business working with React Components.`,
375
+ )} (Special) Client Contexts Components aren't allowed because (Special) Server Functions have no business working with React Components.`,
374
376
  },
375
377
  {
376
378
  blockedImport: USE_AGNOSTIC_CONDITIONS,
377
379
  message: `${makeIntroForSpecificViolationMessage(
378
380
  USE_SERVER_FUNCTIONS,
379
381
  USE_AGNOSTIC_CONDITIONS
380
- )} Server Functions have no business working with React Components.`,
382
+ )} (Special) Agnostic Conditions Components aren't allowed (Special)because Server Functions have no business working with React Components.`,
381
383
  },
382
384
  ],
383
385
  [USE_CLIENT_CONTEXTS]: [
@@ -386,22 +388,22 @@ export const commentedDirectives_BlockedImports = Object.freeze({
386
388
  message: `${makeIntroForSpecificViolationMessage(
387
389
  USE_CLIENT_CONTEXTS,
388
390
  USE_SERVER_LOGICS
389
- )} Server logic should never leak to the client.`,
391
+ )} Prime Server Logics should never leak to the client.`,
390
392
  },
391
- // USE_CLIENT_LOGICS allowed, because logic from the client can safely support Client Components, including Client Contexts Components.
392
- // USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the client just like it can on the server.
393
+ // USE_CLIENT_LOGICS allowed, because Prime Client Logics, being logic from the client, can safely support (Special) Client Contexts Components, like any Client Components.
394
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics can run safely on the client just like they can on the server.
393
395
  {
394
396
  blockedImport: USE_SERVER_COMPONENTS,
395
397
  message: `${makeIntroForSpecificViolationMessage(
396
398
  USE_CLIENT_CONTEXTS,
397
399
  USE_SERVER_COMPONENTS
398
- )} Server Components may only pass through Client Contexts Components through the children prop within Server Components Modules.`,
400
+ )} Lineal Server Components may only pass through Client Contexts Components via the children prop within Server Components Modules.`,
399
401
  },
400
- // USE_CLIENT_COMPONENTS allowed, because Lineal Client Components can create client boundaries within Client Contexts Components.
401
- // USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can render safely on the client just like they can on the server.
402
- // USE_SERVER_FUNCTIONS allowed, because Server Functions are specifically triggered by Client Components, including Client Contexts Components.
403
- // USE_CLIENT_CONTEXTS allowed, because Client Contexts Components can compose with one another.
404
- // USE_AGNOSTIC_CONDITIONS allowed, because Agnostic Components can render safely on the client just like they can on the server, including Agnostic Conditions Components, in a mechanism that allows Client Contexts Components to indirectly compose with child Server Components within Client Contexts Modules.
402
+ // USE_CLIENT_COMPONENTS allowed, because Lineal Client Components can create client boundaries within (Special) Client Contexts Components.
403
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components can render safely on the client just like they can on the server.
404
+ // USE_SERVER_FUNCTIONS allowed, because (Special) Server Functions are specifically triggered by Client Components.
405
+ // USE_CLIENT_CONTEXTS allowed, because (Special) Client Contexts Components can compose with one another.
406
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components, as if they were Lineal Agnostic Components themselves, can render safely on the client just like they can on the server, in a mechanism that allows Client Contexts Components to safely and indirectly compose with child Server Components within Client Contexts Modules.
405
407
  ],
406
408
  [USE_AGNOSTIC_CONDITIONS]: [
407
409
  {
@@ -409,52 +411,58 @@ export const commentedDirectives_BlockedImports = Object.freeze({
409
411
  message: `${makeIntroForSpecificViolationMessage(
410
412
  USE_AGNOSTIC_CONDITIONS,
411
413
  USE_SERVER_LOGICS
412
- )} Server Logic cannot run in both the server and the client.`,
414
+ )} Prime Server Logics cannot run on both the server and the client.`,
413
415
  },
414
416
  {
415
417
  blockedImport: USE_CLIENT_LOGICS,
416
418
  message: `${makeIntroForSpecificViolationMessage(
417
419
  USE_AGNOSTIC_CONDITIONS,
418
420
  USE_CLIENT_LOGICS
419
- )} Client Logic cannot run in both the server and the client.`,
421
+ )} Prime Client Logics cannot run on both the server and the client.`,
420
422
  },
421
- // USE_AGNOSTIC_LOGICS allowed, because environment-agnostic logic can safely support Agnostic Components, including Agnostic Conditions Components. (In this case this is necessary for the import of the conditionAgnosticComponent function needed to make Agnostic Conditions Components.)
422
- // USE_SERVER_COMPONENTS allowed, because they are to be paired with `ComponentForClient` components to form Agnostic Conditions Components.
423
- // USE_CLIENT_COMPONENTS allowed, because they are to be paired with `ComponentForServer` components to form Agnostic Conditions Components.
424
- // USE_AGNOSTIC_COMPONENTS allowed, because they can take the place of `ComponentForServer` and/or `ComponentForClient` components to form Agnostic Conditions Components.
423
+ // USE_AGNOSTIC_LOGICS allowed, because Prime Agnostic Logics, being environment-agnostic logic, can safely support Agnostic Components, including (Special) Agnostic Conditions Components. (In this case this is necessary for the import of the `conditionAgnosticComponent` function needed to make Agnostic Conditions Components.)
424
+ // USE_SERVER_COMPONENTS allowed, because Lineal Server Components are to be paired as `ComponentForServer` components with `ComponentForClient` components to form (Special) Agnostic Conditions Components.
425
+ // USE_CLIENT_COMPONENTS allowed, because Lineal Client Components are to be paired as `ComponentForClient` components with `ComponentForServer` components to form (Special) Agnostic Conditions Components.
426
+ // USE_AGNOSTIC_COMPONENTS allowed, because Lineal Agnostic Components can take the place of `ComponentForServer` and/or `ComponentForClient` components to form (Special) Agnostic Conditions Components.
425
427
  {
426
428
  blockedImport: USE_SERVER_FUNCTIONS,
427
429
  message: `${makeIntroForSpecificViolationMessage(
428
430
  USE_AGNOSTIC_CONDITIONS,
429
431
  USE_SERVER_FUNCTIONS
430
- )} Agnostic Conditions Components only take finite, imported components as arguments in their making. As such, assigning props to these components, including Server Functions, is not made within Agnostic Conditions Modules.`,
432
+ )} (Special) Server Functions are not accepted because (Special) Agnostic Conditions Components only take finite, imported components as arguments in their making. As such, assigning props to these components, including Server Functions, is not made within Agnostic Conditions Modules.`,
431
433
  },
432
434
  {
433
435
  blockedImport: USE_CLIENT_CONTEXTS,
434
436
  message: `${makeIntroForSpecificViolationMessage(
435
437
  USE_AGNOSTIC_CONDITIONS,
436
438
  USE_CLIENT_CONTEXTS
437
- )} Agnostic Conditions Components only take Lineal Components as arguments in their making.`,
439
+ )} (Special) Client Contexts Components cannot be used as component arguments for (Special) Agnostic Conditions Components since they only take Lineal Components as arguments in their making.`,
438
440
  },
439
- // USE_AGNOSTIC_CONDITIONS allowed, because despite not being Lineal Components themselves, their output components can only be Lineal and compatible with their attributed rendering environments, making them acceptable arguments in the making of Agnostic Conditions Components.
441
+ // USE_AGNOSTIC_CONDITIONS allowed, because (Special) Agnostic Conditions Components, despite not being Lineal Components themselves, output components that can only be Lineal and compatible with their attributed rendering environments, making them acceptable arguments in the making of Agnostic Conditions Components.
440
442
  ],
441
443
  [USE_AGNOSTIC_STRATEGIES]: [
442
- // Agnostic Strategies Modules can import all known modules, except themselves since they cannot be imported as they are, only as and via Strategies. (Since Agnostic Strategies Modules cannot be imported as they are, there is no such things as a 'use agnostic strategies' importFileCommentedDirective.)
444
+ // (Special) Agnostic Strategies Modules can import all known modules, except themselves since they cannot be imported as they are, only as and via Strategies. (Since Agnostic Strategies Modules cannot be imported as they are, there is no such things as a 'use agnostic strategies' importFileCommentedDirective.)
443
445
  ],
444
446
  });
445
447
 
446
448
  /* from the currentFileFlow flow */
447
449
 
450
+ const MODULES_MARKED_WITH_THE_ = "modules marked with the";
451
+ const _DIRECTIVE_MUST_HAVE_A_NON_JSX_FILE_EXTENSION =
452
+ "directive must have a non-JSX file extension";
453
+ const _DIRECTIVE_MUST_HAVE_A_JSX_FILE_EXTENSION =
454
+ "directive must have a JSX file extension";
455
+
448
456
  export const commentedDirectives_VerificationReports = Object.freeze({
449
- // somehow doing it by hand is better for type inference
450
- [USE_SERVER_LOGICS]: `modules marked with the "${USE_SERVER_LOGICS}" directive must have a non-JSX file extension.`,
451
- [USE_CLIENT_LOGICS]: `modules marked with the "${USE_CLIENT_LOGICS}" directive must have a non-JSX file extension.`,
452
- [USE_AGNOSTIC_LOGICS]: `modules marked with the "${USE_AGNOSTIC_LOGICS}" directive must have a non-JSX file extension.`,
453
- [USE_SERVER_COMPONENTS]: `modules marked with the "${USE_SERVER_COMPONENTS}" directive must have a JSX file extension.`,
454
- [USE_CLIENT_COMPONENTS]: `modules marked with the "${USE_CLIENT_COMPONENTS}" directive must have a JSX file extension.`,
455
- [USE_AGNOSTIC_COMPONENTS]: `modules marked with the "${USE_AGNOSTIC_COMPONENTS}" directive must have a JSX file extension.`,
456
- [USE_SERVER_FUNCTIONS]: `modules marked with the "${USE_SERVER_FUNCTIONS}" directive must have a non-JSX file extension.`,
457
- [USE_CLIENT_CONTEXTS]: `modules marked with the "${USE_CLIENT_CONTEXTS}" directive must have a JSX file extension.`,
458
- [USE_AGNOSTIC_CONDITIONS]: `modules marked with the "${USE_AGNOSTIC_CONDITIONS}" directive must have a JSX file extension.`,
459
- [USE_AGNOSTIC_STRATEGIES]: `modules marked with the "${USE_AGNOSTIC_STRATEGIES}" directive are free to have the file extension of their choosing. (This is not a problem and should never surface.)`,
457
+ // somehow doing it by hand is better for type inference in raw JS
458
+ [USE_SERVER_LOGICS]: `${MODULES_MARKED_WITH_THE_} "${USE_SERVER_LOGICS}" ${_DIRECTIVE_MUST_HAVE_A_NON_JSX_FILE_EXTENSION}.`,
459
+ [USE_CLIENT_LOGICS]: `${MODULES_MARKED_WITH_THE_} "${USE_CLIENT_LOGICS}" ${_DIRECTIVE_MUST_HAVE_A_NON_JSX_FILE_EXTENSION}.`,
460
+ [USE_AGNOSTIC_LOGICS]: `${MODULES_MARKED_WITH_THE_} "${USE_AGNOSTIC_LOGICS}" ${_DIRECTIVE_MUST_HAVE_A_NON_JSX_FILE_EXTENSION}.`,
461
+ [USE_SERVER_COMPONENTS]: `${MODULES_MARKED_WITH_THE_} "${USE_SERVER_COMPONENTS}" ${_DIRECTIVE_MUST_HAVE_A_JSX_FILE_EXTENSION}.`,
462
+ [USE_CLIENT_COMPONENTS]: `${MODULES_MARKED_WITH_THE_} "${USE_CLIENT_COMPONENTS}" ${_DIRECTIVE_MUST_HAVE_A_JSX_FILE_EXTENSION}.`,
463
+ [USE_AGNOSTIC_COMPONENTS]: `${MODULES_MARKED_WITH_THE_} "${USE_AGNOSTIC_COMPONENTS}" ${_DIRECTIVE_MUST_HAVE_A_JSX_FILE_EXTENSION}.`,
464
+ [USE_SERVER_FUNCTIONS]: `${MODULES_MARKED_WITH_THE_} "${USE_SERVER_FUNCTIONS}" ${_DIRECTIVE_MUST_HAVE_A_NON_JSX_FILE_EXTENSION}.`,
465
+ [USE_CLIENT_CONTEXTS]: `${MODULES_MARKED_WITH_THE_} "${USE_CLIENT_CONTEXTS}" ${_DIRECTIVE_MUST_HAVE_A_JSX_FILE_EXTENSION}.`,
466
+ [USE_AGNOSTIC_CONDITIONS]: `${MODULES_MARKED_WITH_THE_} "${USE_AGNOSTIC_CONDITIONS}" ${_DIRECTIVE_MUST_HAVE_A_JSX_FILE_EXTENSION}.`,
467
+ [USE_AGNOSTIC_STRATEGIES]: `${MODULES_MARKED_WITH_THE_} "${USE_AGNOSTIC_STRATEGIES}" directive are free to have the file extension of their choosing. (This is not a problem and should never surface.)`,
460
468
  });
@@ -28,7 +28,10 @@ import {
28
28
  specificFailure,
29
29
  } from "../constants/bases.js";
30
30
 
31
- import { resolveImportPath } from "../../../_commons/utilities/helpers.js";
31
+ import {
32
+ resolveImportPath,
33
+ highlightFirstLineOfCode,
34
+ } from "../../../_commons/utilities/helpers.js";
32
35
  import {
33
36
  getCommentedDirectiveFromCurrentModule,
34
37
  getVerifiedCommentedDirective,
@@ -37,6 +40,7 @@ import {
37
40
  makeMessageFromCommentedDirective,
38
41
  findSpecificViolationMessage,
39
42
  getStrategizedDirective,
43
+ addressDirectiveIfAgnosticStrategies,
40
44
  } from "./helpers.js";
41
45
 
42
46
  /* currentFileFlow */
@@ -67,10 +71,7 @@ export const currentFileFlow = (context) => {
67
71
  // reports if there is no directive or no valid directive (same, but eventually no directive could have defaults)
68
72
  if (!commentedDirective) {
69
73
  context.report({
70
- loc: {
71
- start: { line: 1, column: 0 },
72
- end: { line: 1, column: context.sourceCode.lines[0].length },
73
- },
74
+ loc: highlightFirstLineOfCode(context),
74
75
  messageId: noCommentedDirective,
75
76
  });
76
77
  return { skip: true };
@@ -84,10 +85,7 @@ export const currentFileFlow = (context) => {
84
85
  // reports if the verification failed
85
86
  if (!verifiedCommentedDirective) {
86
87
  context.report({
87
- loc: {
88
- start: { line: 1, column: 0 },
89
- end: { line: 1, column: context.sourceCode.lines[0].length },
90
- },
88
+ loc: highlightFirstLineOfCode(context),
91
89
  messageId: commentedDirectiveVerificationFailed,
92
90
  data: {
93
91
  [specificFailure]:
@@ -139,10 +137,11 @@ const importedFileFlow = (context, node) => {
139
137
  }
140
138
 
141
139
  /* GETTING THE CORRECT DIRECTIVE INTERPRETATION OF STRATEGY FOR AGNOSTIC STRATEGIES MODULES IMPORTS.
142
- (The Directive-First Architecture does not check whether the export and import Strategies are the same at this time, meaning a @clientLogics strategy could be wrongly imported and interpreted as a @serverLogics strategy.
140
+ (The Directive-First Architecture does not check whether the export and import Strategies are the same at this time, meaning an @clientLogics strategy could be wrongly imported and interpreted as an @serverLogics strategy.
143
141
 
144
- After a short attempt, this feature is currently cancelled, mainly since the amount of work it will require will not be able to be transferred in a future where commented strategies will actually be real syntax.
142
+ After a short attempt, this feature is currently canceled, mainly since the amount of work it will require will not be able to be transferred in a future where commented strategies will actually be real syntax.
145
143
 
144
+ // (Consequently, details below are currently at the stage of wishful thinking.)
146
145
  However, Strategy exports are planned to be linting in the future within their own Agnostic Strategies Modules to ensure they respect import rules within their own scopes. It may also become possible to check whether the export and import Strategies are the same in the future when identifiers are defined and the same, especially for components modules where a convention could be to for all non-type export to be named and PascalCase.) */
147
146
  if (importedFileCommentedDirective === USE_AGNOSTIC_STRATEGIES) {
148
147
  const importingFileCommentedDirective = getStrategizedDirective(
@@ -222,27 +221,29 @@ export const allExportsFlow = (
222
221
  // does not operate on `export type`
223
222
  if (node.exportKind === "type") return;
224
223
 
225
- if (node.source) {
224
+ // regular exports scenarios
225
+ if (!node.source) {
226
+ addressDirectiveIfAgnosticStrategies(
227
+ context,
228
+ node,
229
+ currentFileCommentedDirective
230
+ );
231
+ }
232
+ // re-exports scenarios
233
+ else {
226
234
  const result = importedFileFlow(context, node);
227
235
 
228
236
  if (result.skip) return;
229
237
  const { importedFileCommentedDirective } = result;
230
238
 
231
- // ignores if this is NOT an Agnostic Strategies Module
232
- // verifies current node export strategy if "use agnostic strategies"
233
- if (currentFileCommentedDirective === USE_AGNOSTIC_STRATEGIES) {
234
- const exportStrategizedDirective = getStrategizedDirective(context, node);
235
-
236
- if (exportStrategizedDirective === null) {
237
- context.report({
238
- node,
239
- messageId: exportNotStrategized,
240
- });
241
- return;
242
- }
239
+ const addressedDirective = addressDirectiveIfAgnosticStrategies(
240
+ context,
241
+ node,
242
+ currentFileCommentedDirective
243
+ );
243
244
 
244
- currentFileCommentedDirective = exportStrategizedDirective;
245
- }
245
+ if (!addressedDirective) return;
246
+ else currentFileCommentedDirective = addressedDirective;
246
247
 
247
248
  if (currentFileCommentedDirective !== importedFileCommentedDirective) {
248
249
  context.report({
@@ -255,24 +256,6 @@ export const allExportsFlow = (
255
256
  importedFileCommentedDirective,
256
257
  },
257
258
  });
258
- return;
259
- }
260
- } else {
261
- // ignores if this is NOT an Agnostic Strategies Module
262
- // verifies current node export strategy if "use agnostic strategies"
263
- if (currentFileCommentedDirective === USE_AGNOSTIC_STRATEGIES) {
264
- const exportStrategizedDirective = getStrategizedDirective(context, node);
265
-
266
- if (exportStrategizedDirective === null) {
267
- context.report({
268
- node,
269
- messageId: exportNotStrategized,
270
- });
271
- return;
272
- }
273
-
274
- // just to emphasize that this is the same short flow from above
275
- currentFileCommentedDirective = exportStrategizedDirective;
276
259
  }
277
260
  }
278
261
  };
@@ -190,9 +190,11 @@ export const getCommentedDirectiveFromImportedModule = (resolvedImportPath) => {
190
190
  const importedFileFirstLine = getImportedFileFirstLine(resolvedImportPath);
191
191
 
192
192
  // sees if the first line includes any of the directives and finds the directive that it includes
193
+ /** @type {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS | USE_AGNOSTIC_STRATEGIES | ""} */
193
194
  let includedDirective = "";
194
- const lengthOne = directivesArray.length;
195
- for (let i = 0; i < lengthOne; i++) {
195
+ const firstLength = directivesArray.length;
196
+
197
+ for (let i = 0; i < firstLength; i++) {
196
198
  const directive = directivesArray[i];
197
199
  if (importedFileFirstLine.includes(directive)) {
198
200
  includedDirective = directive;
@@ -203,12 +205,14 @@ export const getCommentedDirectiveFromImportedModule = (resolvedImportPath) => {
203
205
  // returns null early if there is none of the directives in the first line
204
206
  if (includedDirective === "") return null;
205
207
 
208
+ /** @type {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS | USE_AGNOSTIC_STRATEGIES | ""} */
206
209
  let importFileDirective = "";
207
- const lengthTwo =
208
- // sucks for that any but, I'm working in JS here
209
- commentedDirectives_4RawImplementations[includedDirective].length;
210
- for (let i = 0; i < lengthTwo; i++) {
211
- const raw = commentedDirectives_4RawImplementations[includedDirective][i];
210
+ const rawImplementations =
211
+ commentedDirectives_4RawImplementations[includedDirective];
212
+ const secondLength = rawImplementations.length;
213
+
214
+ for (let i = 0; i < secondLength; i++) {
215
+ const raw = rawImplementations[i];
212
216
  if (raw === importedFileFirstLine) {
213
217
  importFileDirective = includedDirective;
214
218
  break;
@@ -289,3 +293,33 @@ export const findSpecificViolationMessage = (
289
293
  currentFileCommentedDirective,
290
294
  importedFileCommentedDirective
291
295
  );
296
+
297
+ /* addressDirectiveIfAgnosticStrategies */
298
+
299
+ /**
300
+ * Verifies the current node's export strategy if `"use agnostic strategies"` by reporting `exportNotStrategized` in case an export is not strategized in an Agnostic Strategies Module.
301
+ * @param {Readonly<import('@typescript-eslint/utils').TSESLint.RuleContext<typeof reExportNotSameMessageId | typeof importBreaksCommentedImportRulesMessageId | typeof noCommentedDirective | typeof commentedDirectiveVerificationFailed | typeof importNotStrategized | typeof exportNotStrategized, []>>} context The ESLint rule's `context` object.
302
+ * @param {import('@typescript-eslint/types').TSESTree.ExportNamedDeclaration | import('@typescript-eslint/types').TSESTree.ExportAllDeclaration | import('@typescript-eslint/types').TSESTree.ExportDefaultDeclaration} node The ESLint `node` of the rule's current traversal.
303
+ * @param {USE_SERVER_LOGICS | USE_CLIENT_LOGICS | USE_AGNOSTIC_LOGICS | USE_SERVER_COMPONENTS | USE_CLIENT_COMPONENTS | USE_AGNOSTIC_COMPONENTS | USE_SERVER_FUNCTIONS | USE_CLIENT_CONTEXTS | USE_AGNOSTIC_CONDITIONS | USE_AGNOSTIC_STRATEGIES} currentFileCommentedDirective The current file's commented directive.
304
+ * @returns The commented directive, the addressed strategy (as a commented directive) or null in case of failure.
305
+ */
306
+ export const addressDirectiveIfAgnosticStrategies = (
307
+ context,
308
+ node,
309
+ currentFileCommentedDirective
310
+ ) => {
311
+ // ignores if not addressing an Agnostic Strategies Module
312
+ if (currentFileCommentedDirective !== USE_AGNOSTIC_STRATEGIES)
313
+ return currentFileCommentedDirective;
314
+
315
+ const exportStrategizedDirective = getStrategizedDirective(context, node);
316
+
317
+ if (exportStrategizedDirective === null) {
318
+ context.report({
319
+ node,
320
+ messageId: exportNotStrategized,
321
+ });
322
+ }
323
+
324
+ return exportStrategizedDirective; // null indicates failure
325
+ };
@@ -9,6 +9,8 @@ import {
9
9
 
10
10
  /**
11
11
  * Makes the directive21 config for the use-agnostic ESLint plugin.
12
+ * @param {import('eslint').ESLint.Plugin} plugin The use-agnostic ESLint plugin itself.
13
+ * @returns The directive21 config's name as a key and its config as its value.
12
14
  */
13
15
  export const makeDirective21Config = (plugin) => ({
14
16
  [directive21ConfigName]: defineConfig([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-use-agnostic",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "Highlights problematic server-client imports in projects made with the Fullstack React Architecture.",
5
5
  "keywords": [
6
6
  "eslint",