@@ -15,6 +15,99 @@ export const createRule = ESLintUtils.RuleCreator(name => {
1515 return `${ REPO_URL } /blob/v${ version } /docs/rules/${ ruleName } .md` ;
1616} ) ;
1717
18+ /**
19+ * A `Literal` with a `value` of type `string`.
20+ */
21+ export interface StringLiteral < Value extends string = string >
22+ extends TSESTree . Literal {
23+ value : Value ;
24+ }
25+
26+ /**
27+ * Checks if the given `node` is a `StringLiteral`.
28+ *
29+ * If a `value` is provided & the `node` is a `StringLiteral`,
30+ * the `value` will be compared to that of the `StringLiteral`.
31+ *
32+ * @param {Node } node
33+ * @param {V? } value
34+ *
35+ * @return {node is StringLiteral<V> }
36+ *
37+ * @template {V}.
38+ */
39+ const isStringLiteral = < V extends string > (
40+ node : TSESTree . Node ,
41+ value ?: V ,
42+ ) : node is StringLiteral < V > =>
43+ node . type === AST_NODE_TYPES . Literal &&
44+ typeof node . value === 'string' &&
45+ ( value === undefined || node . value === value ) ;
46+
47+ interface TemplateLiteral < Value extends string = string >
48+ extends TSESTree . TemplateLiteral {
49+ quasis : [ TSESTree . TemplateElement & { value : { raw : Value ; cooked : Value } } ] ;
50+ }
51+
52+ /**
53+ * Checks if the given `node` is a `TemplateLiteral`.
54+ *
55+ * Complex `TemplateLiteral`s are not considered specific, and so will return `false`.
56+ *
57+ * If a `value` is provided & the `node` is a `TemplateLiteral`,
58+ * the `value` will be compared to that of the `TemplateLiteral`.
59+ *
60+ * @param {Node } node
61+ * @param {V? } value
62+ *
63+ * @return {node is TemplateLiteral<V> }
64+ *
65+ * @template V
66+ */
67+ export const isTemplateLiteral = < V extends string > (
68+ node : TSESTree . Node ,
69+ value ?: V ,
70+ ) : node is TemplateLiteral < V > =>
71+ node . type === AST_NODE_TYPES . TemplateLiteral &&
72+ ( value === undefined ||
73+ ( node . quasis . length === 1 && // bail out if not simple
74+ node . quasis [ 0 ] . value . raw === value ) ) ;
75+
76+ type StringNode < S extends string = string > =
77+ | StringLiteral < S >
78+ | TemplateLiteral < S > ;
79+
80+ /**
81+ * Checks if the given `node` is a {@link StringNode}.
82+ *
83+ * @param {Node } node
84+ * @param {V? } specifics
85+ *
86+ * @return {node is StringNode }
87+ *
88+ * @template V
89+ */
90+ export const isStringNode = < V extends string > (
91+ node : TSESTree . Node ,
92+ specifics ?: V ,
93+ ) : node is StringNode < V > =>
94+ isStringLiteral ( node , specifics ) || isTemplateLiteral ( node , specifics ) ;
95+
96+ /**
97+ * Gets the value of the given `StringNode`.
98+ *
99+ * If the `node` is a `TemplateLiteral`, the `raw` value is used;
100+ * otherwise, `value` is returned instead.
101+ *
102+ * @param {StringNode<S> } node
103+ *
104+ * @return {S }
105+ *
106+ * @template S
107+ */
108+ export const getStringValue = < S extends string > ( node : StringNode < S > ) : S =>
109+ isTemplateLiteral ( node ) ? node . quasis [ 0 ] . value . raw : node . value ;
110+
18111interface JestExpectIdentifier extends TSESTree . Identifier {
19112 name : 'expect' ;
20113}
@@ -217,34 +310,11 @@ export const isLiteralNode = (node: {
217310 type : AST_NODE_TYPES ;
218311} ) : node is TSESTree . Literal => node . type === AST_NODE_TYPES . Literal ;
219312
220- export interface StringLiteral extends TSESTree . Literal {
221- value : string ;
222- }
223-
224- export type StringNode = StringLiteral | TSESTree . TemplateLiteral ;
225-
226- export const isStringLiteral = ( node : TSESTree . Node ) : node is StringLiteral =>
227- node . type === AST_NODE_TYPES . Literal && typeof node . value === 'string' ;
228-
229- export const isTemplateLiteral = (
230- node : TSESTree . Node ,
231- ) : node is TSESTree . TemplateLiteral =>
232- node && node . type === AST_NODE_TYPES . TemplateLiteral ;
233-
234- export const isStringNode = (
235- node : TSESTree . Node | undefined ,
236- ) : node is StringNode =>
237- node !== undefined && ( isStringLiteral ( node ) || isTemplateLiteral ( node ) ) ;
238-
239313export const hasExpressions = (
240314 node : TSESTree . Node ,
241315) : node is TSESTree . Expression =>
242316 'expressions' in node && node . expressions . length > 0 ;
243317
244- /* istanbul ignore next we'll need this later */
245- export const getStringValue = ( arg : StringNode ) : string =>
246- isTemplateLiteral ( arg ) ? arg . quasis [ 0 ] . value . raw : arg . value ;
247-
248318const collectReferences = ( scope : TSESLint . Scope . Scope ) => {
249319 const locals = new Set ( ) ;
250320 const unresolved = new Set ( ) ;
0 commit comments