eslint-plugin-use-agnostic 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/library/_commons/constants/bases.js +72 -0
- package/library/_commons/utilities/helpers.js +191 -0
- package/library/agnostic20/config.js +24 -0
- package/library/agnostic20/constants/bases.js +268 -0
- package/library/agnostic20/rules/import-rules-enforcement.js +55 -0
- package/library/agnostic20/utilities/flows.js +212 -0
- package/library/agnostic20/utilities/helpers.js +186 -0
- package/library/directive21/config.js +24 -0
- package/library/directive21/constants/bases.js +460 -0
- package/library/directive21/rules/import-rules-enforcement.js +67 -0
- package/library/directive21/utilities/flows.js +268 -0
- package/library/directive21/utilities/helpers.js +291 -0
- package/library/index.js +42 -0
- package/package.json +43 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import {
|
|
2
|
+
USE_SERVER_LOGICS as COMMONS_USE_SERVER_LOGICS,
|
|
3
|
+
USE_CLIENT_LOGICS as COMMONS_USE_CLIENT_LOGICS,
|
|
4
|
+
USE_AGNOSTIC_LOGICS as COMMONS_USE_AGNOSTIC_LOGICS,
|
|
5
|
+
USE_SERVER_COMPONENTS as COMMONS_USE_SERVER_COMPONENTS,
|
|
6
|
+
USE_CLIENT_COMPONENTS as COMMONS_USE_CLIENT_COMPONENTS,
|
|
7
|
+
USE_AGNOSTIC_COMPONENTS as COMMONS_USE_AGNOSTIC_COMPONENTS,
|
|
8
|
+
USE_SERVER_FUNCTIONS as COMMONS_USE_SERVER_FUNCTIONS,
|
|
9
|
+
USE_CLIENT_CONTEXTS as COMMONS_USE_CLIENT_CONTEXTS,
|
|
10
|
+
USE_AGNOSTIC_CONDITIONS as COMMONS_USE_AGNOSTIC_CONDITIONS,
|
|
11
|
+
USE_AGNOSTIC_STRATEGIES as COMMONS_USE_AGNOSTIC_STRATEGIES,
|
|
12
|
+
SERVER_LOGICS_MODULE as COMMONS_SERVER_LOGICS_MODULE,
|
|
13
|
+
CLIENT_LOGICS_MODULE as COMMONS_CLIENT_LOGICS_MODULE,
|
|
14
|
+
AGNOSTIC_LOGICS_MODULE as COMMONS_AGNOSTIC_LOGICS_MODULE,
|
|
15
|
+
SERVER_COMPONENTS_MODULE as COMMONS_SERVER_COMPONENTS_MODULE,
|
|
16
|
+
CLIENT_COMPONENTS_MODULE as COMMONS_CLIENT_COMPONENTS_MODULE,
|
|
17
|
+
AGNOSTIC_COMPONENTS_MODULE as COMMONS_AGNOSTIC_COMPONENTS_MODULE,
|
|
18
|
+
SERVER_FUNCTIONS_MODULE as COMMONS_SERVER_FUNCTIONS_MODULE,
|
|
19
|
+
CLIENT_CONTEXTS_MODULE as COMMONS_CLIENT_CONTEXTS_MODULE,
|
|
20
|
+
AGNOSTIC_CONDITIONS_MODULE as COMMONS_AGNOSTIC_CONDITIONS_MODULE,
|
|
21
|
+
AGNOSTIC_STRATEGIES_MODULE as COMMONS_AGNOSTIC_STRATEGIES_MODULE,
|
|
22
|
+
} from "../../_commons/constants/bases.js";
|
|
23
|
+
|
|
24
|
+
import { makeIntroForSpecificViolationMessage as commonsMakeIntroForSpecificViolationMessage } from "../../_commons/utilities/helpers.js";
|
|
25
|
+
|
|
26
|
+
// commented directives
|
|
27
|
+
export const USE_SERVER_LOGICS = COMMONS_USE_SERVER_LOGICS;
|
|
28
|
+
export const USE_CLIENT_LOGICS = COMMONS_USE_CLIENT_LOGICS;
|
|
29
|
+
export const USE_AGNOSTIC_LOGICS = COMMONS_USE_AGNOSTIC_LOGICS;
|
|
30
|
+
export const USE_SERVER_COMPONENTS = COMMONS_USE_SERVER_COMPONENTS;
|
|
31
|
+
export const USE_CLIENT_COMPONENTS = COMMONS_USE_CLIENT_COMPONENTS;
|
|
32
|
+
export const USE_AGNOSTIC_COMPONENTS = COMMONS_USE_AGNOSTIC_COMPONENTS;
|
|
33
|
+
export const USE_SERVER_FUNCTIONS = COMMONS_USE_SERVER_FUNCTIONS;
|
|
34
|
+
export const USE_CLIENT_CONTEXTS = COMMONS_USE_CLIENT_CONTEXTS;
|
|
35
|
+
export const USE_AGNOSTIC_CONDITIONS = COMMONS_USE_AGNOSTIC_CONDITIONS;
|
|
36
|
+
export const USE_AGNOSTIC_STRATEGIES = COMMONS_USE_AGNOSTIC_STRATEGIES;
|
|
37
|
+
|
|
38
|
+
// commented modules
|
|
39
|
+
const SERVER_LOGICS_MODULE = COMMONS_SERVER_LOGICS_MODULE;
|
|
40
|
+
const CLIENT_LOGICS_MODULE = COMMONS_CLIENT_LOGICS_MODULE;
|
|
41
|
+
const AGNOSTIC_LOGICS_MODULE = COMMONS_AGNOSTIC_LOGICS_MODULE;
|
|
42
|
+
const SERVER_COMPONENTS_MODULE = COMMONS_SERVER_COMPONENTS_MODULE;
|
|
43
|
+
const CLIENT_COMPONENTS_MODULE = COMMONS_CLIENT_COMPONENTS_MODULE;
|
|
44
|
+
const AGNOSTIC_COMPONENTS_MODULE = COMMONS_AGNOSTIC_COMPONENTS_MODULE;
|
|
45
|
+
const SERVER_FUNCTIONS_MODULE = COMMONS_SERVER_FUNCTIONS_MODULE;
|
|
46
|
+
const CLIENT_CONTEXTS_MODULE = COMMONS_CLIENT_CONTEXTS_MODULE;
|
|
47
|
+
const AGNOSTIC_CONDITIONS_MODULE = COMMONS_AGNOSTIC_CONDITIONS_MODULE;
|
|
48
|
+
const AGNOSTIC_STRATEGIES_MODULE = COMMONS_AGNOSTIC_STRATEGIES_MODULE;
|
|
49
|
+
|
|
50
|
+
// mapping commented directives with commented modules
|
|
51
|
+
export const commentedDirectives_CommentedModules = Object.freeze({
|
|
52
|
+
[USE_SERVER_LOGICS]: SERVER_LOGICS_MODULE,
|
|
53
|
+
[USE_CLIENT_LOGICS]: CLIENT_LOGICS_MODULE,
|
|
54
|
+
[USE_AGNOSTIC_LOGICS]: AGNOSTIC_LOGICS_MODULE,
|
|
55
|
+
[USE_SERVER_COMPONENTS]: SERVER_COMPONENTS_MODULE,
|
|
56
|
+
[USE_CLIENT_COMPONENTS]: CLIENT_COMPONENTS_MODULE,
|
|
57
|
+
[USE_AGNOSTIC_COMPONENTS]: AGNOSTIC_COMPONENTS_MODULE,
|
|
58
|
+
[USE_SERVER_FUNCTIONS]: SERVER_FUNCTIONS_MODULE,
|
|
59
|
+
[USE_CLIENT_CONTEXTS]: CLIENT_CONTEXTS_MODULE,
|
|
60
|
+
[USE_AGNOSTIC_CONDITIONS]: AGNOSTIC_CONDITIONS_MODULE,
|
|
61
|
+
[USE_AGNOSTIC_STRATEGIES]: AGNOSTIC_STRATEGIES_MODULE,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// message placeholders
|
|
65
|
+
|
|
66
|
+
export const currentFileCommentedDirective = "currentFileCommentedDirective";
|
|
67
|
+
export const importedFileCommentedDirective = "importedFileCommentedDirective";
|
|
68
|
+
export const commentedDirectiveMessage = "commentedDirectiveMessage";
|
|
69
|
+
export const specificViolationMessage = "specificViolationMessage";
|
|
70
|
+
export const specificFailure = "specificFailure";
|
|
71
|
+
|
|
72
|
+
/* from the getCommentedDirectiveFromCurrentModule utility */
|
|
73
|
+
|
|
74
|
+
export const directivesSet = new Set([
|
|
75
|
+
USE_SERVER_LOGICS,
|
|
76
|
+
USE_CLIENT_LOGICS,
|
|
77
|
+
USE_AGNOSTIC_LOGICS,
|
|
78
|
+
USE_SERVER_COMPONENTS,
|
|
79
|
+
USE_CLIENT_COMPONENTS,
|
|
80
|
+
USE_AGNOSTIC_COMPONENTS,
|
|
81
|
+
USE_SERVER_FUNCTIONS,
|
|
82
|
+
USE_CLIENT_CONTEXTS,
|
|
83
|
+
USE_AGNOSTIC_CONDITIONS,
|
|
84
|
+
USE_AGNOSTIC_STRATEGIES,
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
/* from the getCommentedDirectiveFromImportedModule utility */
|
|
88
|
+
|
|
89
|
+
export const directivesArray = Array.from(directivesSet);
|
|
90
|
+
|
|
91
|
+
/* commentedDirectives_4RawImplementations */
|
|
92
|
+
|
|
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}" */`;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 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
|
|
103
|
+
*/
|
|
104
|
+
const make4RawImplementations = (directive) => [
|
|
105
|
+
makeRawCommentedDirectiveV1of4(directive),
|
|
106
|
+
makeRawCommentedDirectiveV2of4(directive),
|
|
107
|
+
makeRawCommentedDirectiveV3of4(directive),
|
|
108
|
+
makeRawCommentedDirectiveV4of4(directive),
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
// mapped commented directives to their 4 raw implementations
|
|
112
|
+
export const commentedDirectives_4RawImplementations = Object.freeze({
|
|
113
|
+
[USE_SERVER_LOGICS]: make4RawImplementations(USE_SERVER_LOGICS),
|
|
114
|
+
[USE_CLIENT_LOGICS]: make4RawImplementations(USE_CLIENT_LOGICS),
|
|
115
|
+
[USE_AGNOSTIC_LOGICS]: make4RawImplementations(USE_AGNOSTIC_LOGICS),
|
|
116
|
+
[USE_SERVER_COMPONENTS]: make4RawImplementations(USE_SERVER_COMPONENTS),
|
|
117
|
+
[USE_CLIENT_COMPONENTS]: make4RawImplementations(USE_CLIENT_COMPONENTS),
|
|
118
|
+
[USE_AGNOSTIC_COMPONENTS]: make4RawImplementations(USE_AGNOSTIC_COMPONENTS),
|
|
119
|
+
[USE_SERVER_FUNCTIONS]: make4RawImplementations(USE_SERVER_FUNCTIONS),
|
|
120
|
+
[USE_CLIENT_CONTEXTS]: make4RawImplementations(USE_CLIENT_CONTEXTS),
|
|
121
|
+
[USE_AGNOSTIC_CONDITIONS]: make4RawImplementations(USE_AGNOSTIC_CONDITIONS),
|
|
122
|
+
[USE_AGNOSTIC_STRATEGIES]: make4RawImplementations(USE_AGNOSTIC_STRATEGIES),
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// commented strategies
|
|
126
|
+
export const AT_SERVER_LOGICS = "@serverLogics";
|
|
127
|
+
export const AT_CLIENT_LOGICS = "@clientLogics";
|
|
128
|
+
export const AT_AGNOSTIC_LOGICS = "@agnosticLogics";
|
|
129
|
+
export const AT_SERVER_COMPONENTS = "@serverComponents";
|
|
130
|
+
export const AT_CLIENT_COMPONENTS = "@clientComponents";
|
|
131
|
+
export const AT_AGNOSTIC_COMPONENTS = "@agnosticComponents";
|
|
132
|
+
export const AT_SERVER_FUNCTIONS = "@serverFunctions";
|
|
133
|
+
export const AT_CLIENT_CONTEXTS = "@clientContexts";
|
|
134
|
+
export const AT_AGNOSTIC_CONDITIONS = "@agnosticConditions";
|
|
135
|
+
|
|
136
|
+
// mapped commented strategies to their commented directives
|
|
137
|
+
export const commentedStrategies_CommentedDirectives = Object.freeze({
|
|
138
|
+
[AT_SERVER_LOGICS]: USE_SERVER_LOGICS,
|
|
139
|
+
[AT_CLIENT_LOGICS]: USE_CLIENT_LOGICS,
|
|
140
|
+
[AT_AGNOSTIC_LOGICS]: USE_AGNOSTIC_LOGICS,
|
|
141
|
+
[AT_SERVER_COMPONENTS]: USE_SERVER_COMPONENTS,
|
|
142
|
+
[AT_CLIENT_COMPONENTS]: USE_CLIENT_COMPONENTS,
|
|
143
|
+
[AT_AGNOSTIC_COMPONENTS]: USE_AGNOSTIC_COMPONENTS,
|
|
144
|
+
[AT_SERVER_FUNCTIONS]: USE_SERVER_FUNCTIONS,
|
|
145
|
+
[AT_CLIENT_CONTEXTS]: USE_CLIENT_CONTEXTS,
|
|
146
|
+
[AT_AGNOSTIC_CONDITIONS]: USE_AGNOSTIC_CONDITIONS,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
/* from the isImportBlocked utility */
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Makes the intro for each specific import rule violation messages.
|
|
153
|
+
* @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
|
+
* @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]".
|
|
156
|
+
*/
|
|
157
|
+
const makeIntroForSpecificViolationMessage = (
|
|
158
|
+
currentFileCommentedDirective,
|
|
159
|
+
importedFileCommentedDirective
|
|
160
|
+
) =>
|
|
161
|
+
commonsMakeIntroForSpecificViolationMessage(
|
|
162
|
+
commentedDirectives_CommentedModules,
|
|
163
|
+
currentFileCommentedDirective,
|
|
164
|
+
importedFileCommentedDirective
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
export const commentedDirectives_BlockedImports = Object.freeze({
|
|
168
|
+
[USE_SERVER_LOGICS]: [
|
|
169
|
+
// USE_SERVER_LOGICS allowed, because Server Logics can compose with one another.
|
|
170
|
+
{
|
|
171
|
+
blockedImport: USE_CLIENT_LOGICS,
|
|
172
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
173
|
+
USE_SERVER_LOGICS,
|
|
174
|
+
USE_CLIENT_LOGICS
|
|
175
|
+
)} Client logic should never leak to the server.`,
|
|
176
|
+
},
|
|
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
|
+
{
|
|
180
|
+
blockedImport: USE_CLIENT_COMPONENTS,
|
|
181
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
182
|
+
USE_SERVER_LOGICS,
|
|
183
|
+
USE_CLIENT_COMPONENTS
|
|
184
|
+
)} Client Components cannot be tinkered with on the server.`,
|
|
185
|
+
},
|
|
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
|
+
{
|
|
189
|
+
blockedImport: USE_CLIENT_CONTEXTS,
|
|
190
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
191
|
+
USE_SERVER_LOGICS,
|
|
192
|
+
USE_CLIENT_CONTEXTS
|
|
193
|
+
)} Client Components cannot be tinkered with on the server, including Client Contexts Components.`,
|
|
194
|
+
},
|
|
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.
|
|
196
|
+
],
|
|
197
|
+
[USE_CLIENT_LOGICS]: [
|
|
198
|
+
{
|
|
199
|
+
blockedImport: USE_SERVER_LOGICS,
|
|
200
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
201
|
+
USE_CLIENT_LOGICS,
|
|
202
|
+
USE_SERVER_LOGICS
|
|
203
|
+
)} Server logic should never leak to the client.`,
|
|
204
|
+
},
|
|
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
|
+
{
|
|
208
|
+
blockedImport: USE_SERVER_COMPONENTS,
|
|
209
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
210
|
+
USE_CLIENT_LOGICS,
|
|
211
|
+
USE_SERVER_COMPONENTS
|
|
212
|
+
)} Server Components cannot be thinkered with on the client.`,
|
|
213
|
+
},
|
|
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.
|
|
219
|
+
],
|
|
220
|
+
[USE_AGNOSTIC_LOGICS]: [
|
|
221
|
+
{
|
|
222
|
+
blockedImport: USE_SERVER_LOGICS,
|
|
223
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
224
|
+
USE_AGNOSTIC_LOGICS,
|
|
225
|
+
USE_SERVER_LOGICS
|
|
226
|
+
)} Server Logic cannot run in both the server and the client.`,
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
blockedImport: USE_CLIENT_LOGICS,
|
|
230
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
231
|
+
USE_AGNOSTIC_LOGICS,
|
|
232
|
+
USE_CLIENT_LOGICS
|
|
233
|
+
)} Client Logic cannot run in both the server and the client.`,
|
|
234
|
+
},
|
|
235
|
+
// USE_AGNOSTIC_LOGICS allowed, because Agnostic Logics can compose with one another.
|
|
236
|
+
{
|
|
237
|
+
blockedImport: USE_SERVER_COMPONENTS,
|
|
238
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
239
|
+
USE_AGNOSTIC_LOGICS,
|
|
240
|
+
USE_SERVER_COMPONENTS
|
|
241
|
+
)} Server Components cannot be tinkered with on both the server and the client.`,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
blockedImport: USE_CLIENT_COMPONENTS,
|
|
245
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
246
|
+
USE_AGNOSTIC_LOGICS,
|
|
247
|
+
USE_CLIENT_COMPONENTS
|
|
248
|
+
)} Client Components cannot be tinkered with on both the server and the client.`,
|
|
249
|
+
},
|
|
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.
|
|
251
|
+
{
|
|
252
|
+
blockedImport: USE_SERVER_FUNCTIONS,
|
|
253
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
254
|
+
USE_AGNOSTIC_LOGICS,
|
|
255
|
+
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.`,
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
blockedImport: USE_CLIENT_CONTEXTS,
|
|
260
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
261
|
+
USE_AGNOSTIC_LOGICS,
|
|
262
|
+
USE_CLIENT_CONTEXTS
|
|
263
|
+
)} Client Components cannot be tinkered with on both the server and the client, including Client Contexts Components.`,
|
|
264
|
+
},
|
|
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.
|
|
266
|
+
],
|
|
267
|
+
[USE_SERVER_COMPONENTS]: [
|
|
268
|
+
// USE_SERVER_LOGICS allowed, because logic from the server can safely support Server Components.
|
|
269
|
+
{
|
|
270
|
+
blockedImport: USE_CLIENT_LOGICS,
|
|
271
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
272
|
+
USE_SERVER_COMPONENTS,
|
|
273
|
+
USE_CLIENT_LOGICS
|
|
274
|
+
)} Client logic should never leak to the server.`,
|
|
275
|
+
},
|
|
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.
|
|
283
|
+
],
|
|
284
|
+
[USE_CLIENT_COMPONENTS]: [
|
|
285
|
+
{
|
|
286
|
+
blockedImport: USE_SERVER_LOGICS,
|
|
287
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
288
|
+
USE_CLIENT_COMPONENTS,
|
|
289
|
+
USE_SERVER_LOGICS
|
|
290
|
+
)} Server logic should never leak to the client.`,
|
|
291
|
+
},
|
|
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
|
+
{
|
|
295
|
+
blockedImport: USE_SERVER_COMPONENTS,
|
|
296
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
297
|
+
USE_CLIENT_COMPONENTS,
|
|
298
|
+
USE_SERVER_COMPONENTS
|
|
299
|
+
)} Server Components cannot be the children of Lineal Client Components.`,
|
|
300
|
+
},
|
|
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.
|
|
306
|
+
],
|
|
307
|
+
[USE_AGNOSTIC_COMPONENTS]: [
|
|
308
|
+
{
|
|
309
|
+
blockedImport: USE_SERVER_LOGICS,
|
|
310
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
311
|
+
USE_AGNOSTIC_COMPONENTS,
|
|
312
|
+
USE_SERVER_LOGICS
|
|
313
|
+
)} Server Logic cannot run in both the server and the client.`,
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
blockedImport: USE_CLIENT_LOGICS,
|
|
317
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
318
|
+
USE_AGNOSTIC_COMPONENTS,
|
|
319
|
+
USE_CLIENT_LOGICS
|
|
320
|
+
)} Client Logic cannot run in both the server and the client.`,
|
|
321
|
+
},
|
|
322
|
+
// USE_AGNOSTIC_LOGICS allowed, because environment-agnostic logic can safely support Agnostic Components.
|
|
323
|
+
{
|
|
324
|
+
blockedImport: USE_SERVER_COMPONENTS,
|
|
325
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
326
|
+
USE_AGNOSTIC_COMPONENTS,
|
|
327
|
+
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.`,
|
|
329
|
+
},
|
|
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.
|
|
335
|
+
],
|
|
336
|
+
[USE_SERVER_FUNCTIONS]: [
|
|
337
|
+
// USE_SERVER_LOGICS allowed, because logic from the server can safely support Server Functions.
|
|
338
|
+
{
|
|
339
|
+
blockedImport: USE_CLIENT_LOGICS,
|
|
340
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
341
|
+
USE_SERVER_FUNCTIONS,
|
|
342
|
+
USE_CLIENT_LOGICS
|
|
343
|
+
)} Client logic should never leak to the server.`,
|
|
344
|
+
},
|
|
345
|
+
// USE_AGNOSTIC_LOGICS allowed, because Agnostic Logic can run safely on the server just like it can on the client.
|
|
346
|
+
{
|
|
347
|
+
blockedImport: USE_SERVER_COMPONENTS,
|
|
348
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
349
|
+
USE_SERVER_FUNCTIONS,
|
|
350
|
+
USE_SERVER_COMPONENTS
|
|
351
|
+
)} Server Functions have no business working with React Components.`,
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
blockedImport: USE_CLIENT_COMPONENTS,
|
|
355
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
356
|
+
USE_SERVER_FUNCTIONS,
|
|
357
|
+
USE_CLIENT_COMPONENTS
|
|
358
|
+
)} Server Functions have no business working with React Components.`,
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
blockedImport: USE_AGNOSTIC_COMPONENTS,
|
|
362
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
363
|
+
USE_SERVER_FUNCTIONS,
|
|
364
|
+
USE_AGNOSTIC_COMPONENTS
|
|
365
|
+
)} Server Functions have no business working with React Components.`,
|
|
366
|
+
},
|
|
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.
|
|
368
|
+
{
|
|
369
|
+
blockedImport: USE_CLIENT_CONTEXTS,
|
|
370
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
371
|
+
USE_SERVER_FUNCTIONS,
|
|
372
|
+
USE_CLIENT_CONTEXTS
|
|
373
|
+
)} Server Functions have no business working with React Components.`,
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
blockedImport: USE_AGNOSTIC_CONDITIONS,
|
|
377
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
378
|
+
USE_SERVER_FUNCTIONS,
|
|
379
|
+
USE_AGNOSTIC_CONDITIONS
|
|
380
|
+
)} Server Functions have no business working with React Components.`,
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
[USE_CLIENT_CONTEXTS]: [
|
|
384
|
+
{
|
|
385
|
+
blockedImport: USE_SERVER_LOGICS,
|
|
386
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
387
|
+
USE_CLIENT_CONTEXTS,
|
|
388
|
+
USE_SERVER_LOGICS
|
|
389
|
+
)} Server logic should never leak to the client.`,
|
|
390
|
+
},
|
|
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
|
+
{
|
|
394
|
+
blockedImport: USE_SERVER_COMPONENTS,
|
|
395
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
396
|
+
USE_CLIENT_CONTEXTS,
|
|
397
|
+
USE_SERVER_COMPONENTS
|
|
398
|
+
)} Server Components may only pass through Client Contexts Components through the children prop within Server Components Modules.`,
|
|
399
|
+
},
|
|
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.
|
|
405
|
+
],
|
|
406
|
+
[USE_AGNOSTIC_CONDITIONS]: [
|
|
407
|
+
{
|
|
408
|
+
blockedImport: USE_SERVER_LOGICS,
|
|
409
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
410
|
+
USE_AGNOSTIC_CONDITIONS,
|
|
411
|
+
USE_SERVER_LOGICS
|
|
412
|
+
)} Server Logic cannot run in both the server and the client.`,
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
blockedImport: USE_CLIENT_LOGICS,
|
|
416
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
417
|
+
USE_AGNOSTIC_CONDITIONS,
|
|
418
|
+
USE_CLIENT_LOGICS
|
|
419
|
+
)} Client Logic cannot run in both the server and the client.`,
|
|
420
|
+
},
|
|
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.
|
|
425
|
+
{
|
|
426
|
+
blockedImport: USE_SERVER_FUNCTIONS,
|
|
427
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
428
|
+
USE_AGNOSTIC_CONDITIONS,
|
|
429
|
+
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.`,
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
blockedImport: USE_CLIENT_CONTEXTS,
|
|
434
|
+
message: `${makeIntroForSpecificViolationMessage(
|
|
435
|
+
USE_AGNOSTIC_CONDITIONS,
|
|
436
|
+
USE_CLIENT_CONTEXTS
|
|
437
|
+
)} Agnostic Conditions Components only take Lineal Components as arguments in their making.`,
|
|
438
|
+
},
|
|
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.
|
|
440
|
+
],
|
|
441
|
+
[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.)
|
|
443
|
+
],
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
/* from the currentFileFlow flow */
|
|
447
|
+
|
|
448
|
+
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.)`,
|
|
460
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
reExportNotSameMessageId,
|
|
3
|
+
importBreaksCommentedImportRulesMessageId,
|
|
4
|
+
noCommentedDirective,
|
|
5
|
+
commentedDirectiveVerificationFailed,
|
|
6
|
+
importNotStrategized,
|
|
7
|
+
exportNotStrategized,
|
|
8
|
+
} from "../../_commons/constants/bases.js";
|
|
9
|
+
import {
|
|
10
|
+
currentFileCommentedDirective,
|
|
11
|
+
importedFileCommentedDirective,
|
|
12
|
+
commentedDirectiveMessage,
|
|
13
|
+
specificViolationMessage,
|
|
14
|
+
specificFailure,
|
|
15
|
+
} from "../constants/bases.js";
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
currentFileFlow,
|
|
19
|
+
importsFlow,
|
|
20
|
+
allExportsFlow,
|
|
21
|
+
} from "../utilities/flows.js";
|
|
22
|
+
|
|
23
|
+
/** @type {import('@typescript-eslint/utils').TSESLint.RuleModule<typeof reExportNotSameMessageId | typeof importBreaksCommentedImportRulesMessageId | typeof noCommentedDirective | typeof commentedDirectiveVerificationFailed | typeof importNotStrategized | typeof exportNotStrategized, []>} */
|
|
24
|
+
const rule = {
|
|
25
|
+
meta: {
|
|
26
|
+
type: "problem",
|
|
27
|
+
docs: {
|
|
28
|
+
description:
|
|
29
|
+
"Enforces import rules based on the file's commented directive. ",
|
|
30
|
+
},
|
|
31
|
+
schema: [],
|
|
32
|
+
// currentFileCommentedDirective, importedFileCommentedDirective, commentedDirectiveMessage, specificViolationMessage, specificFailure
|
|
33
|
+
messages: {
|
|
34
|
+
[reExportNotSameMessageId]: `The commented directives of this file (or Strategy) and this re-export are dissimilar.
|
|
35
|
+
Here, "{{ ${currentFileCommentedDirective} }}" and "{{ ${importedFileCommentedDirective} }}" are not the same. Please re-export only from modules that have the same commented directive as the current module. `,
|
|
36
|
+
[importBreaksCommentedImportRulesMessageId]: `{{ ${commentedDirectiveMessage} }}
|
|
37
|
+
In this case, {{ ${specificViolationMessage} }} `,
|
|
38
|
+
[noCommentedDirective]: `No commented directive detected.
|
|
39
|
+
All targeted modules need to be marked with their respective directives (\`// "use server logics"\`, etc.) for the purpose of this linting rule. `,
|
|
40
|
+
[commentedDirectiveVerificationFailed]: `The commented directive could not pass verification due to an incompatible combination with its file extension.
|
|
41
|
+
In this context, {{ ${specificFailure} }} `,
|
|
42
|
+
[importNotStrategized]: `Imports from Agnostic Strategies Modules must be strategized (\`/* @serverLogics */\`, etc.).
|
|
43
|
+
Please include a Strategy that corresponds to the kind of module this import would be mapped to. `,
|
|
44
|
+
[exportNotStrategized]: `Exports from Agnostic Strategies Modules must be strategized (\`/* @serverLogics */\`, etc.).
|
|
45
|
+
Please include a Strategy that corresponds to the kind of module this export would be mapped to. `,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
create: (context) => {
|
|
49
|
+
const result = currentFileFlow(context);
|
|
50
|
+
|
|
51
|
+
if (result.skip) return {};
|
|
52
|
+
const { verifiedCommentedDirective } = result;
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
ImportDeclaration: (node) =>
|
|
56
|
+
importsFlow(context, node, verifiedCommentedDirective),
|
|
57
|
+
ExportNamedDeclaration: (node) =>
|
|
58
|
+
allExportsFlow(context, node, verifiedCommentedDirective),
|
|
59
|
+
ExportAllDeclaration: (node) =>
|
|
60
|
+
allExportsFlow(context, node, verifiedCommentedDirective),
|
|
61
|
+
ExportDefaultDeclaration: (node) =>
|
|
62
|
+
allExportsFlow(context, node, verifiedCommentedDirective),
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default rule; // enforce-commented-directives-import-rules
|