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 +6 -6
- package/library/_commons/constants/bases.js +4 -2
- package/library/_commons/utilities/helpers.js +20 -8
- package/library/agnostic20/_commons/constants/bases.js +33 -32
- package/library/agnostic20/_commons/utilities/flows.js +7 -10
- package/library/agnostic20/config.js +2 -0
- package/library/directive21/_commons/constants/bases.js +115 -107
- package/library/directive21/_commons/utilities/flows.js +27 -44
- package/library/directive21/_commons/utilities/helpers.js +41 -7
- package/library/directive21/config.js +2 -0
- package/package.json +1 -1
- /package/library/directive21/{crossingStrategies → (crossingStrategies)}/_commons/plugins/strategies.js +0 -0
- /package/library/directive21/{crossingStrategies → (crossingStrategies)}/_commons/rules/defaults.js +0 -0
- /package/library/directive21/{crossingStrategies → (crossingStrategies)}/_commons/rules/namespaces.js +0 -0
- /package/library/directive21/{crossingStrategies → (crossingStrategies)}/_commons/rules/specifiers.js +0 -0
- /package/library/directive21/{crossingStrategies → (crossingStrategies)}/config.js +0 -0
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
|
|
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
|
|
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
|
|
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
|
|
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;
|
|
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
|
|
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"
|
|
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
|
|
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
|
|
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
|
|
113
|
-
// USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the server just like they can on the client,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
184
|
-
// USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can be composed with Logics on the client just like they can on the server,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
)}
|
|
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
|
|
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
|
|
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
|
-
)}
|
|
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
|
|
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
|
|
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 {
|
|
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
|
-
//
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
|
177
|
+
)} Prime Client Logics should never leak to the server.`,
|
|
176
178
|
},
|
|
177
|
-
// USE_AGNOSTIC_LOGICS allowed, because Agnostic
|
|
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
|
|
187
|
-
// USE_SERVER_FUNCTIONS allowed, because
|
|
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
|
|
195
|
+
)} (Special) Client Contexts Components, like any Client Components, cannot be tinkered with on the server.`,
|
|
194
196
|
},
|
|
195
|
-
// USE_AGNOSTIC_CONDITIONS allowed, because
|
|
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
|
|
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
|
|
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
|
|
216
|
-
// USE_SERVER_FUNCTIONS allowed, because
|
|
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
|
|
218
|
-
// USE_AGNOSTIC_CONDITIONS allowed, because
|
|
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
|
|
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
|
|
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
|
|
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
|
-
)}
|
|
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
|
|
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
|
|
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
|
|
276
|
+
)} Prime Client Logics should never leak to the server.`,
|
|
275
277
|
},
|
|
276
|
-
// USE_AGNOSTIC_LOGICS allowed, because Agnostic
|
|
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
|
|
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
|
|
281
|
-
// USE_CLIENT_CONTEXTS allowed, because
|
|
282
|
-
// USE_AGNOSTIC_CONDITIONS allowed, because Agnostic Components can render safely on the server just like they can on the client
|
|
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
|
|
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
|
|
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
|
|
305
|
-
// USE_AGNOSTIC_CONDITIONS allowed, because Agnostic Components can render safely on the client just like they can on the server
|
|
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
|
|
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
|
|
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
|
-
)}
|
|
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
|
|
331
|
-
// USE_AGNOSTIC_COMPONENTS allowed, because Agnostic Components can compose with one another.
|
|
332
|
-
// USE_SERVER_FUNCTIONS allowed, because
|
|
333
|
-
// USE_CLIENT_CONTEXTS allowed, because
|
|
334
|
-
//
|
|
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
|
|
345
|
+
)} Prime Client Logics should never leak to the server.`,
|
|
344
346
|
},
|
|
345
|
-
// USE_AGNOSTIC_LOGICS allowed, because Agnostic
|
|
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
|
|
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
|
|
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,
|
|
392
|
-
// USE_AGNOSTIC_LOGICS allowed, because Agnostic
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
423
|
-
// USE_CLIENT_COMPONENTS allowed, because
|
|
424
|
-
// USE_AGNOSTIC_COMPONENTS allowed, because
|
|
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,
|
|
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]:
|
|
451
|
-
[USE_CLIENT_LOGICS]:
|
|
452
|
-
[USE_AGNOSTIC_LOGICS]:
|
|
453
|
-
[USE_SERVER_COMPONENTS]:
|
|
454
|
-
[USE_CLIENT_COMPONENTS]:
|
|
455
|
-
[USE_AGNOSTIC_COMPONENTS]:
|
|
456
|
-
[USE_SERVER_FUNCTIONS]:
|
|
457
|
-
[USE_CLIENT_CONTEXTS]:
|
|
458
|
-
[USE_AGNOSTIC_CONDITIONS]:
|
|
459
|
-
[USE_AGNOSTIC_STRATEGIES]:
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
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
|
-
|
|
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
|
|
195
|
-
|
|
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
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
File without changes
|
/package/library/directive21/{crossingStrategies → (crossingStrategies)}/_commons/rules/defaults.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|