eslint-plugin-use-agnostic 1.3.5 → 1.4.1
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/comments.config.js +13 -0
- package/comments.config.json +1 -1
- package/jscomments/jsdoc/comments.js +1 -1
- package/library/_commons/constants/bases.js +20 -1
- package/library/agnostic20/_commons/constants/bases.js +0 -5
- package/library/directive21/_commons/constants/bases.js +5 -3
- package/library/directive21/_commons/utilities/helpers.js +7 -5
- package/library/index.js +73 -0
- package/package.json +2 -2
- package/types/index.d.ts +468 -1
package/comments.config.js
CHANGED
|
@@ -12,9 +12,22 @@ export const data = Object.freeze({
|
|
|
12
12
|
|
|
13
13
|
const ignores = [];
|
|
14
14
|
|
|
15
|
+
const composedVariablesExclusives = [
|
|
16
|
+
"JSDOC#FORCOMPOSEDVARIABLES#AGNOSTIC20",
|
|
17
|
+
"JSDOC#FORCOMPOSEDVARIABLES#DIRECTIVE21",
|
|
18
|
+
"JSDOC#FORCOMPOSEDVARIABLES#RESOLVED",
|
|
19
|
+
"JSDOC#FORCOMPOSEDVARIABLES#EFFECTIVE",
|
|
20
|
+
"JSDOC#FORCOMPOSEDVARIABLES#COMMENTED",
|
|
21
|
+
"JSDOC#FORCOMPOSEDVARIABLES#DIRECTIVE",
|
|
22
|
+
"JSDOC#FORCOMPOSEDVARIABLES#DIRECTIVES",
|
|
23
|
+
"JSDOC#FORCOMPOSEDVARIABLES#INITIALTHE",
|
|
24
|
+
"TESTS#FORCOMPOSEDVARIABLES#MODULE",
|
|
25
|
+
];
|
|
26
|
+
|
|
15
27
|
const config = {
|
|
16
28
|
data,
|
|
17
29
|
ignores,
|
|
30
|
+
composedVariablesExclusives,
|
|
18
31
|
};
|
|
19
32
|
|
|
20
33
|
export default config;
|
package/comments.config.json
CHANGED
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
"placeholder": "$COMMENT#JSDOC#DEFINITIONS#DIRECTIVE21#GETVERIFIEDCOMMENTEDDIRECTIVE"
|
|
166
166
|
},
|
|
167
167
|
"getStrategizedDirective": {
|
|
168
|
-
"value": "Gets the interpreted directive from a specified commented Strategy (such as `@serverLogics`) nested inside the import declaration for an import from an Agnostic Strategies Module.",
|
|
168
|
+
"value": "Gets the interpreted directive from a specified commented Strategy (such as `@serverLogics`) nested inside the import (or export) declaration for an import (or export) from an Agnostic Strategies Module.",
|
|
169
169
|
"key": "JSDOC#DEFINITIONS#DIRECTIVE21#GETSTRATEGIZEDDIRECTIVE",
|
|
170
170
|
"placeholder": "$COMMENT#JSDOC#DEFINITIONS#DIRECTIVE21#GETSTRATEGIZEDDIRECTIVE"
|
|
171
171
|
},
|
|
@@ -71,7 +71,7 @@ export const jsDocComments = Object.freeze({
|
|
|
71
71
|
getVerifiedCommentedDirective:
|
|
72
72
|
"Ensures that a module's commented directive is consistent with its file extension (depending on whether it ends with 'x' for JSX)." /* $COMMENT#JSDOC#DEFINITIONS#DIRECTIVE21#GETVERIFIEDCOMMENTEDDIRECTIVE */,
|
|
73
73
|
getStrategizedDirective:
|
|
74
|
-
"Gets the interpreted directive from a specified commented Strategy (such as `@serverLogics`) nested inside the import declaration for an import from an Agnostic Strategies Module." /* $COMMENT#JSDOC#DEFINITIONS#DIRECTIVE21#GETSTRATEGIZEDDIRECTIVE */,
|
|
74
|
+
"Gets the interpreted directive from a specified commented Strategy (such as `@serverLogics`) nested inside the import (or export) declaration for an import (or export) from an Agnostic Strategies Module." /* $COMMENT#JSDOC#DEFINITIONS#DIRECTIVE21#GETSTRATEGIZEDDIRECTIVE */,
|
|
75
75
|
addressDirectiveIfAgnosticStrategies:
|
|
76
76
|
'Verifies the current node\'s export strategy if the current commented directive is `"use agnostic strategies"` by reporting `exportNotStrategized` in case an export is not strategized in an Agnostic Strategies Module.' /* $COMMENT#JSDOC#DEFINITIONS#DIRECTIVE21#ADDRESSDIRECTIVEIFAGNOSTICSTRATEGIES */,
|
|
77
77
|
isImportBlocked:
|
|
@@ -104,14 +104,33 @@ export const resolvedDirectives_resolvedModules =
|
|
|
104
104
|
// JavaScript/TypeScript extensions
|
|
105
105
|
export const TSX = ".tsx";
|
|
106
106
|
export const TS = ".ts";
|
|
107
|
+
export const MTSX = ".mtsx";
|
|
108
|
+
export const MTS = ".mts";
|
|
109
|
+
export const CTSX = ".ctsx";
|
|
110
|
+
export const CTS = ".cts";
|
|
107
111
|
export const JSX = ".jsx";
|
|
108
112
|
export const JS = ".js";
|
|
113
|
+
export const MJSX = ".mjsx";
|
|
109
114
|
export const MJS = ".mjs";
|
|
115
|
+
export const CJSX = ".cjsx";
|
|
110
116
|
export const CJS = ".cjs";
|
|
111
117
|
|
|
112
118
|
// JavaScript/TypeScript extensions array
|
|
113
119
|
/** @type {Extensions} */
|
|
114
|
-
export const EXTENSIONS = Object.freeze([
|
|
120
|
+
export const EXTENSIONS = Object.freeze([
|
|
121
|
+
TSX,
|
|
122
|
+
TS,
|
|
123
|
+
MTSX,
|
|
124
|
+
MTS,
|
|
125
|
+
CTSX,
|
|
126
|
+
CTS,
|
|
127
|
+
JSX,
|
|
128
|
+
JS,
|
|
129
|
+
MJSX,
|
|
130
|
+
MJS,
|
|
131
|
+
CJSX,
|
|
132
|
+
CJS,
|
|
133
|
+
]); // In priority order
|
|
115
134
|
|
|
116
135
|
// message strings
|
|
117
136
|
export const ARE_NOT_ALLOWED_TO_IMPORT = "are not allowed to import";
|
|
@@ -138,11 +138,6 @@ const makeBlockedImportSuggestingUseAgnostic = (
|
|
|
138
138
|
});
|
|
139
139
|
};
|
|
140
140
|
|
|
141
|
-
// The final boss is going to be to building this from the config.
|
|
142
|
-
// Probably in the blocked import thing.
|
|
143
|
-
// But so that means I'm going to need using resolveConfig, or maybe I could give resolveConfig an option that allows it to return the actual config data with all values recursively resolved.
|
|
144
|
-
// That's what I would do, then I would just need to use the object of the config data instead of `jscommentsConfig[agnostic20ConfigName]` for makeBlockedImport.
|
|
145
|
-
// const jscommentsConfigData = makeResolvedConfig(configPath)
|
|
146
141
|
export const effectiveDirectives_blockedImports = Object.freeze({
|
|
147
142
|
[USE_SERVER_LOGICS]: Object.freeze([
|
|
148
143
|
// USE_SERVER_LOGICS allowed, because Server Logics can compose with one another.
|
|
@@ -67,7 +67,9 @@ export const commentedDirectives_extensionRules = Object.freeze({
|
|
|
67
67
|
[USE_SERVER_FUNCTIONS]: false,
|
|
68
68
|
[USE_CLIENT_CONTEXTS]: true,
|
|
69
69
|
[USE_AGNOSTIC_CONDITIONS]: true,
|
|
70
|
-
|
|
70
|
+
// CHANGE: Agnostic Strategies Modules must now be JSX modules (ending in `x`) in order to conform with eXtra JSX, and moreover to assert their capacity to adapt with both logics and components.
|
|
71
|
+
// [USE_AGNOSTIC_STRATEGIES]: null, // Any extension allowed
|
|
72
|
+
[USE_AGNOSTIC_STRATEGIES]: true,
|
|
71
73
|
});
|
|
72
74
|
|
|
73
75
|
// commented strategies
|
|
@@ -83,7 +85,7 @@ export const AT_AGNOSTIC_CONDITIONS = "@agnosticConditions";
|
|
|
83
85
|
|
|
84
86
|
// commented strategies array
|
|
85
87
|
/** @type {CommentedStrategies} */
|
|
86
|
-
export const
|
|
88
|
+
export const commentedStrategiesArray = Object.freeze([
|
|
87
89
|
AT_SERVER_LOGICS,
|
|
88
90
|
AT_CLIENT_LOGICS,
|
|
89
91
|
AT_AGNOSTIC_LOGICS,
|
|
@@ -97,7 +99,7 @@ export const strategiesArray = Object.freeze([
|
|
|
97
99
|
|
|
98
100
|
// commented strategies set
|
|
99
101
|
/** @type {ReadonlySet<CommentedStrategy>} */
|
|
100
|
-
export const
|
|
102
|
+
export const commentedStrategiesSet = new Set(commentedStrategiesArray); // no longer used exported to satisfy static type inference
|
|
101
103
|
|
|
102
104
|
// mapped commented strategies to their commented directives
|
|
103
105
|
export const commentedStrategies_commentedDirectives = Object.freeze({
|
|
@@ -4,7 +4,7 @@ import { exportNotStrategized } from "../../../_commons/constants/bases.js";
|
|
|
4
4
|
import {
|
|
5
5
|
USE_AGNOSTIC_STRATEGIES,
|
|
6
6
|
commentedDirectivesArray,
|
|
7
|
-
|
|
7
|
+
commentedStrategiesArray,
|
|
8
8
|
commentedDirectives_extensionRules,
|
|
9
9
|
commentedStrategies_commentedDirectives,
|
|
10
10
|
commentedDirectives_blockedImports,
|
|
@@ -201,7 +201,8 @@ export const getVerifiedCommentedDirective = (directive, extension) => {
|
|
|
201
201
|
|
|
202
202
|
if (rule === true && isExtensionJSX) return directive; // requires JSX extension
|
|
203
203
|
if (rule === false && !isExtensionJSX) return directive; // forbids JSX extension
|
|
204
|
-
|
|
204
|
+
// CHANGE: no longer applies, Agnostic Strategies Modules are now required to ends in `x`.
|
|
205
|
+
// if (rule === null) return directive; // no extension constraint, specifically for "use agnostic strategies"
|
|
205
206
|
|
|
206
207
|
return null; // verification failed
|
|
207
208
|
};
|
|
@@ -209,9 +210,9 @@ export const getVerifiedCommentedDirective = (directive, extension) => {
|
|
|
209
210
|
/* getStrategizedDirective */
|
|
210
211
|
|
|
211
212
|
/**
|
|
212
|
-
* Gets the interpreted directive from a specified commented Strategy (such as `@serverLogics`) nested inside the import declaration for an import from an Agnostic Strategies Module.
|
|
213
|
+
* Gets the interpreted directive from a specified commented Strategy (such as `@serverLogics`) nested inside the import (or export) declaration for an import (or export) from an Agnostic Strategies Module.
|
|
213
214
|
* @param {Context} context The ESLint rule's `context` object.
|
|
214
|
-
* @param {ImportDeclaration} node The ESLint `node` of the rule's current traversal.
|
|
215
|
+
* @param {ImportDeclaration | ExportNamedDeclaration | ExportAllDeclaration | ExportDefaultDeclaration} node The ESLint `node` of the rule's current traversal.
|
|
215
216
|
* @returns The interpreted directive, a.k.a. strategized directive, or lack thereof via `null`.
|
|
216
217
|
*/
|
|
217
218
|
export const getStrategizedDirective = (context, node) => {
|
|
@@ -226,7 +227,8 @@ export const getStrategizedDirective = (context, node) => {
|
|
|
226
227
|
|
|
227
228
|
// asserts whether that first nested comment is or isn't a Strategy
|
|
228
229
|
const strategy =
|
|
229
|
-
|
|
230
|
+
commentedStrategiesArray.find((strategy) => strategy === rawStrategy) ??
|
|
231
|
+
null;
|
|
230
232
|
|
|
231
233
|
// returns null early if no strategy was identified
|
|
232
234
|
if (!strategy) return null;
|
package/library/index.js
CHANGED
|
@@ -45,3 +45,76 @@ export {
|
|
|
45
45
|
enforceEffectiveDirectivesRuleName,
|
|
46
46
|
enforceCommentedDirectivesRuleName,
|
|
47
47
|
} from "./_commons/constants/bases.js";
|
|
48
|
+
|
|
49
|
+
// NEW: eslint-plugin-use-agnostic is effectively the premier implementation of the Directive-First Architecture. As such, the following imports are to access its constants and utilities across other implementations of the Directive-First Architecture, such as eXtra JSX.
|
|
50
|
+
|
|
51
|
+
// agnostic20
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
// directives
|
|
55
|
+
NO_DIRECTIVE,
|
|
56
|
+
USE_SERVER,
|
|
57
|
+
USE_CLIENT,
|
|
58
|
+
USE_AGNOSTIC,
|
|
59
|
+
// directives array
|
|
60
|
+
directivesArray,
|
|
61
|
+
// directives set
|
|
62
|
+
directivesSet,
|
|
63
|
+
// mapping directives with effective directives
|
|
64
|
+
directives_effectiveDirectives,
|
|
65
|
+
} from "./agnostic20/_commons/constants/bases.js";
|
|
66
|
+
|
|
67
|
+
export {
|
|
68
|
+
getDirectiveFromModule,
|
|
69
|
+
getDirectiveFromCurrentModule,
|
|
70
|
+
getDirectiveFromImportedModule,
|
|
71
|
+
getEffectiveDirective,
|
|
72
|
+
isImportBlocked as isImportBlockedAgnostic20,
|
|
73
|
+
} from "./agnostic20/_commons/utilities/helpers.js";
|
|
74
|
+
|
|
75
|
+
// directive21
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
// commented directives
|
|
79
|
+
USE_SERVER_LOGICS,
|
|
80
|
+
USE_CLIENT_LOGICS,
|
|
81
|
+
USE_AGNOSTIC_LOGICS,
|
|
82
|
+
USE_SERVER_COMPONENTS,
|
|
83
|
+
USE_CLIENT_COMPONENTS,
|
|
84
|
+
USE_AGNOSTIC_COMPONENTS,
|
|
85
|
+
USE_SERVER_FUNCTIONS,
|
|
86
|
+
USE_CLIENT_CONTEXTS,
|
|
87
|
+
USE_AGNOSTIC_CONDITIONS,
|
|
88
|
+
USE_AGNOSTIC_STRATEGIES,
|
|
89
|
+
// commented directives array
|
|
90
|
+
commentedDirectivesArray,
|
|
91
|
+
// commented directives set
|
|
92
|
+
commentedDirectivesSet,
|
|
93
|
+
// mapped commented directives to their extension rules
|
|
94
|
+
commentedDirectives_extensionRules,
|
|
95
|
+
// commented strategies
|
|
96
|
+
AT_SERVER_LOGICS,
|
|
97
|
+
AT_CLIENT_LOGICS,
|
|
98
|
+
AT_AGNOSTIC_LOGICS,
|
|
99
|
+
AT_SERVER_COMPONENTS,
|
|
100
|
+
AT_CLIENT_COMPONENTS,
|
|
101
|
+
AT_AGNOSTIC_COMPONENTS,
|
|
102
|
+
AT_SERVER_FUNCTIONS,
|
|
103
|
+
AT_CLIENT_CONTEXTS,
|
|
104
|
+
AT_AGNOSTIC_CONDITIONS,
|
|
105
|
+
// commented strategies array
|
|
106
|
+
commentedStrategiesArray,
|
|
107
|
+
// commented strategies set
|
|
108
|
+
commentedStrategiesSet,
|
|
109
|
+
// mapped commented strategies to their commented directives
|
|
110
|
+
commentedStrategies_commentedDirectives,
|
|
111
|
+
} from "./directive21/_commons/constants/bases.js";
|
|
112
|
+
|
|
113
|
+
export {
|
|
114
|
+
getCommentedDirectiveFromSourceCode,
|
|
115
|
+
getCommentedDirectiveFromCurrentModule,
|
|
116
|
+
getCommentedDirectiveFromImportedModule,
|
|
117
|
+
getVerifiedCommentedDirective,
|
|
118
|
+
getStrategizedDirective,
|
|
119
|
+
isImportBlocked as isImportBlockedDirective21,
|
|
120
|
+
} from "./directive21/_commons/utilities/helpers.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-use-agnostic",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Highlights problematic server-client imports in projects made with the Fullstack React Architecture.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"get-sourcecode-from-file-path": "^1.1.2",
|
|
46
46
|
"resolve-importing-path": "^1.0.3",
|
|
47
|
-
"tsconfig-paths": "^4.2.0",
|
|
48
47
|
"typescript-eslint": "^8.32.0"
|
|
49
48
|
},
|
|
50
49
|
"devDependencies": {
|
|
51
50
|
"@typescript-eslint/utils": "^8.31.1",
|
|
52
51
|
"eslint": ">=9.0.0",
|
|
52
|
+
"tsconfig-paths": "^4.2.0",
|
|
53
53
|
"typescript": "^5.8.3"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
package/types/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type { ESLint } from "eslint";
|
|
1
|
+
import type { ESLint, SourceCode as ESLintSourceCode } from "eslint";
|
|
2
|
+
import type {
|
|
3
|
+
SourceCode as TSESLintSourceCode,
|
|
4
|
+
RuleContext,
|
|
5
|
+
} from "@typescript-eslint/utils/dist/ts-eslint";
|
|
6
|
+
import type { TSESTree } from "@typescript-eslint/types";
|
|
2
7
|
|
|
3
8
|
declare const plugin: ESLint.Plugin;
|
|
4
9
|
|
|
@@ -10,3 +15,465 @@ export const agnostic20ConfigName: "agnostic20";
|
|
|
10
15
|
export const directive21ConfigName: "directive21";
|
|
11
16
|
export const enforceEffectiveDirectivesRuleName: "enforce-effective-directives-import-rules";
|
|
12
17
|
export const enforceCommentedDirectivesRuleName: "enforce-commented-directives-import-rules";
|
|
18
|
+
|
|
19
|
+
// NEW
|
|
20
|
+
|
|
21
|
+
// agnostic20
|
|
22
|
+
|
|
23
|
+
// directives
|
|
24
|
+
export const NO_DIRECTIVE: "no directive";
|
|
25
|
+
export const USE_SERVER: "use server";
|
|
26
|
+
export const USE_CLIENT: "use client";
|
|
27
|
+
export const USE_AGNOSTIC: "use agnostic";
|
|
28
|
+
|
|
29
|
+
// directives array
|
|
30
|
+
export const directivesArray: readonly [
|
|
31
|
+
typeof USE_SERVER,
|
|
32
|
+
typeof USE_CLIENT,
|
|
33
|
+
typeof USE_AGNOSTIC
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// directives set
|
|
37
|
+
export const directivesSet: ReadonlySet<
|
|
38
|
+
typeof USE_SERVER | typeof USE_CLIENT | typeof USE_AGNOSTIC
|
|
39
|
+
>;
|
|
40
|
+
|
|
41
|
+
// mapping directives with effective directives
|
|
42
|
+
export const directives_effectiveDirectives: Readonly<{
|
|
43
|
+
[NO_DIRECTIVE]: Readonly<{
|
|
44
|
+
logics: "use server logics";
|
|
45
|
+
components: "use server components";
|
|
46
|
+
functions: null;
|
|
47
|
+
}>;
|
|
48
|
+
[USE_SERVER]: Readonly<{
|
|
49
|
+
logics: null;
|
|
50
|
+
components: null;
|
|
51
|
+
functions: "use server functions";
|
|
52
|
+
}>;
|
|
53
|
+
[USE_CLIENT]: Readonly<{
|
|
54
|
+
logics: "use client logics";
|
|
55
|
+
components: "use client components";
|
|
56
|
+
functions: null;
|
|
57
|
+
}>;
|
|
58
|
+
[USE_AGNOSTIC]: Readonly<{
|
|
59
|
+
logics: "use agnostic logics";
|
|
60
|
+
components: "use agnostic components";
|
|
61
|
+
functions: null;
|
|
62
|
+
}>;
|
|
63
|
+
}>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Gets the directive of a module from its Abstract Syntax Tree.
|
|
67
|
+
* - `null` denotes a server-by-default module, ideally a Server Module.
|
|
68
|
+
* - `'use server'` denotes a Server Functions Module.
|
|
69
|
+
* - `'use client'` denotes a Client Module.
|
|
70
|
+
* - `'use agnostic'` denotes an Agnostic Module (formerly Shared Module).
|
|
71
|
+
* @param ast The module's AST (Abstract Syntax Tree).
|
|
72
|
+
* @returns The directive, or lack thereof via `null`. The lack of a directive is considered server-by-default.
|
|
73
|
+
*/
|
|
74
|
+
export const getDirectiveFromModule: (
|
|
75
|
+
ast: TSESLintSourceCode.Program
|
|
76
|
+
) => "use server" | "use client" | "use agnostic" | null;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Gets the directive of the current module.
|
|
80
|
+
* - `null` denotes a server-by-default module, ideally a Server Module.
|
|
81
|
+
* - `'use server'` denotes a Server Functions Module.
|
|
82
|
+
* - `'use client'` denotes a Client Module.
|
|
83
|
+
* - `'use agnostic'` denotes an Agnostic Module (formerly Shared Module).
|
|
84
|
+
* @param context The ESLint rule's `context` object.
|
|
85
|
+
* @returns The directive, or lack thereof via `null`. The lack of a directive is considered server-by-default.
|
|
86
|
+
*/
|
|
87
|
+
export const getDirectiveFromCurrentModule: (
|
|
88
|
+
context: RuleContext<string, readonly unknown[]>
|
|
89
|
+
) => "use server" | "use client" | "use agnostic" | null;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Gets the directive of the imported module.
|
|
93
|
+
* - `null` denotes a server-by-default module, ideally a Server Module.
|
|
94
|
+
* - `'use server'` denotes a Server Functions Module.
|
|
95
|
+
* - `'use client'` denotes a Client Module.
|
|
96
|
+
* - `'use agnostic'` denotes an Agnostic Module (formerly Shared Module).
|
|
97
|
+
* @param resolvedPath The resolved path of the imported module.
|
|
98
|
+
* @returns The directive, or lack thereof via `null`. The lack of a directive is considered server-by-default.
|
|
99
|
+
*/
|
|
100
|
+
export const getDirectiveFromImportedModule: (
|
|
101
|
+
resolvedPath: string
|
|
102
|
+
) => "use server" | "use client" | "use agnostic" | null;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Gets the effective directive of a module, based on the combination of its directive (or lack thereof) and its extension (depending on whether it ends with 'x' for JSX).
|
|
106
|
+
* - `'use server logics'` denotes a Server Logics Module.
|
|
107
|
+
* - `'use server components'` denotes a Server Components Module.
|
|
108
|
+
* - `'use server functions'` denotes a Server Functions Module.
|
|
109
|
+
* - `'use client logics'` denotes a Client Logics Module.
|
|
110
|
+
* - `'use client components'` denotes a Client Components Module.
|
|
111
|
+
* - `'use agnostic logics'` denotes an Agnostic Logics Module.
|
|
112
|
+
* - `'use agnostic components'` denotes an Agnostic Components Module.
|
|
113
|
+
* @param directive The directive as written on top of the file (`"no directive"` if no valid directive).
|
|
114
|
+
* @param extension The JavaScript (TypeScript) extension of the file.
|
|
115
|
+
* @returns The effective directive, from which imports rules are applied.
|
|
116
|
+
*/
|
|
117
|
+
export const getEffectiveDirective: (
|
|
118
|
+
directive: "use server" | "use client" | "use agnostic" | "no directive",
|
|
119
|
+
extension:
|
|
120
|
+
| ".tsx"
|
|
121
|
+
| ".ts"
|
|
122
|
+
| ".mtsx"
|
|
123
|
+
| ".mts"
|
|
124
|
+
| ".ctsx"
|
|
125
|
+
| ".cts"
|
|
126
|
+
| ".jsx"
|
|
127
|
+
| ".js"
|
|
128
|
+
| ".mjsx"
|
|
129
|
+
| ".mjs"
|
|
130
|
+
| ".cjsx"
|
|
131
|
+
| ".cjs"
|
|
132
|
+
) =>
|
|
133
|
+
| "use server logics"
|
|
134
|
+
| "use server components"
|
|
135
|
+
| "use server functions"
|
|
136
|
+
| "use client logics"
|
|
137
|
+
| "use client components"
|
|
138
|
+
| "use agnostic logics"
|
|
139
|
+
| "use agnostic components"
|
|
140
|
+
| null;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Returns a boolean deciding if an imported file's effective directive is incompatible with the current file's effective directive.
|
|
144
|
+
* @param currentFileEffectiveDirective The current file's effective directive.
|
|
145
|
+
* @param importedFileEffectiveDirective The imported file's effective directive.
|
|
146
|
+
* @returns `true` if the import is blocked, as established in `effectiveDirectives_BlockedImports`.
|
|
147
|
+
*/
|
|
148
|
+
export const isImportBlockedAgnostic20: (
|
|
149
|
+
currentFileEffectiveDirective:
|
|
150
|
+
| "use server logics"
|
|
151
|
+
| "use server components"
|
|
152
|
+
| "use server functions"
|
|
153
|
+
| "use client logics"
|
|
154
|
+
| "use client components"
|
|
155
|
+
| "use agnostic logics"
|
|
156
|
+
| "use agnostic components",
|
|
157
|
+
importedFileEffectiveDirective:
|
|
158
|
+
| "use server logics"
|
|
159
|
+
| "use server components"
|
|
160
|
+
| "use server functions"
|
|
161
|
+
| "use client logics"
|
|
162
|
+
| "use client components"
|
|
163
|
+
| "use agnostic logics"
|
|
164
|
+
| "use agnostic components"
|
|
165
|
+
) => boolean;
|
|
166
|
+
|
|
167
|
+
// directive21
|
|
168
|
+
|
|
169
|
+
// commented directives
|
|
170
|
+
export const USE_SERVER_LOGICS: "use server logics";
|
|
171
|
+
export const USE_CLIENT_LOGICS: "use client logics";
|
|
172
|
+
export const USE_AGNOSTIC_LOGICS: "use agnostic logics";
|
|
173
|
+
export const USE_SERVER_COMPONENTS: "use server components";
|
|
174
|
+
export const USE_CLIENT_COMPONENTS: "use client components";
|
|
175
|
+
export const USE_AGNOSTIC_COMPONENTS: "use agnostic components";
|
|
176
|
+
export const USE_SERVER_FUNCTIONS: "use server functions";
|
|
177
|
+
export const USE_CLIENT_CONTEXTS: "use client contexts";
|
|
178
|
+
export const USE_AGNOSTIC_CONDITIONS: "use agnostic conditions";
|
|
179
|
+
export const USE_AGNOSTIC_STRATEGIES: "use agnostic strategies";
|
|
180
|
+
|
|
181
|
+
// commented directives array
|
|
182
|
+
export const commentedDirectivesArray: readonly [
|
|
183
|
+
typeof USE_SERVER_LOGICS,
|
|
184
|
+
typeof USE_CLIENT_LOGICS,
|
|
185
|
+
typeof USE_AGNOSTIC_LOGICS,
|
|
186
|
+
typeof USE_SERVER_COMPONENTS,
|
|
187
|
+
typeof USE_CLIENT_COMPONENTS,
|
|
188
|
+
typeof USE_AGNOSTIC_COMPONENTS,
|
|
189
|
+
typeof USE_SERVER_FUNCTIONS,
|
|
190
|
+
typeof USE_CLIENT_CONTEXTS,
|
|
191
|
+
typeof USE_AGNOSTIC_CONDITIONS,
|
|
192
|
+
typeof USE_AGNOSTIC_STRATEGIES
|
|
193
|
+
];
|
|
194
|
+
|
|
195
|
+
// commented directives set
|
|
196
|
+
export const commentedDirectivesSet: ReadonlySet<
|
|
197
|
+
| typeof USE_SERVER_LOGICS
|
|
198
|
+
| typeof USE_CLIENT_LOGICS
|
|
199
|
+
| typeof USE_AGNOSTIC_LOGICS
|
|
200
|
+
| typeof USE_SERVER_COMPONENTS
|
|
201
|
+
| typeof USE_CLIENT_COMPONENTS
|
|
202
|
+
| typeof USE_AGNOSTIC_COMPONENTS
|
|
203
|
+
| typeof USE_SERVER_FUNCTIONS
|
|
204
|
+
| typeof USE_CLIENT_CONTEXTS
|
|
205
|
+
| typeof USE_AGNOSTIC_CONDITIONS
|
|
206
|
+
| typeof USE_AGNOSTIC_STRATEGIES
|
|
207
|
+
>;
|
|
208
|
+
|
|
209
|
+
// mapped commented directives to their extension rules
|
|
210
|
+
/**
|
|
211
|
+
* - `true` means requires the presence of a JSX extension (`.jsx`)
|
|
212
|
+
* - `false` means requires the absence of a JSX extension (`.js`)
|
|
213
|
+
* */
|
|
214
|
+
export const commentedDirectives_extensionRules: Readonly<{
|
|
215
|
+
[USE_SERVER_LOGICS]: false;
|
|
216
|
+
[USE_CLIENT_LOGICS]: false;
|
|
217
|
+
[USE_AGNOSTIC_LOGICS]: false;
|
|
218
|
+
[USE_SERVER_COMPONENTS]: true;
|
|
219
|
+
[USE_CLIENT_COMPONENTS]: true;
|
|
220
|
+
[USE_AGNOSTIC_COMPONENTS]: true;
|
|
221
|
+
[USE_SERVER_FUNCTIONS]: false;
|
|
222
|
+
[USE_CLIENT_CONTEXTS]: true;
|
|
223
|
+
[USE_AGNOSTIC_CONDITIONS]: true;
|
|
224
|
+
[USE_AGNOSTIC_STRATEGIES]: true;
|
|
225
|
+
}>;
|
|
226
|
+
|
|
227
|
+
// commented strategies
|
|
228
|
+
export const AT_SERVER_LOGICS: "@serverLogics";
|
|
229
|
+
export const AT_CLIENT_LOGICS: "@clientLogics";
|
|
230
|
+
export const AT_AGNOSTIC_LOGICS: "@agnosticLogics";
|
|
231
|
+
export const AT_SERVER_COMPONENTS: "@serverComponents";
|
|
232
|
+
export const AT_CLIENT_COMPONENTS: "@clientComponents";
|
|
233
|
+
export const AT_AGNOSTIC_COMPONENTS: "@agnosticComponents";
|
|
234
|
+
export const AT_SERVER_FUNCTIONS: "@serverFunctions";
|
|
235
|
+
export const AT_CLIENT_CONTEXTS: "@clientContexts";
|
|
236
|
+
export const AT_AGNOSTIC_CONDITIONS: "@agnosticConditions";
|
|
237
|
+
|
|
238
|
+
// commented strategies array
|
|
239
|
+
export const commentedStrategiesArray: readonly [
|
|
240
|
+
typeof AT_SERVER_LOGICS,
|
|
241
|
+
typeof AT_CLIENT_LOGICS,
|
|
242
|
+
typeof AT_AGNOSTIC_LOGICS,
|
|
243
|
+
typeof AT_SERVER_COMPONENTS,
|
|
244
|
+
typeof AT_CLIENT_COMPONENTS,
|
|
245
|
+
typeof AT_AGNOSTIC_COMPONENTS,
|
|
246
|
+
typeof AT_SERVER_FUNCTIONS,
|
|
247
|
+
typeof AT_CLIENT_CONTEXTS,
|
|
248
|
+
typeof AT_AGNOSTIC_CONDITIONS
|
|
249
|
+
];
|
|
250
|
+
|
|
251
|
+
// commented strategies set
|
|
252
|
+
export const commentedStrategiesSet: ReadonlySet<
|
|
253
|
+
| typeof AT_SERVER_LOGICS
|
|
254
|
+
| typeof AT_CLIENT_LOGICS
|
|
255
|
+
| typeof AT_AGNOSTIC_LOGICS
|
|
256
|
+
| typeof AT_SERVER_COMPONENTS
|
|
257
|
+
| typeof AT_CLIENT_COMPONENTS
|
|
258
|
+
| typeof AT_AGNOSTIC_COMPONENTS
|
|
259
|
+
| typeof AT_SERVER_FUNCTIONS
|
|
260
|
+
| typeof AT_CLIENT_CONTEXTS
|
|
261
|
+
| typeof AT_AGNOSTIC_CONDITIONS
|
|
262
|
+
>;
|
|
263
|
+
|
|
264
|
+
// mapped commented strategies to their commented directives
|
|
265
|
+
export const commentedStrategies_commentedDirectives: Readonly<{
|
|
266
|
+
[AT_SERVER_LOGICS]: "use server logics";
|
|
267
|
+
[AT_CLIENT_LOGICS]: "use client logics";
|
|
268
|
+
[AT_AGNOSTIC_LOGICS]: "use agnostic logics";
|
|
269
|
+
[AT_SERVER_COMPONENTS]: "use server components";
|
|
270
|
+
[AT_CLIENT_COMPONENTS]: "use client components";
|
|
271
|
+
[AT_AGNOSTIC_COMPONENTS]: "use agnostic components";
|
|
272
|
+
[AT_SERVER_FUNCTIONS]: "use server functions";
|
|
273
|
+
[AT_CLIENT_CONTEXTS]: "use client contexts";
|
|
274
|
+
[AT_AGNOSTIC_CONDITIONS]: "use agnostic conditions";
|
|
275
|
+
}>;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Gets the commented directive of a module from its ESLint `SourceCode` object.
|
|
279
|
+
*
|
|
280
|
+
* Accepted directives for the default Directive-First Architecture are (single or double quotes included):
|
|
281
|
+
* - `'use server logics'`, `"use server logics"` denoting a Server Logics Module.
|
|
282
|
+
* - `'use client logics'`, `"use client logics"` denoting a Client Logics Module.
|
|
283
|
+
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
284
|
+
* - `'use server components'`, `"use server components"` denoting a Server Components Module.
|
|
285
|
+
* - `'use client components'`, `"use client components"` denoting a Client Components Module.
|
|
286
|
+
* - `'use agnostic components'`, `"use agnostic components"` denoting an Agnostic Components Module.
|
|
287
|
+
* - `'use server functions'`, `"use server functions"` denoting a Server Functions Module.
|
|
288
|
+
* - `'use client contexts'`, `"use client contexts"` denoting a Client Contexts Module.
|
|
289
|
+
* - `'use agnostic conditions'`, `"use agnostic conditions"` denoting an Agnostic Conditions Module.
|
|
290
|
+
* - `'use agnostic strategies'`, `"use agnostic strategies"` denoting an Agnostic Strategies Module.
|
|
291
|
+
* @param sourceCode The ESLint SourceCode object.
|
|
292
|
+
* @returns The commented directive, or lack thereof via `null`. Given the strictness of this architecture, the lack of a directive is considered a mistake. (Though rules may provide the opportunity to declare a default, and configs with preset defaults may become provided.)
|
|
293
|
+
*/
|
|
294
|
+
export const getCommentedDirectiveFromSourceCode: (
|
|
295
|
+
sourceCode: ESLintSourceCode
|
|
296
|
+
) =>
|
|
297
|
+
| "use server logics"
|
|
298
|
+
| "use client logics"
|
|
299
|
+
| "use agnostic logics"
|
|
300
|
+
| "use server components"
|
|
301
|
+
| "use client components"
|
|
302
|
+
| "use agnostic components"
|
|
303
|
+
| "use server functions"
|
|
304
|
+
| "use client contexts"
|
|
305
|
+
| "use agnostic conditions"
|
|
306
|
+
| "use agnostic strategies"
|
|
307
|
+
| null;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Gets the commented directive of the current module.
|
|
311
|
+
*
|
|
312
|
+
* Accepted directives for the default Directive-First Architecture are (single or double quotes included):
|
|
313
|
+
* - `'use server logics'`, `"use server logics"` denoting a Server Logics Module.
|
|
314
|
+
* - `'use client logics'`, `"use client logics"` denoting a Client Logics Module.
|
|
315
|
+
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
316
|
+
* - `'use server components'`, `"use server components"` denoting a Server Components Module.
|
|
317
|
+
* - `'use client components'`, `"use client components"` denoting a Client Components Module.
|
|
318
|
+
* - `'use agnostic components'`, `"use agnostic components"` denoting an Agnostic Components Module.
|
|
319
|
+
* - `'use server functions'`, `"use server functions"` denoting a Server Functions Module.
|
|
320
|
+
* - `'use client contexts'`, `"use client contexts"` denoting a Client Contexts Module.
|
|
321
|
+
* - `'use agnostic conditions'`, `"use agnostic conditions"` denoting an Agnostic Conditions Module.
|
|
322
|
+
* - `'use agnostic strategies'`, `"use agnostic strategies"` denoting an Agnostic Strategies Module.
|
|
323
|
+
* @param context The ESLint rule's `context` object.
|
|
324
|
+
* @returns The commented directive, or lack thereof via `null`. Given the strictness of this architecture, the lack of a directive is considered a mistake. (Though rules may provide the opportunity to declare a default, and configs with preset defaults may become provided.)
|
|
325
|
+
*/
|
|
326
|
+
export const getCommentedDirectiveFromCurrentModule: (
|
|
327
|
+
context: RuleContext<string, readonly unknown[]>
|
|
328
|
+
) =>
|
|
329
|
+
| "use server logics"
|
|
330
|
+
| "use client logics"
|
|
331
|
+
| "use agnostic logics"
|
|
332
|
+
| "use server components"
|
|
333
|
+
| "use client components"
|
|
334
|
+
| "use agnostic components"
|
|
335
|
+
| "use server functions"
|
|
336
|
+
| "use client contexts"
|
|
337
|
+
| "use agnostic conditions"
|
|
338
|
+
| "use agnostic strategies"
|
|
339
|
+
| null;
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Gets the commented directive of the imported module.
|
|
343
|
+
*
|
|
344
|
+
* Accepted directives for the default Directive-First Architecture are (single or double quotes included):
|
|
345
|
+
* - `'use server logics'`, `"use server logics"` denoting a Server Logics Module.
|
|
346
|
+
* - `'use client logics'`, `"use client logics"` denoting a Client Logics Module.
|
|
347
|
+
* - `'use agnostic logics'`, `"use agnostic logics"` denoting an Agnostic Logics Module.
|
|
348
|
+
* - `'use server components'`, `"use server components"` denoting a Server Components Module.
|
|
349
|
+
* - `'use client components'`, `"use client components"` denoting a Client Components Module.
|
|
350
|
+
* - `'use agnostic components'`, `"use agnostic components"` denoting an Agnostic Components Module.
|
|
351
|
+
* - `'use server functions'`, `"use server functions"` denoting a Server Functions Module.
|
|
352
|
+
* - `'use client contexts'`, `"use client contexts"` denoting a Client Contexts Module.
|
|
353
|
+
* - `'use agnostic conditions'`, `"use agnostic conditions"` denoting an Agnostic Conditions Module.
|
|
354
|
+
* - `'use agnostic strategies'`, `"use agnostic strategies"` denoting an Agnostic Strategies Module.
|
|
355
|
+
* @param resolvedPath The resolved path of the imported module.
|
|
356
|
+
* @returns The commented directive, or lack thereof via `null`. Given the strictness of this architecture, the lack of a directive is considered a mistake. (Though rules may provide the opportunity to declare a default, and configs with preset defaults may become provided.)
|
|
357
|
+
*/
|
|
358
|
+
export const getCommentedDirectiveFromImportedModule: (
|
|
359
|
+
resolvedPath: string
|
|
360
|
+
) =>
|
|
361
|
+
| "use server logics"
|
|
362
|
+
| "use client logics"
|
|
363
|
+
| "use agnostic logics"
|
|
364
|
+
| "use server components"
|
|
365
|
+
| "use client components"
|
|
366
|
+
| "use agnostic components"
|
|
367
|
+
| "use server functions"
|
|
368
|
+
| "use client contexts"
|
|
369
|
+
| "use agnostic conditions"
|
|
370
|
+
| "use agnostic strategies"
|
|
371
|
+
| null;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Ensures that a module's commented directive is consistent with its file extension (depending on whether it ends with 'x' for JSX).
|
|
375
|
+
* - `'use server logics'`: Server Logics Modules do NOT export JSX.
|
|
376
|
+
* - `'use client logics'`: Client Logics Modules do NOT export JSX.
|
|
377
|
+
* - `'use agnostic logics'`: Agnostic Logics Modules do NOT export JSX.
|
|
378
|
+
* - `'use server components'`: Server Components Modules ONLY export JSX.
|
|
379
|
+
* - `'use client components'`: Client Components Modules ONLY export JSX.
|
|
380
|
+
* - `'use agnostic components'`: Agnostic Components Modules ONLY export JSX.
|
|
381
|
+
* - `'use server functions'`: Server Functions Modules do NOT export JSX.
|
|
382
|
+
* - `'use client contexts'`: Client Contexts Modules ONLY export JSX.
|
|
383
|
+
* - `'use agnostic conditions'`: Agnostic Conditions Modules ONLY export JSX.
|
|
384
|
+
* - `'use agnostic strategies'`: Agnostic Strategies Modules may export JSX.
|
|
385
|
+
* @param directive The commented directive as written on top of the file (cannot be `null` at that stage).
|
|
386
|
+
* @param extension The JavaScript (TypeScript) extension of the file.
|
|
387
|
+
* @returns The verified commented directive, from which imports rules are applied. Returns `null` if the verification failed, upon which an error will be reported depending on the commented directive, since the error logic here is strictly binary.
|
|
388
|
+
*/
|
|
389
|
+
export const getVerifiedCommentedDirective: (
|
|
390
|
+
directive:
|
|
391
|
+
| "use server logics"
|
|
392
|
+
| "use client logics"
|
|
393
|
+
| "use agnostic logics"
|
|
394
|
+
| "use server components"
|
|
395
|
+
| "use client components"
|
|
396
|
+
| "use agnostic components"
|
|
397
|
+
| "use server functions"
|
|
398
|
+
| "use client contexts"
|
|
399
|
+
| "use agnostic conditions"
|
|
400
|
+
| "use agnostic strategies",
|
|
401
|
+
extension:
|
|
402
|
+
| ".tsx"
|
|
403
|
+
| ".ts"
|
|
404
|
+
| ".mtsx"
|
|
405
|
+
| ".mts"
|
|
406
|
+
| ".ctsx"
|
|
407
|
+
| ".cts"
|
|
408
|
+
| ".jsx"
|
|
409
|
+
| ".js"
|
|
410
|
+
| ".mjsx"
|
|
411
|
+
| ".mjs"
|
|
412
|
+
| ".cjsx"
|
|
413
|
+
| ".cjs"
|
|
414
|
+
) =>
|
|
415
|
+
| "use server logics"
|
|
416
|
+
| "use client logics"
|
|
417
|
+
| "use agnostic logics"
|
|
418
|
+
| "use server components"
|
|
419
|
+
| "use client components"
|
|
420
|
+
| "use agnostic components"
|
|
421
|
+
| "use server functions"
|
|
422
|
+
| "use client contexts"
|
|
423
|
+
| "use agnostic conditions"
|
|
424
|
+
| "use agnostic strategies"
|
|
425
|
+
| null;
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Gets the interpreted directive from a specified commented Strategy (such as `@serverLogics`) nested inside the import (or export) declaration for an import (or export) from an Agnostic Strategies Module.
|
|
429
|
+
* @param context The ESLint rule's `context` object.
|
|
430
|
+
* @param node The ESLint `node` of the rule's current traversal.
|
|
431
|
+
* @returns The interpreted directive, a.k.a. strategized directive, or lack thereof via `null`.
|
|
432
|
+
*/
|
|
433
|
+
export const getStrategizedDirective: (
|
|
434
|
+
context: RuleContext<string, readonly unknown[]>,
|
|
435
|
+
node:
|
|
436
|
+
| TSESTree.ImportDeclaration
|
|
437
|
+
| TSESTree.ExportNamedDeclaration
|
|
438
|
+
| TSESTree.ExportAllDeclaration
|
|
439
|
+
| TSESTree.ExportDefaultDeclaration
|
|
440
|
+
) =>
|
|
441
|
+
| "use server logics"
|
|
442
|
+
| "use client logics"
|
|
443
|
+
| "use agnostic logics"
|
|
444
|
+
| "use server components"
|
|
445
|
+
| "use client components"
|
|
446
|
+
| "use agnostic components"
|
|
447
|
+
| "use server functions"
|
|
448
|
+
| "use client contexts"
|
|
449
|
+
| "use agnostic conditions"
|
|
450
|
+
| null;
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Returns a boolean deciding if an imported file's commented directive is incompatible with the current file's commented directive.
|
|
454
|
+
* @param currentFileCommentedDirective The current file's commented directive.
|
|
455
|
+
* @param importedFileCommentedDirective The imported file's commented directive.
|
|
456
|
+
* @returns `true` if the import is blocked, as established in `commentedDirectives_BlockedImports`.
|
|
457
|
+
*/
|
|
458
|
+
export const isImportBlockedDirective21: (
|
|
459
|
+
currentFileCommentedDirective:
|
|
460
|
+
| "use server logics"
|
|
461
|
+
| "use client logics"
|
|
462
|
+
| "use agnostic logics"
|
|
463
|
+
| "use server components"
|
|
464
|
+
| "use client components"
|
|
465
|
+
| "use agnostic components"
|
|
466
|
+
| "use server functions"
|
|
467
|
+
| "use client contexts"
|
|
468
|
+
| "use agnostic conditions",
|
|
469
|
+
importedFileCommentedDirective:
|
|
470
|
+
| "use server logics"
|
|
471
|
+
| "use client logics"
|
|
472
|
+
| "use agnostic logics"
|
|
473
|
+
| "use server components"
|
|
474
|
+
| "use client components"
|
|
475
|
+
| "use agnostic components"
|
|
476
|
+
| "use server functions"
|
|
477
|
+
| "use client contexts"
|
|
478
|
+
| "use agnostic conditions"
|
|
479
|
+
) => boolean;
|