@danielx/civet 0.6.37 → 0.6.39

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.
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var ts_diagnostic_exports = {};
30
+ __export(ts_diagnostic_exports, {
31
+ convertDiagnostic: () => convertDiagnostic,
32
+ flattenDiagnosticMessageText: () => flattenDiagnosticMessageText,
33
+ rangeFromTextSpan: () => rangeFromTextSpan,
34
+ remapPosition: () => remapPosition,
35
+ remapRange: () => remapRange
36
+ });
37
+ module.exports = __toCommonJS(ts_diagnostic_exports);
38
+ var import_vscode_languageserver = __toESM(require("vscode-languageserver"));
39
+ var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
40
+ let DiagnosticCategory = {};
41
+ DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
42
+ DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
43
+ DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion";
44
+ DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message";
45
+ function remapPosition(position, sourcemapLines) {
46
+ if (!sourcemapLines)
47
+ return position;
48
+ const { line, character } = position;
49
+ const textLine = sourcemapLines[line];
50
+ if (!textLine?.length)
51
+ return position;
52
+ let i = 0, p = 0, l = textLine.length, lastMapping, lastMappingPosition = 0;
53
+ while (i < l) {
54
+ const mapping = textLine[i];
55
+ p += mapping[0];
56
+ if (mapping.length === 4) {
57
+ lastMapping = mapping;
58
+ lastMappingPosition = p;
59
+ }
60
+ if (p >= character) {
61
+ break;
62
+ }
63
+ i++;
64
+ }
65
+ if (lastMapping) {
66
+ const srcLine = lastMapping[2];
67
+ const srcChar = lastMapping[3];
68
+ const newChar = srcChar + character - lastMappingPosition;
69
+ return {
70
+ line: srcLine,
71
+ character: newChar
72
+ };
73
+ } else {
74
+ return position;
75
+ }
76
+ }
77
+ function remapRange(range, sourcemapLines) {
78
+ return {
79
+ start: remapPosition(range.start, sourcemapLines),
80
+ end: remapPosition(range.end, sourcemapLines)
81
+ };
82
+ }
83
+ function flattenDiagnosticMessageText(diag, indent = 0) {
84
+ if (typeof diag === "string") {
85
+ return diag;
86
+ } else if (diag === void 0) {
87
+ return "";
88
+ }
89
+ let result = "";
90
+ if (indent) {
91
+ result += "\n";
92
+ for (let i = 0; i < indent; i++) {
93
+ result += " ";
94
+ }
95
+ }
96
+ result += diag.messageText;
97
+ indent++;
98
+ if (diag.next) {
99
+ for (const kid of diag.next) {
100
+ result += flattenDiagnosticMessageText(kid, indent);
101
+ }
102
+ }
103
+ return result;
104
+ }
105
+ function rangeFromTextSpan(span, document) {
106
+ return {
107
+ start: document.positionAt(span.start),
108
+ end: document.positionAt(span.start + span.length)
109
+ };
110
+ }
111
+ function convertDiagnostic(diagnostic, document, sourcemapLines) {
112
+ return {
113
+ message: flattenDiagnosticMessageText(diagnostic.messageText),
114
+ range: remapRange(
115
+ rangeFromTextSpan(
116
+ {
117
+ start: diagnostic.start || 0,
118
+ length: diagnostic.length ?? 1
119
+ },
120
+ document
121
+ ),
122
+ sourcemapLines
123
+ ),
124
+ severity: diagnosticCategoryToSeverity(diagnostic.category),
125
+ code: diagnostic.code,
126
+ source: diagnostic.source || "typescript"
127
+ };
128
+ }
129
+ function diagnosticCategoryToSeverity(category) {
130
+ switch (category) {
131
+ case DiagnosticCategory.Warning: {
132
+ return import_vscode_languageserver.DiagnosticSeverity.Warning;
133
+ }
134
+ case DiagnosticCategory.Error: {
135
+ return import_vscode_languageserver.DiagnosticSeverity.Error;
136
+ }
137
+ case DiagnosticCategory.Suggestion: {
138
+ return import_vscode_languageserver.DiagnosticSeverity.Hint;
139
+ }
140
+ case DiagnosticCategory.Message: {
141
+ return import_vscode_languageserver.DiagnosticSeverity.Information;
142
+ }
143
+ }
144
+ }
145
+ // Annotate the CommonJS export names for ESM import in node:
146
+ 0 && (module.exports = {
147
+ convertDiagnostic,
148
+ flattenDiagnosticMessageText,
149
+ rangeFromTextSpan,
150
+ remapPosition,
151
+ remapRange
152
+ });
@@ -0,0 +1,114 @@
1
+ let DiagnosticCategory = {};
2
+ DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
3
+ DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
4
+ DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion";
5
+ DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message";
6
+ import vs, { DiagnosticSeverity, Position, Range } from "vscode-languageserver";
7
+ import { TextDocument } from "vscode-languageserver-textdocument";
8
+ function remapPosition(position, sourcemapLines) {
9
+ if (!sourcemapLines)
10
+ return position;
11
+ const { line, character } = position;
12
+ const textLine = sourcemapLines[line];
13
+ if (!textLine?.length)
14
+ return position;
15
+ let i = 0, p = 0, l = textLine.length, lastMapping, lastMappingPosition = 0;
16
+ while (i < l) {
17
+ const mapping = textLine[i];
18
+ p += mapping[0];
19
+ if (mapping.length === 4) {
20
+ lastMapping = mapping;
21
+ lastMappingPosition = p;
22
+ }
23
+ if (p >= character) {
24
+ break;
25
+ }
26
+ i++;
27
+ }
28
+ if (lastMapping) {
29
+ const srcLine = lastMapping[2];
30
+ const srcChar = lastMapping[3];
31
+ const newChar = srcChar + character - lastMappingPosition;
32
+ return {
33
+ line: srcLine,
34
+ character: newChar
35
+ };
36
+ } else {
37
+ return position;
38
+ }
39
+ }
40
+ function remapRange(range, sourcemapLines) {
41
+ return {
42
+ start: remapPosition(range.start, sourcemapLines),
43
+ end: remapPosition(range.end, sourcemapLines)
44
+ };
45
+ }
46
+ function flattenDiagnosticMessageText(diag, indent = 0) {
47
+ if (typeof diag === "string") {
48
+ return diag;
49
+ } else if (diag === void 0) {
50
+ return "";
51
+ }
52
+ let result = "";
53
+ if (indent) {
54
+ result += "\n";
55
+ for (let i = 0; i < indent; i++) {
56
+ result += " ";
57
+ }
58
+ }
59
+ result += diag.messageText;
60
+ indent++;
61
+ if (diag.next) {
62
+ for (const kid of diag.next) {
63
+ result += flattenDiagnosticMessageText(kid, indent);
64
+ }
65
+ }
66
+ return result;
67
+ }
68
+ function rangeFromTextSpan(span, document) {
69
+ return {
70
+ start: document.positionAt(span.start),
71
+ end: document.positionAt(span.start + span.length)
72
+ };
73
+ }
74
+ function convertDiagnostic(diagnostic, document, sourcemapLines) {
75
+ return {
76
+ message: flattenDiagnosticMessageText(diagnostic.messageText),
77
+ range: remapRange(
78
+ rangeFromTextSpan(
79
+ {
80
+ start: diagnostic.start || 0,
81
+ length: diagnostic.length ?? 1
82
+ },
83
+ document
84
+ ),
85
+ sourcemapLines
86
+ ),
87
+ severity: diagnosticCategoryToSeverity(diagnostic.category),
88
+ code: diagnostic.code,
89
+ source: diagnostic.source || "typescript"
90
+ };
91
+ }
92
+ function diagnosticCategoryToSeverity(category) {
93
+ switch (category) {
94
+ case DiagnosticCategory.Warning: {
95
+ return DiagnosticSeverity.Warning;
96
+ }
97
+ case DiagnosticCategory.Error: {
98
+ return DiagnosticSeverity.Error;
99
+ }
100
+ case DiagnosticCategory.Suggestion: {
101
+ return DiagnosticSeverity.Hint;
102
+ }
103
+ case DiagnosticCategory.Message: {
104
+ return DiagnosticSeverity.Information;
105
+ }
106
+ }
107
+ }
108
+ export {
109
+ convertDiagnostic,
110
+ flattenDiagnosticMessageText,
111
+ rangeFromTextSpan,
112
+ remapPosition,
113
+ remapRange
114
+ };
@@ -1,6 +1,12 @@
1
1
  // src/index.ts
