13
13
const chalk = require ( "chalk" ) ;
14
14
const { readFileSync, watch } = require ( "fs" ) ;
15
15
const { join, basename, sep, dirname } = require ( "path" ) ;
16
- const readline = require ( ' readline' )
16
+ const readline = require ( " readline" ) ;
17
17
18
18
const ts = require ( "typescript" ) ;
19
19
const remark = require ( "remark" ) ;
@@ -32,19 +32,19 @@ const filterString = process.argv[2] ? process.argv[2] : "";
32
32
33
33
if ( filterString === "--watch" ) {
34
34
const clear = ( ) => {
35
- const blank = '\n' . repeat ( process . stdout . rows )
36
- console . log ( blank )
37
- readline . cursorTo ( process . stdout , 0 , 0 )
38
- readline . clearScreenDown ( process . stdout )
39
- }
35
+ const blank = "\n" . repeat ( process . stdout . rows ) ;
36
+ console . log ( blank ) ;
37
+ readline . cursorTo ( process . stdout , 0 , 0 ) ;
38
+ readline . clearScreenDown ( process . stdout ) ;
39
+ } ;
40
40
41
41
if ( process . platform === "linux" ) throw new Error ( "Sorry linux peeps, the node watcher doesn't support linux." ) ;
42
42
watch ( join ( __dirname , ".." , "docs" ) , { recursive : true } , ( _ , filename ) => {
43
- clear ( )
44
- process . stdout . write ( "♲ " )
43
+ clear ( ) ;
44
+ process . stdout . write ( "♲ " ) ;
45
45
validateAtPaths ( [ join ( docsPath , filename ) ] ) ;
46
46
} ) ;
47
- clear ( )
47
+ clear ( ) ;
48
48
console . log ( `${ chalk . bold ( "Started the watcher" ) } , pressing save on a file in ./docs will lint that file.` ) ;
49
49
} else {
50
50
const toValidate = docs
@@ -170,96 +170,100 @@ function lintTSLanguageFile(file) {
170
170
ts . ScriptKind . TS
171
171
) ;
172
172
173
-
174
- const filename = basename ( file , ".ts" )
175
- const lastDir = dirname ( file ) . split ( sep ) . pop ( )
173
+ const filename = basename ( file , ".ts" ) ;
174
+ const lastDir = dirname ( file ) . split ( sep ) . pop ( ) ;
176
175
177
- const isRootImport = filename === lastDir
176
+ const isRootImport = filename === lastDir ;
178
177
if ( isRootImport ) {
179
178
// This is the import for the language which pulls in all the existing messages
180
179
//
181
- const notImportStatements = sourceFile . statements . filter ( f => f . kind !== 261 )
180
+ const notImportStatements = sourceFile . statements . filter ( ( f ) => f . kind !== 261 ) ;
182
181
const lastStatementIsDeclaration = sourceFile . statements [ 0 ] . kind !== 232 ;
183
- const onlyImportsAndOneExport = lastStatementIsDeclaration && notImportStatements . length === 1
184
-
182
+ const onlyImportsAndOneExport = lastStatementIsDeclaration && notImportStatements . length === 1 ;
183
+
185
184
if ( ! onlyImportsAndOneExport ) {
186
- errors . push ( new Error ( "A root language import can only include imports and an export called 'lang' " ) ) ;
185
+ errors . push ( new Error ( "A root language import can only include imports and an export called 'lang' " ) ) ;
187
186
}
188
187
189
188
if ( lastStatementIsDeclaration ) {
190
189
/** @type {import("typescript").VariableDeclarationList } */
191
190
// @ts -ignore
192
- const declarationList = notImportStatements [ 0 ] . declarationList
191
+ const declarationList = notImportStatements [ 0 ] . declarationList ;
193
192
194
- const declaration = declarationList . declarations [ 0 ]
195
- if ( ! declaration . initializer ) errors . push ( new Error ( `Something is off with the export in this file` ) ) ;
193
+ const declaration = declarationList . declarations [ 0 ] ;
194
+ if ( ! declaration . initializer ) errors . push ( new Error ( `Something is off with the export in this file` ) ) ;
196
195
197
196
/** @type {import("typescript").CallExpression } */
198
197
// @ts -ignore
199
- const callExpression = declaration . initializer . expression
200
- if ( callExpression . getText ( sourceFile ) !== "defineMessages" ) errors . push ( new Error ( `The export needs to call define messages` ) ) ;
201
-
198
+ const callExpression = declaration . initializer . expression ;
199
+ if ( callExpression . getText ( sourceFile ) !== "defineMessages" )
200
+ errors . push ( new Error ( `The export needs to call define messages` ) ) ;
201
+
202
202
/** @type {import("typescript").ObjectLiteralExpression } */
203
203
// @ts -ignore
204
- const arg0 = declaration . initializer . arguments [ 0 ]
205
- arg0 . properties . forEach ( p => {
206
- if ( p . kind !== 290 ) errors . push ( new Error ( `You can only have spreads (...) in the export` ) ) ;
207
- } )
204
+ const arg0 = declaration . initializer . arguments [ 0 ] ;
205
+ arg0 . properties . forEach ( ( p ) => {
206
+ if ( p . kind !== 290 ) errors . push ( new Error ( `You can only have spreads (...) in the export` ) ) ;
207
+ } ) ;
208
208
}
209
209
210
- sourceFile . statements . forEach ( s => {
211
- if ( ! ts . isImportDeclaration ( s ) ) return
212
- if ( ! s . importClause ) errors . push ( new Error ( `The import ${ s . moduleSpecifier . getText ( sourceFile ) } is not importing an object` ) ) ;
213
-
214
- const allowed = [ '"react-intl"' ]
215
- const specifier = s . moduleSpecifier . getText ( sourceFile )
210
+ sourceFile . statements . forEach ( ( s ) => {
211
+ if ( ! ts . isImportDeclaration ( s ) ) return ;
212
+ if ( ! s . importClause )
213
+ errors . push ( new Error ( `The import ${ s . moduleSpecifier . getText ( sourceFile ) } is not importing an object` ) ) ;
214
+
215
+ const allowed = [ '"react-intl"' ] ;
216
+ const specifier = s . moduleSpecifier . getText ( sourceFile ) ;
216
217
217
218
if ( ! allowed . includes ( specifier ) && ! specifier . startsWith ( '".' ) ) {
218
- errors . push ( new Error ( `The import ${ specifier } is not allowlisted ([${ allowed . join ( ", " ) } ]) nor relative` ) ) ;
219
+ errors . push ( new Error ( `The import ${ specifier } is not allowlisted ([${ allowed . join ( ", " ) } ]) nor relative` ) ) ;
219
220
}
220
- } )
221
+ } ) ;
221
222
222
223
} else {
223
224
// This should just be a simple lint that it only has a declaration
224
225
const tooManyStatements = sourceFile . statements . length > 1 ;
225
226
const notDeclarationList = sourceFile . statements . length > 0 && sourceFile . statements [ 0 ] . kind !== 232 ;
226
-
227
+
227
228
if ( tooManyStatements ) {
228
- errors . push ( new Error ( "TS files had more than one statement (e.g. more than `export const somethingCopy = { ... }` " ) ) ;
229
+ errors . push (
230
+ new Error ( "TS files had more than one statement (e.g. more than `export const somethingCopy = { ... }` " )
231
+ ) ;
229
232
}
230
-
233
+
231
234
if ( notDeclarationList ) {
232
- errors . push ( new Error ( "TS files should only look like: `export const somethingCopy = { ... }` " ) )
235
+ errors . push ( new Error ( "TS files should only look like: `export const somethingCopy = { ... }` " ) ) ;
233
236
}
234
- // @ts -ignore
235
- const lastStatement = sourceFile . statements [ 0 ] . declarationList
236
- if ( ! ts . isVariableDeclarationList ( lastStatement ) ) {
237
- errors . push ( new Error ( "TS files should only look like: `export const somethingCopy = { ... }` " ) )
238
- } else {
239
- /** @type {import("typescript").ObjectLiteralExpression } */
237
+
238
+ // @ts -ignore
239
+ if ( sourceFile . statements [ 0 ] && sourceFile . statements [ 0 ] . declarationList ) {
240
240
// @ts -ignore
241
- const init = lastStatement . declarations [ 0 ] . initializer
242
- if ( ! init ) {
243
- errors . push ( new Error ( "Something is off in the const in that file " ) )
241
+ const lastStatement = sourceFile . statements [ 0 ] . declarationList ;
242
+ if ( ! ts . isVariableDeclarationList ( lastStatement ) ) {
243
+ errors . push ( new Error ( "TS files should only look like: `export const somethingCopy = { ... }` " ) ) ;
244
244
} else {
245
- init . properties . forEach ( prop => {
246
- /** @type {import("typescript").PropertyAssignment } */
247
- // @ts -ignore
248
- const init = prop . initializer
249
- if ( init . kind !== 10 && init . kind !== 14 ) {
250
- if ( init . kind === 218 ) {
251
- errors . push ( new Error ( `The template string at ${ prop . name . getText ( sourceFile ) } can't have evaluated code ( no \${} allowed )` ) )
252
- } else {
253
- errors . push ( new Error ( `The value at ${ prop . name . getText ( sourceFile ) } isn't a string` ) )
245
+ /** @type {import("typescript").ObjectLiteralExpression } */
246
+ // @ts -ignore
247
+ const init = lastStatement . declarations [ 0 ] . initializer ;
248
+ if ( ! init ) {
249
+ errors . push ( new Error ( "Something is off in the const in that file" ) ) ;
250
+ } else {
251
+ init . properties . forEach ( ( prop ) => {
252
+ /** @type {import("typescript").PropertyAssignment } */
253
+ // @ts -ignore
254
+ const init = prop . initializer ;
255
+ if ( init . kind !== 10 && init . kind !== 14 ) {
256
+ if ( init . kind === 218 ) {
257
+ errors . push ( new Error ( `The template string at ${ prop . name . getText ( sourceFile ) } can't have evaluated code ( no \${} allowed )` ) ) ;
258
+ } else {
259
+ errors . push ( new Error ( `The value at ${ prop . name . getText ( sourceFile ) } isn't a string` ) ) ;
260
+ }
254
261
}
255
- }
256
- } ) ;
262
+ } ) ;
263
+ }
257
264
}
258
- // declarationList.declarations[0]
259
265
}
260
266
}
261
267
262
-
263
268
return errors . map ( ( e ) => ( { path : file , error : e } ) ) ;
264
-
265
269
}
0 commit comments