casper-context 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 +253 -0
- package/dist/index.js +9 -0
- package/dist/lifecycle/post.js +239 -0
- package/dist/lifecycle/pre.js +113 -0
- package/dist/plugin.js +57 -0
- package/dist/transforms/autoContextTransform.js +1 -0
- package/dist/transforms/contextTransform.js +1 -0
- package/dist/transforms/stateTransform.js +1 -0
- package/dist/types/plugin.d.js +1 -0
- package/dist/utils/astHelpers.js +644 -0
- package/dist/utils/constants.js +111 -0
- package/dist/utils/names.js +1 -0
- package/dist/utils/scope.js +1 -0
- package/dist/utils/utilityHelpers.js +606 -0
- package/dist/visitors/AssignmentExpression.js +104 -0
- package/dist/visitors/CallExpression.js +1 -0
- package/dist/visitors/FunctionDeclaration.js +116 -0
- package/dist/visitors/Identifier.js +123 -0
- package/dist/visitors/JSXElement.js +1 -0
- package/dist/visitors/Program.js +278 -0
- package/dist/visitors/ReturnStatement.js +81 -0
- package/dist/visitors/VariableDeclaration.js +209 -0
- package/package.json +60 -0
- package/src/index.js +2 -0
- package/src/lifecycle/post.js +237 -0
- package/src/lifecycle/pre.js +103 -0
- package/src/plugin.js +51 -0
- package/src/transforms/autoContextTransform.js +0 -0
- package/src/transforms/contextTransform.js +0 -0
- package/src/transforms/stateTransform.js +0 -0
- package/src/types/plugin.d.ts +0 -0
- package/src/utils/astHelpers.js +767 -0
- package/src/utils/constants.js +102 -0
- package/src/utils/names.js +0 -0
- package/src/utils/scope.js +0 -0
- package/src/utils/utilityHelpers.js +636 -0
- package/src/visitors/AssignmentExpression.js +100 -0
- package/src/visitors/CallExpression.js +0 -0
- package/src/visitors/FunctionDeclaration.js +114 -0
- package/src/visitors/Identifier.js +142 -0
- package/src/visitors/JSXElement.js +0 -0
- package/src/visitors/Program.js +280 -0
- package/src/visitors/ReturnStatement.js +75 -0
- package/src/visitors/VariableDeclaration.js +216 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Application Root & Provider Orchestration.
|
|
3
|
+
* This module manages the final wrapping phase of the AST transformation.
|
|
4
|
+
* It ensures that the transformed component tree is encapsulated within
|
|
5
|
+
* the custom Casper Context Provider, enabling global state distribution.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Core Logic Constants
|
|
10
|
+
* @description
|
|
11
|
+
* - _CCTX_CMP_NAME_PREFIX: The prefix used to identify and generate unique
|
|
12
|
+
* Context Provider instances (e.g., '_$_ctx_').
|
|
13
|
+
* - _CCTX_EMPTY: A safe fallback initializer for string-based AST properties.
|
|
14
|
+
*/
|
|
15
|
+
import { _CCTX_CMP_NAME_PREFIX, _CCTX_EMPTY } from '../utils/constants';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* AST Transformation Helpers
|
|
19
|
+
* @description
|
|
20
|
+
* - buildCtxProvider: A structural helper that wraps a JSX element or
|
|
21
|
+
* Function body with a `<Context.Provider>` component, mapping internal
|
|
22
|
+
* state to the Provider's `value` prop.
|
|
23
|
+
*/
|
|
24
|
+
import { buildCtxProvider } from '../utils/astHelpers';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @module Logger
|
|
28
|
+
* @description Provides a controlled logging interface for the Babel transformation process.
|
|
29
|
+
*/
|
|
30
|
+
import { log } from '../utils/utilityHelpers';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @important
|
|
34
|
+
* The `buildCtxProvider` function is typically invoked during the `Program.exit`
|
|
35
|
+
* or `ExportDefaultDeclaration` phase to ensure all nested transformations
|
|
36
|
+
* are complete before the final Provider wrapping occurs.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Visitor for `ReturnStatement` nodes inside a function declaration.
|
|
41
|
+
*
|
|
42
|
+
* This function inspects the return statement of a component function
|
|
43
|
+
* and wraps its returned JSX or value with the corresponding context provider.
|
|
44
|
+
* It ensures that the component correctly provides state and context to its children.
|
|
45
|
+
*
|
|
46
|
+
* @param {NodePath} path - The Babel AST path representing the `ReturnStatement` node.
|
|
47
|
+
* @param {Object} state - Plugin state, including import information and configuration.
|
|
48
|
+
* @param {Object} t - Babel types helper (`@babel/types`) used to generate AST nodes.
|
|
49
|
+
* @param {Object} entry - Registry entry for the component, containing `ctxName` and variable names.
|
|
50
|
+
*
|
|
51
|
+
* @returns {void}
|
|
52
|
+
* Modifies the return statement node in place, replacing it with a `React.createElement`
|
|
53
|
+
* call that wraps the original return value with a context provider.
|
|
54
|
+
*
|
|
55
|
+
* @important
|
|
56
|
+
* - Only processes return statements that have a non-null argument.
|
|
57
|
+
* - Uses `buildCtxProvider` to generate the provider wrapper.
|
|
58
|
+
* - Errors are silently caught; no changes occur if an exception is thrown.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```js
|
|
62
|
+
* functionDeclarationReturnStatementVisitor(path, state, t, entry);
|
|
63
|
+
* // Wraps the return value of a component function with its context provider
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function functionDeclarationReturnStatementVisitor (path, state, t, entry) {
|
|
67
|
+
try {
|
|
68
|
+
const returnNode = path.node.argument;
|
|
69
|
+
if (!returnNode) return;
|
|
70
|
+
const stateName = entry.ctxName.replace(_CCTX_CMP_NAME_PREFIX, _CCTX_EMPTY);
|
|
71
|
+
buildCtxProvider(path, t, returnNode, state, stateName);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
log('error', '[::functionDeclarationReturnStatementVisitor::]', e.message);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Variable Registration & Classification Logic.
|
|
3
|
+
* This module is responsible for the initial discovery phase of the transformation.
|
|
4
|
+
* It identifies custom context variables during their declaration, classifies their
|
|
5
|
+
* initial values, and registers them within the global tracking registry.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* AST Literal & Expression Constants
|
|
10
|
+
* @description These constants are used to evaluate the 'init' value of a variable.
|
|
11
|
+
* Your library uses these to distinguish between simple state and complex logic.
|
|
12
|
+
*/
|
|
13
|
+
import {
|
|
14
|
+
NUMERIC_LITERAL, // e.g., 42
|
|
15
|
+
STRING_LITERAL, // e.g., "hello"
|
|
16
|
+
BOOLEAN_LITERAL, // e.g., true
|
|
17
|
+
ARRAY_EXPRESSION, // e.g., [1, 2, 3]
|
|
18
|
+
OBJECT_EXPRESSION,// e.g., { key: 'value' }
|
|
19
|
+
_CCTX_EMPTY // Default fallback for uninitialized variables
|
|
20
|
+
} from '../utils/constants';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Registration & Lifecycle Utilities
|
|
24
|
+
* @description
|
|
25
|
+
* - isExcludeFile: Prevents tracking variables in ignored files or directories.
|
|
26
|
+
* - registerVariable: The core method that saves variable metadata to the virtualRegistry.
|
|
27
|
+
* - getFilePathHASH: Ensures variables are scoped to a unique file ID to prevent collisions.
|
|
28
|
+
*/
|
|
29
|
+
import { isExcludeFile, registerVariable, getFilePathHASH } from '../utils/utilityHelpers';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Scope & Inheritance Helpers
|
|
33
|
+
* @description
|
|
34
|
+
* - getInheritantDecComponent: Traverses upward from a variable declaration to find
|
|
35
|
+
* the parent component name, ensuring the variable is correctly scoped to its owner.
|
|
36
|
+
*/
|
|
37
|
+
import { getInheritantDecComponent } from '../utils/astHelpers';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @module Logger
|
|
41
|
+
* @description Provides a controlled logging interface for the Babel transformation process.
|
|
42
|
+
*/
|
|
43
|
+
import { log } from '../utils/utilityHelpers';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @important
|
|
47
|
+
* **Classification Note:** When a variable is registered, its "Literal Type" determines
|
|
48
|
+
* how the subsequent `useState` hook is initialized. Non-literal initializers
|
|
49
|
+
* may require different handling during the `functionDeclarationExit` phase.
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Extracts the initial value of a variable from a Babel AST `VariableDeclarator` node.
|
|
54
|
+
*
|
|
55
|
+
* This function inspects the `init` property of a variable declaration and
|
|
56
|
+
* attempts to determine its literal value. It handles primitive literals,
|
|
57
|
+
* arrays, and objects with literal values. Non-literal or complex expressions
|
|
58
|
+
* are flagged as `NON_LITERAL`.
|
|
59
|
+
*
|
|
60
|
+
* @param {NodePath} path - Babel AST path for a `VariableDeclarator` node.
|
|
61
|
+
*
|
|
62
|
+
* @returns {any} The initial value of the variable:
|
|
63
|
+
* - `number` for numeric literals
|
|
64
|
+
* - `string` for string literals
|
|
65
|
+
* - `boolean` for boolean literals
|
|
66
|
+
* - `Array` of literal values for array expressions
|
|
67
|
+
* - `Object` of literal key-value pairs for object expressions
|
|
68
|
+
* - `NON_LITERAL` for other expressions or complex initializers
|
|
69
|
+
* - `undefined` if the variable has no initializer
|
|
70
|
+
*
|
|
71
|
+
* @important
|
|
72
|
+
* - Only inspects direct literal values. Nested expressions inside arrays or objects
|
|
73
|
+
* that are not literals will be ignored or marked as `null`.
|
|
74
|
+
* - Errors during traversal or invalid AST nodes will return the current `initValue`.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```js
|
|
78
|
+
* // For "const a = 5;" → returns 5
|
|
79
|
+
* // For "const b = [1, 2];" → returns [1, 2]
|
|
80
|
+
* // For "const c = { x: 1, y: 'a' };" → returns { x: 1, y: 'a' }
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
function getVariableInitValue(path) {
|
|
84
|
+
let initValue = undefined;
|
|
85
|
+
try {
|
|
86
|
+
if (path.node.init) {
|
|
87
|
+
const valNode = path.node.init;
|
|
88
|
+
if (valNode.type === NUMERIC_LITERAL ||
|
|
89
|
+
valNode.type === STRING_LITERAL ||
|
|
90
|
+
valNode.type === BOOLEAN_LITERAL) {
|
|
91
|
+
initValue = valNode.value;
|
|
92
|
+
}
|
|
93
|
+
else if (valNode.type === ARRAY_EXPRESSION) {
|
|
94
|
+
initValue =
|
|
95
|
+
valNode.elements.map(e => e.value ?? null);
|
|
96
|
+
}
|
|
97
|
+
else if (valNode.type === OBJECT_EXPRESSION) {
|
|
98
|
+
const obj = {};
|
|
99
|
+
for (const prop of valNode.properties) {
|
|
100
|
+
if (prop.key && prop.value && prop.value.value !== undefined) {
|
|
101
|
+
obj[prop.key.name || prop.key.value] = prop.value.value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
initValue = obj;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
initValue = NON_LITERAL;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return initValue;
|
|
111
|
+
} catch (e) {
|
|
112
|
+
return initValue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Visitor for `VariableDeclarator` nodes to register state variables in the virtual registry.
|
|
118
|
+
*
|
|
119
|
+
* This function checks if a variable's name matches the plugin's configured prefix.
|
|
120
|
+
* If so, it extracts the initial value, identifies the enclosing component, and
|
|
121
|
+
* registers the variable in the `virtualRegistry`. It also ensures React and global
|
|
122
|
+
* context imports are flagged if needed.
|
|
123
|
+
*
|
|
124
|
+
* @param {NodePath} path - Babel AST path for a `VariableDeclarator` node.
|
|
125
|
+
* @param {Object} state - Plugin state, including filename, import metadata, and configuration flags.
|
|
126
|
+
* @param {Object} t - Babel types helper (`@babel/types`) used to inspect or create AST nodes.
|
|
127
|
+
* @param {Object<string, Object>} virtualRegistry - Registry of components and their registered variables.
|
|
128
|
+
*
|
|
129
|
+
* @returns {void}
|
|
130
|
+
* - Registers the variable in the `virtualRegistry` under the component hash.
|
|
131
|
+
* - Sets `state.needsGblContext` if the variable belongs to a global context.
|
|
132
|
+
* - Flags `state.needUseStateImport` if `useState` is not yet imported.
|
|
133
|
+
*
|
|
134
|
+
* @important
|
|
135
|
+
* - Only processes variables whose names start with the configured prefix.
|
|
136
|
+
* - Uses `getVariableInitValue` to determine the variable's initial value.
|
|
137
|
+
* - Errors are silently caught; no action is taken if an exception occurs.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```js
|
|
141
|
+
* variableDeclarationVisitor(path, state, t, virtualRegistry);
|
|
142
|
+
* // Registers a prefixed variable in the virtual registry with its initial value
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export default function variableDeclarationVisitor(path, state, t, virtualRegistry) {
|
|
146
|
+
try {
|
|
147
|
+
const fileName = state.filename || _CCTX_EMPTY;
|
|
148
|
+
if (!isExcludeFile(fileName, this.opts)) return;
|
|
149
|
+
if (path.node.id.name?.startsWith(state.casperConfig.prefix)) {
|
|
150
|
+
const inheritantCMP = getInheritantDecComponent(path);
|
|
151
|
+
if (!inheritantCMP) return;
|
|
152
|
+
const filePathHash = getFilePathHASH(fileName);
|
|
153
|
+
let _init_value = getVariableInitValue(path);
|
|
154
|
+
state.needsGblContext = true;
|
|
155
|
+
if (
|
|
156
|
+
!state.importState.reactId &&
|
|
157
|
+
!state.importState.useStateId
|
|
158
|
+
) {
|
|
159
|
+
state.needUseStateImport = true
|
|
160
|
+
}
|
|
161
|
+
registerVariable(`${inheritantCMP}_${filePathHash}`, path.node.id.name, _init_value, virtualRegistry);
|
|
162
|
+
}
|
|
163
|
+
} catch (e) {
|
|
164
|
+
log('error', '[::variableDeclarationVisitor::]', e.message);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Visitor for `VariableDeclarator` nodes inside a function's body to collect state variables.
|
|
170
|
+
*
|
|
171
|
+
* This function inspects variable declarations within a component function and collects
|
|
172
|
+
* those whose names start with the plugin's configured prefix. Collected variables are
|
|
173
|
+
* added to `localStateVars` for later use in context or state initialization.
|
|
174
|
+
* The original declaration line is removed from the AST to prevent duplication.
|
|
175
|
+
*
|
|
176
|
+
* @param {NodePath} path - Babel AST path for a `VariableDeclarator` node.
|
|
177
|
+
* @param {Object} state - Plugin state, containing the configuration and flags.
|
|
178
|
+
* @param {Object} t - Babel types helper (`@babel/types`) used to inspect and manipulate AST nodes.
|
|
179
|
+
* @param {Array<Object>} localStateVars - Array to collect state variables with `{ name, init }`.
|
|
180
|
+
*
|
|
181
|
+
* @returns {void}
|
|
182
|
+
* - Pushes matched variables into `localStateVars`.
|
|
183
|
+
* - Removes the original variable declaration or the specific declarator from the AST.
|
|
184
|
+
*
|
|
185
|
+
* @important
|
|
186
|
+
* - Only processes identifiers whose names match the configured prefix.
|
|
187
|
+
* - Safely handles declarations with multiple declarators by removing only the matched one.
|
|
188
|
+
* - Errors are silently caught; no action occurs if an exception is thrown.
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```js
|
|
192
|
+
* const localStateVars = [];
|
|
193
|
+
* functionReturnVariableDelarationVisitor(path, state, t, localStateVars);
|
|
194
|
+
* // localStateVars now contains the prefixed variables from the function
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export function functionReturnVariableDelarationVisitor(path, state, t, localStateVars) {
|
|
198
|
+
try {
|
|
199
|
+
const id = path.node.id;
|
|
200
|
+
const init = path.node.init;
|
|
201
|
+
if (!t.isIdentifier(id)) return;
|
|
202
|
+
if (id.name.startsWith(state.casperConfig.prefix)) {
|
|
203
|
+
localStateVars.push({ name: id.name, init });
|
|
204
|
+
// remove declaration line
|
|
205
|
+
if (t.isVariableDeclaration(path.parent)) {
|
|
206
|
+
if (path.parent.declarations.length === 1) {
|
|
207
|
+
path.parentPath.remove();
|
|
208
|
+
} else {
|
|
209
|
+
path.remove();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
} catch (e) {
|
|
214
|
+
log('error', '[::functionReturnVariableDelarationVisitor::]', e.message);
|
|
215
|
+
}
|
|
216
|
+
}
|