2
- import { createUnplugin } from "unplugin";
2
+ import {
3
+ createUnplugin
4
+ } from "unplugin";
3
5
  import civet from "@danielx/civet";
6
+ import {
7
+ remapRange,
8
+ flattenDiagnosticMessageText
9
+ } from "@danielx/civet/ts-diagnostic";
4
10
  import * as fs from "fs";
5
11
  import path from "path";
6
12
  import ts from "typescript";
@@ -16,15 +22,19 @@ var civetUnplugin = createUnplugin((options = {}) => {
16
22
  if (options.dts && options.js) {
17
23
  throw new Error("Can't have both `dts` and `js` be set to `true`.");
18
24
  }
19
- const transpileToJS = options.js ?? !options.dts;
25
+ if (options.typecheck && options.js) {
26
+ throw new Error("Can't have both `typecheck` and `js` be set to `true`.");
27
+ }
28
+ const transpileToJS = options.js ?? !(options.dts || options.typecheck);
20
29
  const outExt = options.outputExtension ?? (transpileToJS ? ".jsx" : ".tsx");
21
30
  let fsMap = /* @__PURE__ */ new Map();
31
+ const sourceMaps = /* @__PURE__ */ new Map();
22
32
  let compilerOptions;
23
33
  return {
24
34
  name: "unplugin-civet",
25
35
  enforce: "pre",
26
36
  async buildStart() {
27
- if (options.dts) {
37
+ if (options.dts || options.typecheck) {
28
38
  const configPath = ts.findConfigFile(process.cwd(), ts.sys.fileExists);
29
39
  if (!configPath) {
30
40
  throw new Error("Could not find 'tsconfig.json'");
@@ -50,7 +60,7 @@ var civetUnplugin = createUnplugin((options = {}) => {
50
60
  }
51
61
  },
52
62
  buildEnd() {
53
- if (options.dts) {
63
+ if (options.dts || options.typecheck) {
54
64
  const system = tsvfs.createFSBackedSystem(fsMap, process.cwd(), ts);
55
65
  const host = tsvfs.createVirtualCompilerHost(
56
66
  system,
@@ -62,20 +72,55 @@ var civetUnplugin = createUnplugin((options = {}) => {
62
72
  options: compilerOptions,
63
73
  host: host.compilerHost
64
74
  });
65
- for (const file of fsMap.keys()) {
66
- const sourceFile = program.getSourceFile(file);
67
- program.emit(
68
- sourceFile,
69
- (filePath, content) => {
70
- this.emitFile({
71
- source: content,
72
- fileName: path.relative(process.cwd(), filePath),
73
- type: "asset"
74
- });
75
+ const diagnostics = ts.getPreEmitDiagnostics(program).map((diagnostic) => {
76
+ const file = diagnostic.file;
77
+ if (!file)
78
+ return diagnostic;
79
+ const sourceMap = sourceMaps.get(file.fileName);
80
+ if (!sourceMap)
81
+ return diagnostic;
82
+ const sourcemapLines = sourceMap.data.lines;
83
+ const range = remapRange(
84
+ {
85
+ start: diagnostic.start || 0,
86
+ end: (diagnostic.start || 0) + (diagnostic.length || 1)
75
87
  },
76
- void 0,
77
- true
88
+ sourcemapLines
78
89
  );
90
+ return {
91
+ ...diagnostic,
92
+ messageText: flattenDiagnosticMessageText(diagnostic.messageText),
93
+ length: diagnostic.length,
94
+ start: range.start
95
+ };
96
+ });
97
+ if (diagnostics.length > 0) {
98
+ console.error(
99
+ ts.formatDiagnosticsWithColorAndContext(diagnostics, formatHost)
100
+ );
101
+ }
102
+ if (options.dts) {
103
+ for (const file of fsMap.keys()) {
104
+ const sourceFile = program.getSourceFile(file);
105
+ program.emit(
106
+ sourceFile,
107
+ async (filePath, content) => {
108
+ const dir = path.dirname(filePath);
109
+ await fs.promises.mkdir(dir, { recursive: true });
110
+ const pathFromDistDir = path.relative(
111
+ compilerOptions.outDir ?? process.cwd(),
112
+ filePath
113
+ );
114
+ this.emitFile({
115
+ source: content,
116
+ fileName: pathFromDistDir,
117
+ type: "asset"
118
+ });
119
+ },
120
+ void 0,
121
+ true
122
+ );
123
+ }
79
124
  }
80
125
  }
81
126
  },
@@ -99,13 +144,20 @@ var civetUnplugin = createUnplugin((options = {}) => {
99
144
  return null;
100
145
  const filename = path.resolve(process.cwd(), id.slice(0, -outExt.length));
101
146
  const code = await fs.promises.readFile(filename, "utf-8");
147
+ const compiled = civet.compile(code, {
148
+ // inlineMap: true,
149
+ filename: id,
150
+ js: transpileToJS,
151
+ sourceMap: true
152
+ });
153
+ sourceMaps.set(path.resolve(process.cwd(), id), compiled.sourceMap);
154
+ const jsonSourceMap = compiled.sourceMap.json(
155
+ path.basename(id.replace(/\.[jt]sx$/, "")),
156
+ path.basename(id)
157
+ );
102
158
  let transformed = {
103
- code: civet.compile(code, {
104
- inlineMap: true,
105
- filename: id,
106
- js: transpileToJS
107
- }),
108
- map: null
159
+ code: compiled.code,
160
+ map: jsonSourceMap
109
161
  };
110
162
  if (options.transformOutput)
111
163
  transformed = await options.transformOutput(transformed.code, id);
@@ -114,8 +166,12 @@ var civetUnplugin = createUnplugin((options = {}) => {
114
166
  transform(code, id) {
115
167
  if (!/\.civet\.tsx?$/.test(id))
116
168
  return null;
117
- if (options.dts) {
118
- fsMap.set(path.resolve(process.cwd(), id), code);
169
+ if (options.dts || options.typecheck) {
170
+ const resolved = path.resolve(process.cwd(), id);
171
+ fsMap.set(resolved, code);
172
+ const slash = resolved.replace(/\\/g, "/");
173
+ if (resolved !== slash)
174
+ fsMap.set(slash, code);
119
175
  }
120
176
  return null;
121
177
  },
@@ -6,9 +6,11 @@ type PluginOptions = {
6
6
  transformOutput?: (code: string, id: string) => TransformResult | Promise<TransformResult>;
7
7
  } & ({
8
8
  dts?: false;
9
+ typecheck?: false;
9
10
  js?: false | true;
10
11
  } | {
11
12
  dts?: true;
13
+ typecheck?: true;
12
14
  js?: false;
13
15
  });
14
16
  declare const civetUnplugin: unplugin.UnpluginInstance<PluginOptions, boolean>;
@@ -6,9 +6,11 @@ type PluginOptions = {
6
6
  transformOutput?: (code: string, id: string) => TransformResult | Promise<TransformResult>;
7
7
  } & ({
8
8
  dts?: false;
9
+ typecheck?: false;
9
10
  js?: false | true;
10
11
  } | {
11
12
  dts?: true;
13
+ typecheck?: true;
12
14
  js?: false;
13
15
  });
14
16
  declare const civetUnplugin: unplugin.UnpluginInstance<PluginOptions, boolean>;
package/dist/unplugin.js CHANGED
@@ -35,6 +35,7 @@ __export(src_exports, {
35
35
  module.exports = __toCommonJS(src_exports);
36
36
  var import_unplugin = require("unplugin");
37
37
  var import_civet = __toESM(require("@danielx/civet"));
38
+ var import_ts_diagnostic = require("@danielx/civet/ts-diagnostic");
38
39
  var fs = __toESM(require("fs"));
39
40
  var import_path = __toESM(require("path"));
40
41
  var import_typescript = __toESM(require("typescript"));
@@ -50,15 +51,19 @@ var civetUnplugin = (0, import_unplugin.createUnplugin)((options = {}) => {
50
51
  if (options.dts && options.js) {
51
52
  throw new Error("Can't have both `dts` and `js` be set to `true`.");
52
53
  }
53
- const transpileToJS = options.js ?? !options.dts;
54
+ if (options.typecheck && options.js) {
55
+ throw new Error("Can't have both `typecheck` and `js` be set to `true`.");
56
+ }
57
+ const transpileToJS = options.js ?? !(options.dts || options.typecheck);
54
58
  const outExt = options.outputExtension ?? (transpileToJS ? ".jsx" : ".tsx");
55
59
  let fsMap = /* @__PURE__ */ new Map();
60
+ const sourceMaps = /* @__PURE__ */ new Map();
56
61
  let compilerOptions;
57
62
  return {
58
63
  name: "unplugin-civet",
59
64
  enforce: "pre",
60
65
  async buildStart() {
61
- if (options.dts) {
66
+ if (options.dts || options.typecheck) {
62
67
  const configPath = import_typescript.default.findConfigFile(process.cwd(), import_typescript.default.sys.fileExists);
63
68
  if (!configPath) {
64
69
  throw new Error("Could not find 'tsconfig.json'");
@@ -84,7 +89,7 @@ var civetUnplugin = (0, import_unplugin.createUnplugin)((options = {}) => {
84
89
  }
85
90
  },
86
91
  buildEnd() {
87
- if (options.dts) {
92
+ if (options.dts || options.typecheck) {
88
93
  const system = tsvfs.createFSBackedSystem(fsMap, process.cwd(), import_typescript.default);
89
94
  const host = tsvfs.createVirtualCompilerHost(
90
95
  system,
@@ -96,20 +101,55 @@ var civetUnplugin = (0, import_unplugin.createUnplugin)((options = {}) => {
96
101
  options: compilerOptions,
97
102
  host: host.compilerHost
98
103
  });
99
- for (const file of fsMap.keys()) {
100
- const sourceFile = program.getSourceFile(file);
101
- program.emit(
102
- sourceFile,
103
- (filePath, content) => {
104
- this.emitFile({
105
- source: content,
106
- fileName: import_path.default.relative(process.cwd(), filePath),
107
- type: "asset"
108
- });
104
+ const diagnostics = import_typescript.default.getPreEmitDiagnostics(program).map((diagnostic) => {
105
+ const file = diagnostic.file;
106
+ if (!file)
107
+ return diagnostic;
108
+ const sourceMap = sourceMaps.get(file.fileName);
109
+ if (!sourceMap)
110
+ return diagnostic;
111
+ const sourcemapLines = sourceMap.data.lines;
112
+ const range = (0, import_ts_diagnostic.remapRange)(
113
+ {
114
+ start: diagnostic.start || 0,
115
+ end: (diagnostic.start || 0) + (diagnostic.length || 1)
109
116
  },
110
- void 0,
111
- true
117
+ sourcemapLines
112
118
  );
119
+ return {
120
+ ...diagnostic,
121
+ messageText: (0, import_ts_diagnostic.flattenDiagnosticMessageText)(diagnostic.messageText),
122
+ length: diagnostic.length,
123
+ start: range.start
124
+ };
125
+ });
126
+ if (diagnostics.length > 0) {
127
+ console.error(
128
+ import_typescript.default.formatDiagnosticsWithColorAndContext(diagnostics, formatHost)
129
+ );
130
+ }
131
+ if (options.dts) {
132
+ for (const file of fsMap.keys()) {
133
+ const sourceFile = program.getSourceFile(file);
134
+ program.emit(
135
+ sourceFile,
136
+ async (filePath, content) => {
137
+ const dir = import_path.default.dirname(filePath);
138
+ await fs.promises.mkdir(dir, { recursive: true });
139
+ const pathFromDistDir = import_path.default.relative(
140
+ compilerOptions.outDir ?? process.cwd(),
141
+ filePath
142
+ );
143
+ this.emitFile({
144
+ source: content,
145
+ fileName: pathFromDistDir,
146
+ type: "asset"
147
+ });
148
+ },
149
+ void 0,
150
+ true
151
+ );
152
+ }
113
153
  }
114
154
  }
115
155
  },
@@ -133,13 +173,20 @@ var civetUnplugin = (0, import_unplugin.createUnplugin)((options = {}) => {
133
173
  return null;
134
174
  const filename = import_path.default.resolve(process.cwd(), id.slice(0, -outExt.length));
135
175
  const code = await fs.promises.readFile(filename, "utf-8");
176
+ const compiled = import_civet.default.compile(code, {
177
+ // inlineMap: true,
178
+ filename: id,
179
+ js: transpileToJS,
180
+ sourceMap: true
181
+ });
182
+ sourceMaps.set(import_path.default.resolve(process.cwd(), id), compiled.sourceMap);
183
+ const jsonSourceMap = compiled.sourceMap.json(
184
+ import_path.default.basename(id.replace(/\.[jt]sx$/, "")),
185
+ import_path.default.basename(id)
186
+ );
136
187
  let transformed = {
137
- code: import_civet.default.compile(code, {
138
- inlineMap: true,
139
- filename: id,
140
- js: transpileToJS
141
- }),
142
- map: null
188
+ code: compiled.code,
189
+ map: jsonSourceMap
143
190
  };
144
191
  if (options.transformOutput)
145
192
  transformed = await options.transformOutput(transformed.code, id);
@@ -148,8 +195,12 @@ var civetUnplugin = (0, import_unplugin.createUnplugin)((options = {}) => {
148
195
  transform(code, id) {
149
196
  if (!/\.civet\.tsx?$/.test(id))
150
197
  return null;
151
- if (options.dts) {
152
- fsMap.set(import_path.default.resolve(process.cwd(), id), code);
198
+ if (options.dts || options.typecheck) {
199
+ const resolved = import_path.default.resolve(process.cwd(), id);
200
+ fsMap.set(resolved, code);
201
+ const slash = resolved.replace(/\\/g, "/");
202
+ if (resolved !== slash)
203
+ fsMap.set(slash, code);
153
204
  }
154
205
  return null;
155
206
  },