Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
No EOL
5.7 KiB
Text
87 lines
No EOL
5.7 KiB
Text
// This module provides intellisense for all components that has the `"use client"` directive.
|
|
import { NEXT_TS_ERRORS } from '../constant';
|
|
import { getTs, getTypeChecker } from '../utils';
|
|
const clientBoundary = {
|
|
getSemanticDiagnosticsForExportVariableStatement (source, node) {
|
|
const ts = getTs();
|
|
const diagnostics = [];
|
|
if (ts.isVariableDeclarationList(node.declarationList)) {
|
|
for (const declaration of node.declarationList.declarations){
|
|
const initializer = declaration.initializer;
|
|
if (initializer && ts.isArrowFunction(initializer)) {
|
|
diagnostics.push(...clientBoundary.getSemanticDiagnosticsForFunctionExport(source, initializer));
|
|
}
|
|
}
|
|
}
|
|
return diagnostics;
|
|
},
|
|
getSemanticDiagnosticsForFunctionExport (source, node) {
|
|
var _node_parameters;
|
|
const ts = getTs();
|
|
const typeChecker = getTypeChecker();
|
|
if (!typeChecker) return [];
|
|
const diagnostics = [];
|
|
const isErrorFile = /[\\/]error\.tsx?$/.test(source.fileName);
|
|
const isGlobalErrorFile = /[\\/]global-error\.tsx?$/.test(source.fileName);
|
|
const props = (_node_parameters = node.parameters) == null ? void 0 : _node_parameters[0];
|
|
if (props) {
|
|
var _propsType_symbol_getDeclarations, _propsType_symbol;
|
|
const propsType = typeChecker.getTypeAtLocation(props);
|
|
const typeNode = (_propsType_symbol = propsType.symbol) == null ? void 0 : (_propsType_symbol_getDeclarations = _propsType_symbol.getDeclarations()) == null ? void 0 : _propsType_symbol_getDeclarations[0];
|
|
if (typeNode && ts.isTypeLiteralNode(typeNode)) {
|
|
for (const member of typeNode.members){
|
|
if (ts.isPropertySignature(member)) {
|
|
const propName = member.name.getText();
|
|
const propType = member.type;
|
|
if (propType) {
|
|
var _propTypeInfo_symbol_getDeclarations, _propTypeInfo_symbol;
|
|
const propTypeInfo = typeChecker.getTypeAtLocation(propType);
|
|
const typeDeclarationNode = (_propTypeInfo_symbol = propTypeInfo.symbol) == null ? void 0 : (_propTypeInfo_symbol_getDeclarations = _propTypeInfo_symbol.getDeclarations()) == null ? void 0 : _propTypeInfo_symbol_getDeclarations[0];
|
|
if (typeDeclarationNode) {
|
|
if (ts.isFunctionTypeNode(typeDeclarationNode) || // someFunc(): void
|
|
ts.isMethodSignature(typeDeclarationNode)) {
|
|
// By convention, props named "action" can accept functions since we
|
|
// assume these are Server Actions. Structurally, there's no
|
|
// difference between a Server Action and a normal function until
|
|
// TypeScript exposes directives in the type of a function. This
|
|
// will miss accidentally passing normal functions but a false
|
|
// negative is better than a false positive given how frequent the
|
|
// false-positive would be.
|
|
const maybeServerAction = propName === 'action' || /.+Action$/.test(propName);
|
|
// There's a special case for the error file that the `reset` prop
|
|
// is allowed to be a function:
|
|
// https://github.com/vercel/next.js/issues/46573
|
|
const isErrorReset = (isErrorFile || isGlobalErrorFile) && propName === 'reset';
|
|
if (!maybeServerAction && !isErrorReset) {
|
|
diagnostics.push({
|
|
file: source,
|
|
category: ts.DiagnosticCategory.Warning,
|
|
code: NEXT_TS_ERRORS.INVALID_CLIENT_ENTRY_PROP,
|
|
messageText: `Props must be serializable for components in the "use client" entry file. ` + `"${propName}" is a function that's not a Server Action. ` + `Rename "${propName}" either to "action" or have its name end with "Action" e.g. "${propName}Action" to indicate it is a Server Action.`,
|
|
start: propType.getStart(),
|
|
length: propType.getWidth()
|
|
});
|
|
}
|
|
} else if (// Show warning for not serializable props.
|
|
ts.isConstructorTypeNode(typeDeclarationNode) || ts.isClassDeclaration(typeDeclarationNode)) {
|
|
diagnostics.push({
|
|
file: source,
|
|
category: ts.DiagnosticCategory.Warning,
|
|
code: NEXT_TS_ERRORS.INVALID_CLIENT_ENTRY_PROP,
|
|
messageText: `Props must be serializable for components in the "use client" entry file, "${propName}" is invalid.`,
|
|
start: propType.getStart(),
|
|
length: propType.getWidth()
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return diagnostics;
|
|
}
|
|
};
|
|
export default clientBoundary;
|
|
|
|
//# sourceMappingURL=client-boundary.js.map |