@marko/type-check 0.0.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/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Marko Type Check (@marko/type-check)
2
+
3
+ A CLI for running type checks on .marko, .ts, and .js files.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ npm install --save-dev @marko/type-check
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Use the `marko-type-check` or `mtc` command followed by options to run type checks on your project files:
14
+
15
+ ```terminal
16
+ marko-type-check [options]
17
+
18
+ # or with the shorthand
19
+ mtc [options]
20
+ ```
21
+
22
+ ## Options
23
+
24
+ | Option | Alias | Description | Default Value |
25
+ | ---------------- | ----- | ---------------------------------------------------------------------- | ---------------------------------- |
26
+ | --project <path> | -p | Path to the tsconfig or jsconfig file | ./tsconfig.json or ./jsconfig.json |
27
+ | --display <type> | -d | Set the display type for error output. Choices: codeframe or condensed | codeframe |
28
+ | --emit | -e | Emit .js, .d.ts, .marko (with types stripped), and .d.marko files | false |
29
+ | --help | -h | Display the help text | |
30
+ | --version | -v | Display the CLI version, Marko version, and TypeScript version | |
31
+
32
+ ## Examples
33
+
34
+ ### Run type check with the default tsconfig.json file:
35
+
36
+ ```
37
+ marko-type-check
38
+ ```
39
+
40
+ ### Run type check with a custom jsconfig.json file and condensed error output:
41
+
42
+ ```
43
+ mtc -p ./jsconfig.json -d condensed
44
+ ```
45
+
46
+ ### Run type check and emit output files:
47
+
48
+ ```
49
+ marko-type-check -e
50
+ ```
51
+
52
+ ## FAQ
53
+
54
+ ### What files are emitted with the `--emit` option?
55
+
56
+ The `emit` option outputs files similar to the [`tsc` cli](https://www.typescriptlang.org/docs/handbook/compiler-options.html). Meaning `.js` and `.d.ts` files will be output. Beyond that `.marko` files _with their types stripped_ and an associated `.d.marko` file will be output that serve a similar purpose to the `.js` and `.d.ts` files.
57
+
58
+ ### What is a `.d.marko` file?
59
+
60
+ A `.d.marko` files is similar to a `.d.ts` file. All script content in the file will be processed as if the Marko script-lang was typescript and the Marko-VSCode plugin and this CLI will both prefer loading a `.d.marko` over an adjacent `.marko` file. The `.d.marko` files output by this tool will strip out any runtime code such that only type information is in the `.d.marko` output.
61
+
62
+ ### Does this replace `tsc`?
63
+
64
+ Yes this replaces `tsc` since in order to provide proper type checking for `.marko` files the `.ts` and `.js` files must be processed as well.
65
+
66
+ ## Contributing
67
+
68
+ Contributions are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) for more information on how to contribute.
69
+
70
+ ## License
71
+
72
+ This project is licensed under the [MIT License](LICENSE).
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,598 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli.ts
27
+ var import_fs = __toESM(require("fs"));
28
+ var import_path2 = __toESM(require("path"));
29
+ var import_module = require("module");
30
+ var import_arg = __toESM(require("arg"));
31
+ var import_kleur2 = __toESM(require("kleur"));
32
+
33
+ // src/run.ts
34
+ var import_path = __toESM(require("path"));
35
+ var import_tsserverlibrary = __toESM(require("typescript/lib/tsserverlibrary"));
36
+ var import_kleur = __toESM(require("kleur"));
37
+ var import_code_frame = require("@babel/code-frame");
38
+ var import_language_tools = require("@marko/language-tools");
39
+ var Display = {
40
+ codeframe: "codeframe",
41
+ condensed: "condensed"
42
+ };
43
+ var currentDirectory = import_tsserverlibrary.default.sys.getCurrentDirectory();
44
+ var fsPathReg = /^(?:[./\\]|[A-Z]:)/i;
45
+ var modulePartsReg = /^((?:@(?:[^/]+)\/)?(?:[^/]+))(.*)$/;
46
+ var extractCache = /* @__PURE__ */ new WeakMap();
47
+ var requiredTSCompilerOptions = {
48
+ module: import_tsserverlibrary.default.ModuleKind.ESNext,
49
+ moduleResolution: import_tsserverlibrary.default.ModuleResolutionKind.Bundler,
50
+ allowJs: true,
51
+ declaration: true,
52
+ skipLibCheck: true,
53
+ isolatedModules: true,
54
+ allowNonTsExtensions: true
55
+ };
56
+ var requiredTSCompilerOptionsEmit = {
57
+ ...requiredTSCompilerOptions,
58
+ noEmit: false,
59
+ declaration: true,
60
+ emitDeclarationOnly: false
61
+ };
62
+ var requiredTSCompilerOptionsNoEmit = {
63
+ ...requiredTSCompilerOptions,
64
+ noEmit: true,
65
+ declaration: false,
66
+ emitDeclarationOnly: false
67
+ };
68
+ var defaultTSConfig = {
69
+ include: [],
70
+ compilerOptions: {
71
+ lib: ["dom", "node", "esnext"]
72
+ }
73
+ };
74
+ function run(opts) {
75
+ var _a;
76
+ const {
77
+ emit = false,
78
+ display = Display.codeframe,
79
+ project: configFile = findConfigFile("tsconfig.json") || findConfigFile("jsconfig.json")
80
+ } = opts;
81
+ if (!configFile)
82
+ throw new Error("Could not find tsconfig.json or jsconfig.json");
83
+ const { host, parsedCommandLine, getProcessor } = createCompilerHost(
84
+ configFile,
85
+ emit ? requiredTSCompilerOptionsEmit : requiredTSCompilerOptionsNoEmit
86
+ );
87
+ const formatSettings = import_tsserverlibrary.default.getDefaultFormatCodeSettings(
88
+ ((_a = host.getNewLine) == null ? void 0 : _a.call(host)) || import_tsserverlibrary.default.sys.newLine
89
+ );
90
+ const report = {
91
+ out: [],
92
+ display,
93
+ hasErrors: false,
94
+ formatSettings
95
+ };
96
+ const program = import_tsserverlibrary.default.createProgram({
97
+ host,
98
+ options: parsedCommandLine.options,
99
+ rootNames: parsedCommandLine.fileNames,
100
+ projectReferences: parsedCommandLine.projectReferences
101
+ });
102
+ reportDiagnostics(report, import_tsserverlibrary.default.getPreEmitDiagnostics(program));
103
+ if (!report.hasErrors) {
104
+ const typeChecker = program.getTypeChecker();
105
+ const printer = import_tsserverlibrary.default.createPrinter({
106
+ noEmitHelpers: true,
107
+ removeComments: true
108
+ });
109
+ const emitResult = program.emit(
110
+ void 0,
111
+ emit ? (fileName, _text, writeByteOrderMark, onError, sourceFiles, data) => {
112
+ const processor = (sourceFiles == null ? void 0 : sourceFiles.length) === 1 && getProcessor(sourceFiles[0].fileName) || void 0;
113
+ if (processor) {
114
+ const [sourceFile] = sourceFiles;
115
+ const processorExt = (0, import_language_tools.getExt)(sourceFile.fileName);
116
+ const inDtsExt = processorExt + import_tsserverlibrary.default.Extension.Dts;
117
+ const inJsExt = processorExt + import_tsserverlibrary.default.Extension.Js;
118
+ const inExt = fileName.endsWith(inDtsExt) ? inDtsExt : fileName.endsWith(inJsExt) ? inJsExt : void 0;
119
+ if (!inExt) {
120
+ throw new Error("Unexpected file extension: " + fileName);
121
+ }
122
+ const isDts = inExt === inDtsExt;
123
+ let outFileName = fileName;
124
+ if ((0, import_language_tools.isDefinitionFile)(sourceFile.fileName)) {
125
+ if (!isDts)
126
+ return;
127
+ outFileName = fileName.slice(0, -inExt.length) + processorExt;
128
+ } else {
129
+ if (isDts && program.getSourceFile(
130
+ `${sourceFile.fileName.slice(
131
+ 0,
132
+ -processorExt.length
133
+ )}.d${processorExt}`
134
+ )) {
135
+ return;
136
+ }
137
+ outFileName = fileName.slice(0, -inExt.length) + (isDts ? ".d" : "") + processorExt;
138
+ }
139
+ const extracted = extractCache.get(
140
+ program.getSourceFile(sourceFile.fileName)
141
+ );
142
+ const printContext = {
143
+ extracted,
144
+ printer,
145
+ typeChecker,
146
+ sourceFile,
147
+ formatSettings
148
+ };
149
+ host.writeFile(
150
+ outFileName,
151
+ isDts ? processor.printTypes(printContext).code : processor.print(printContext).code,
152
+ writeByteOrderMark,
153
+ onError,
154
+ sourceFiles,
155
+ data
156
+ );
157
+ } else {
158
+ host.writeFile(
159
+ fileName,
160
+ _text,
161
+ writeByteOrderMark,
162
+ onError,
163
+ sourceFiles,
164
+ data
165
+ );
166
+ }
167
+ } : void 0,
168
+ void 0,
169
+ false
170
+ );
171
+ reportDiagnostics(report, emitResult.diagnostics);
172
+ }
173
+ const lineSep = report.formatSettings.newLineCharacter + report.formatSettings.newLineCharacter;
174
+ console.log(report.out.join(lineSep));
175
+ process.exitCode = report.hasErrors ? 1 : 0;
176
+ }
177
+ function createCompilerHost(configFile, compilerOptions) {
178
+ const getProcessor = (fileName) => {
179
+ const ext = (0, import_language_tools.getExt)(fileName);
180
+ return ext ? processors[ext] : void 0;
181
+ };
182
+ const resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options, _containingSourceFile, _reusedNames) => {
183
+ return moduleLiterals.map((moduleLiteral) => {
184
+ return import_tsserverlibrary.default.bundlerModuleNameResolver(
185
+ moduleLiteral.text,
186
+ containingFile,
187
+ options,
188
+ host,
189
+ resolutionCache,
190
+ redirectedReference
191
+ );
192
+ });
193
+ };
194
+ const parsedCommandLine = import_tsserverlibrary.default.parseJsonConfigFileContent(
195
+ configFile && import_tsserverlibrary.default.readConfigFile(configFile, import_tsserverlibrary.default.sys.readFile).config || defaultTSConfig,
196
+ import_tsserverlibrary.default.sys,
197
+ currentDirectory,
198
+ compilerOptions,
199
+ configFile,
200
+ void 0,
201
+ import_language_tools.Processors.extensions.map((extension) => ({
202
+ extension,
203
+ isMixedContent: false,
204
+ scriptKind: import_tsserverlibrary.default.ScriptKind.Deferred
205
+ }))
206
+ );
207
+ const host = {
208
+ getDefaultLibFileName: import_tsserverlibrary.default.getDefaultLibFilePath,
209
+ writeFile: import_tsserverlibrary.default.sys.writeFile,
210
+ getCurrentDirectory: import_tsserverlibrary.default.sys.getCurrentDirectory,
211
+ getDirectories: import_tsserverlibrary.default.sys.getDirectories,
212
+ getCanonicalFileName: (fileName) => import_tsserverlibrary.default.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),
213
+ getNewLine: () => import_tsserverlibrary.default.sys.newLine,
214
+ useCaseSensitiveFileNames: () => import_tsserverlibrary.default.sys.useCaseSensitiveFileNames,
215
+ fileExists: import_tsserverlibrary.default.sys.fileExists,
216
+ readFile: import_tsserverlibrary.default.sys.readFile,
217
+ readDirectory: (path3, extensions, exclude, include, depth) => import_tsserverlibrary.default.sys.readDirectory(
218
+ path3,
219
+ extensions == null ? void 0 : extensions.concat(import_language_tools.Processors.extensions),
220
+ exclude,
221
+ include,
222
+ depth
223
+ ),
224
+ resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options, containingSourceFile, reusedNames) {
225
+ let normalModuleLiterals = moduleLiterals;
226
+ let resolvedModules;
227
+ for (let i = 0; i < moduleLiterals.length; i++) {
228
+ const moduleName = moduleLiterals[i].text;
229
+ const process2 = moduleName[0] !== "*" ? getProcessor(moduleName) : void 0;
230
+ if (process2) {
231
+ let resolvedFileName;
232
+ if (fsPathReg.test(moduleName)) {
233
+ resolvedFileName = import_path.default.resolve(containingFile, "..", moduleName);
234
+ } else {
235
+ const [, nodeModuleName, relativeModulePath] = modulePartsReg.exec(moduleName);
236
+ const { resolvedModule } = import_tsserverlibrary.default.resolveModuleName(
237
+ `${nodeModuleName}/package.json`,
238
+ containingFile,
239
+ options,
240
+ host,
241
+ resolutionCache
242
+ );
243
+ if (resolvedModule) {
244
+ resolvedFileName = import_path.default.join(
245
+ resolvedModule.resolvedFileName,
246
+ "..",
247
+ relativeModulePath
248
+ );
249
+ }
250
+ }
251
+ if (!resolvedModules) {
252
+ resolvedModules = [];
253
+ normalModuleLiterals = [];
254
+ for (let j = 0; j < i; j++) {
255
+ resolvedModules.push(void 0);
256
+ normalModuleLiterals.push(moduleLiterals[j]);
257
+ }
258
+ }
259
+ if (resolvedFileName) {
260
+ if ((0, import_language_tools.isDefinitionFile)(resolvedFileName)) {
261
+ if (!host.fileExists(resolvedFileName)) {
262
+ resolvedFileName = void 0;
263
+ }
264
+ } else {
265
+ const ext = (0, import_language_tools.getExt)(resolvedFileName);
266
+ const definitionFile = `${resolvedFileName.slice(
267
+ 0,
268
+ -ext.length
269
+ )}.d${ext}`;
270
+ if (host.fileExists(definitionFile)) {
271
+ resolvedFileName = definitionFile;
272
+ } else if (!host.fileExists(resolvedFileName)) {
273
+ resolvedFileName = void 0;
274
+ }
275
+ }
276
+ }
277
+ resolvedModules.push({
278
+ resolvedModule: resolvedFileName ? {
279
+ resolvedFileName,
280
+ extension: process2.getScriptExtension(resolvedFileName),
281
+ isExternalLibraryImport: false
282
+ } : void 0
283
+ });
284
+ } else if (resolvedModules) {
285
+ resolvedModules.push(void 0);
286
+ }
287
+ }
288
+ const normalResolvedModules = normalModuleLiterals.length ? resolveModuleNameLiterals(
289
+ normalModuleLiterals,
290
+ containingFile,
291
+ redirectedReference,
292
+ options,
293
+ containingSourceFile,
294
+ reusedNames
295
+ ) : void 0;
296
+ if (resolvedModules) {
297
+ if (normalResolvedModules) {
298
+ for (let i = 0, j = 0; i < resolvedModules.length; i++) {
299
+ if (!resolvedModules[i]) {
300
+ resolvedModules[i] = normalResolvedModules[j++];
301
+ }
302
+ }
303
+ }
304
+ return resolvedModules;
305
+ } else {
306
+ return normalResolvedModules;
307
+ }
308
+ },
309
+ getSourceFile: (fileName, languageVersion) => {
310
+ const processor = getProcessor(fileName);
311
+ const code = host.readFile(fileName);
312
+ if (code !== void 0) {
313
+ if (processor) {
314
+ const extracted = processor.extract(fileName, code);
315
+ const sourceFile = import_tsserverlibrary.default.createSourceFile(
316
+ fileName,
317
+ extracted.toString(),
318
+ languageVersion,
319
+ true,
320
+ processor.getScriptKind(fileName)
321
+ );
322
+ extractCache.set(sourceFile, extracted);
323
+ return sourceFile;
324
+ }
325
+ return import_tsserverlibrary.default.createSourceFile(fileName, code, languageVersion, true);
326
+ }
327
+ }
328
+ };
329
+ const resolutionCache = import_tsserverlibrary.default.createModuleResolutionCache(
330
+ currentDirectory,
331
+ host.getCanonicalFileName,
332
+ parsedCommandLine.options
333
+ );
334
+ const processors = import_language_tools.Processors.create({
335
+ ts: import_tsserverlibrary.default,
336
+ host,
337
+ configFile
338
+ });
339
+ parsedCommandLine.fileNames = [
340
+ ...new Set(
341
+ parsedCommandLine.fileNames.concat(
342
+ Object.values(processors).map((processor) => {
343
+ var _a;
344
+ return (_a = processor.getRootNames) == null ? void 0 : _a.call(processor);
345
+ }).flat().filter(Boolean)
346
+ )
347
+ )
348
+ ];
349
+ return {
350
+ host,
351
+ parsedCommandLine,
352
+ getProcessor
353
+ };
354
+ }
355
+ function reportDiagnostics(report, diags) {
356
+ for (const diag of diags) {
357
+ if (diag.file && diag.start !== void 0) {
358
+ const extracted = extractCache.get(diag.file);
359
+ let code = diag.file.text;
360
+ let loc;
361
+ if (extracted) {
362
+ loc = extracted.sourceLocationAt(
363
+ diag.start,
364
+ diag.start + (diag.length || 0)
365
+ );
366
+ code = extracted.parsed.code;
367
+ if (!loc)
368
+ continue;
369
+ } else {
370
+ const start = import_tsserverlibrary.default.getLineAndCharacterOfPosition(diag.file, diag.start);
371
+ const end = diag.length ? import_tsserverlibrary.default.getLineAndCharacterOfPosition(
372
+ diag.file,
373
+ diag.start + diag.length
374
+ ) : start;
375
+ loc = {
376
+ start,
377
+ end
378
+ };
379
+ }
380
+ if (diag.category === import_tsserverlibrary.default.DiagnosticCategory.Error) {
381
+ report.hasErrors = true;
382
+ }
383
+ const diagMessage = flattenDiagnosticMessage(
384
+ diag.messageText,
385
+ report.display,
386
+ report.formatSettings.newLineCharacter
387
+ );
388
+ report.out.push(
389
+ `${import_kleur.default.cyan(
390
+ import_path.default.relative(currentDirectory, diag.file.fileName)
391
+ )}:${import_kleur.default.yellow(loc.start.line + 1)}:${import_kleur.default.yellow(
392
+ loc.start.character + 1
393
+ )} - ${coloredDiagnosticCategory(diag.category)} ${import_kleur.default.dim(
394
+ `TS${diag.code}`
395
+ )}${report.formatSettings.newLineCharacter}${report.display === Display.codeframe ? report.formatSettings.newLineCharacter + formatCodeFrameMessage(code, loc, diagMessage) : diagMessage}`
396
+ );
397
+ } else {
398
+ if (diag.category === import_tsserverlibrary.default.DiagnosticCategory.Error) {
399
+ report.hasErrors = true;
400
+ }
401
+ report.out.push(
402
+ flattenDiagnosticMessage(
403
+ diag.messageText,
404
+ report.display,
405
+ report.formatSettings.newLineCharacter
406
+ )
407
+ );
408
+ }
409
+ if (diag.relatedInformation && report.display === Display.codeframe) {
410
+ reportRelatedDiagnostics(report, diag.relatedInformation);
411
+ }
412
+ }
413
+ }
414
+ function reportRelatedDiagnostics(report, diags) {
415
+ for (const diag of diags) {
416
+ if (diag.file && diag.start) {
417
+ const extracted = extractCache.get(diag.file);
418
+ let code = diag.file.text;
419
+ let loc;
420
+ if (extracted) {
421
+ loc = extracted.sourceLocationAt(
422
+ diag.start,
423
+ diag.start + (diag.length || 0)
424
+ );
425
+ code = extracted.parsed.code;
426
+ } else {
427
+ const start = import_tsserverlibrary.default.getLineAndCharacterOfPosition(diag.file, diag.start);
428
+ const end = diag.length ? import_tsserverlibrary.default.getLineAndCharacterOfPosition(
429
+ diag.file,
430
+ diag.start + diag.length
431
+ ) : start;
432
+ loc = {
433
+ start,
434
+ end
435
+ };
436
+ }
437
+ if (loc) {
438
+ report.out.push(
439
+ formatCodeFrameMessage(
440
+ code,
441
+ loc,
442
+ `${flattenDiagnosticMessage(
443
+ diag.messageText,
444
+ report.display,
445
+ report.formatSettings.newLineCharacter
446
+ )} @ ${import_path.default.relative(currentDirectory, diag.file.fileName)}:${loc.start.line + 1}:${loc.start.character + 1}`
447
+ )
448
+ );
449
+ }
450
+ } else {
451
+ report.out.push(
452
+ flattenDiagnosticMessage(
453
+ diag.messageText,
454
+ report.display,
455
+ report.formatSettings.newLineCharacter
456
+ )
457
+ );
458
+ }
459
+ }
460
+ }
461
+ function formatCodeFrameMessage(code, loc, message) {
462
+ return (0, import_code_frame.codeFrameColumns)(
463
+ code,
464
+ {
465
+ start: {
466
+ line: loc.start.line + 1,
467
+ column: loc.start.character + 1
468
+ },
469
+ end: {
470
+ line: loc.end.line + 1,
471
+ column: loc.end.character + 1
472
+ }
473
+ },
474
+ {
475
+ highlightCode: true,
476
+ message
477
+ }
478
+ );
479
+ }
480
+ function flattenDiagnosticMessage(message, display, newLine) {
481
+ const str = import_tsserverlibrary.default.flattenDiagnosticMessageText(message, newLine);
482
+ const strWithNewlines = str.replace(/(?:\r?\n)[ \t]+/g, newLine);
483
+ return str === strWithNewlines ? str : (display === Display.codeframe ? newLine : "") + strWithNewlines;
484
+ }
485
+ function coloredDiagnosticCategory(category) {
486
+ switch (category) {
487
+ case import_tsserverlibrary.default.DiagnosticCategory.Error:
488
+ return import_kleur.default.red("error");
489
+ case import_tsserverlibrary.default.DiagnosticCategory.Warning:
490
+ return import_kleur.default.yellow("warning");
491
+ case import_tsserverlibrary.default.DiagnosticCategory.Message:
492
+ return import_kleur.default.blue("message");
493
+ case import_tsserverlibrary.default.DiagnosticCategory.Suggestion:
494
+ return import_kleur.default.magenta("suggestion");
495
+ default:
496
+ return import_kleur.default.red(
497
+ (import_tsserverlibrary.default.DiagnosticCategory[category] || "unknown").toLocaleLowerCase()
498
+ );
499
+ }
500
+ }
501
+ function findConfigFile(name) {
502
+ return import_tsserverlibrary.default.findConfigFile(currentDirectory, import_tsserverlibrary.default.sys.fileExists, name);
503
+ }
504
+
505
+ // src/cli.ts
506
+ var args = (0, import_arg.default)(
507
+ {
508
+ "--project": String,
509
+ "--display": String,
510
+ "--emit": Boolean,
511
+ "--help": Boolean,
512
+ "--version": Boolean,
513
+ "-p": "--project",
514
+ "-d": "--display",
515
+ "-e": "--emit",
516
+ "-h": "--help",
517
+ "-v": "--version"
518
+ },
519
+ { permissive: false, argv: process.argv.slice(2) }
520
+ );
521
+ if (args["--help"]) {
522
+ console.log(`${import_kleur2.default.bold(
523
+ `Usage: ${import_kleur2.default.cyan("marko-type-check")} ${import_kleur2.default.magenta(
524
+ `[options]`
525
+ )} | ${import_kleur2.default.cyan("mtc")} ${import_kleur2.default.magenta(`[options]`)}
526
+ `
527
+ )}
528
+ A command-line interface for running type checks on .marko, .ts, and .js files.
529
+
530
+ ${import_kleur2.default.bold("Options:")}
531
+ ${import_kleur2.default.yellow("-p, --project")} ${import_kleur2.default.magenta(
532
+ "<path>"
533
+ )} Path to the tsconfig or jsconfig file (default: ${import_kleur2.default.green(
534
+ `"./tsconfig.json"`
535
+ )} or ${import_kleur2.default.green(`"./jsconfig.json"`)})
536
+ ${import_kleur2.default.yellow("-d, --display")} ${import_kleur2.default.magenta(
537
+ "<type>"
538
+ )} Set the display type for error output. Choices: ${import_kleur2.default.green(
539
+ `"codeframe"`
540
+ )} or ${import_kleur2.default.green(`"condensed"`)} (default: ${import_kleur2.default.green(`"codeframe"`)})
541
+ ${import_kleur2.default.yellow(
542
+ "-e, --emit"
543
+ )} Emit .js, .d.ts, .marko (with types stripped), and .d.marko files (default: ${import_kleur2.default.magenta(
544
+ "false"
545
+ )})
546
+ ${import_kleur2.default.yellow(
547
+ "-v, --version"
548
+ )} Display the CLI version, Marko version, and TypeScript version
549
+ ${import_kleur2.default.yellow("-h, --help")} Display this help text
550
+
551
+ ${import_kleur2.default.bold("Examples:")}
552
+ ${import_kleur2.default.cyan("marko-type-check")} --project ./tsconfig.json
553
+ ${import_kleur2.default.cyan("mtc")} -p ./jsconfig.json -d condensed -e
554
+
555
+ For more information, visit ${import_kleur2.default.blue(
556
+ "https://github.com/marko-js/language-server/tree/main/packages/marko-type-check"
557
+ )}
558
+ `);
559
+ } else if (args["--version"]) {
560
+ const require2 = (0, import_module.createRequire)(__dirname);
561
+ const getPackageVersion = (id) => {
562
+ try {
563
+ return `${id} v${require2(`${id}/package.json`).version}`;
564
+ } catch {
565
+ return `${id} unknown version`;
566
+ }
567
+ };
568
+ console.log(
569
+ `marko-type-check v${require2("../package.json").version} (${[
570
+ getPackageVersion("marko"),
571
+ getPackageVersion("@marko/compiler"),
572
+ getPackageVersion("typescript")
573
+ ].join(", ")})`
574
+ );
575
+ } else {
576
+ const {
577
+ "--emit": emit,
578
+ "--display": display = process.env.CI ? Display.condensed : Display.codeframe
579
+ } = args;
580
+ let { "--project": project } = args;
581
+ if (project) {
582
+ project = import_path2.default.resolve(process.cwd(), project);
583
+ if (!import_fs.default.existsSync(project)) {
584
+ throw new Error(`Project path does not exist: ${project}`);
585
+ }
586
+ }
587
+ checkDisplay(display);
588
+ run({ project, display, emit });
589
+ }
590
+ function checkDisplay(display) {
591
+ if (display && Display[display] === void 0) {
592
+ throw new Error(
593
+ `Invalid display option, must be one of: ${Object.values(Display).join(
594
+ ", "
595
+ )}`
596
+ );
597
+ }
598
+ }
package/dist/run.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export declare const Display: {
2
+ readonly codeframe: "codeframe";
3
+ readonly condensed: "condensed";
4
+ };
5
+ export type Display = (typeof Display)[keyof typeof Display];
6
+ export interface Options {
7
+ project?: string;
8
+ display?: Display;
9
+ emit?: boolean;
10
+ }
11
+ export default function run(opts: Options): void;
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@marko/type-check",
3
+ "description": "A CLI to type check Marko projects",
4
+ "version": "0.0.1",
5
+ "bugs": "https://github.com/marko-js/language-server/issues/new?template=Bug_report.md",
6
+ "dependencies": {
7
+ "@babel/code-frame": "^7.18.6",
8
+ "@marko/language-tools": "^2.0.0",
9
+ "arg": "^5.0.2",
10
+ "kleur": "^4.1.5",
11
+ "strip-json-comments": "^5.0.0",
12
+ "typescript": "5.0.2"
13
+ },
14
+ "devDependencies": {
15
+ "@types/babel__code-frame": "^7.0.3"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "!**/__tests__",
20
+ "!**/*.tsbuildinfo"
21
+ ],
22
+ "homepage": "https://github.com/marko-js/language-server/tree/main/packages/type-check/README.md",
23
+ "keywords": [
24
+ "type-check",
25
+ "marko",
26
+ "tsc",
27
+ "typescript",
28
+ "tools"
29
+ ],
30
+ "license": "MIT",
31
+ "bin": {
32
+ "marko-type-check": "dist/cli.js",
33
+ "mtc": "dist/cli.js"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/marko-js/language-server/tree/main/packages/type-check"
38
+ },
39
+ "scripts": {
40
+ "build": "tsc -b && tsx build.mts"
41
+ }
42
+ }