@simplysm/sd-cli 11.0.8 → 11.0.11

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.
Files changed (64) hide show
  1. package/dist/build-cluster.js +25 -36
  2. package/dist/build-cluster.js.map +1 -1
  3. package/dist/build-tools/SdCliCordova.d.ts +21 -0
  4. package/dist/build-tools/SdCliCordova.js +182 -0
  5. package/dist/build-tools/SdCliCordova.js.map +1 -0
  6. package/dist/build-tools/SdCliNgRoutesFileGenerator.d.ts +4 -0
  7. package/dist/build-tools/SdCliNgRoutesFileGenerator.js +64 -0
  8. package/dist/build-tools/SdCliNgRoutesFileGenerator.js.map +1 -0
  9. package/dist/build-tools/SdLinter.js +8 -1
  10. package/dist/build-tools/SdLinter.js.map +1 -1
  11. package/dist/build-tools/SdNgBundler.d.ts +16 -5
  12. package/dist/build-tools/SdNgBundler.js +280 -179
  13. package/dist/build-tools/SdNgBundler.js.map +1 -1
  14. package/dist/build-tools/SdTsBundler.d.ts +6 -5
  15. package/dist/build-tools/SdTsBundler.js +78 -80
  16. package/dist/build-tools/SdTsBundler.js.map +1 -1
  17. package/dist/build-tools/SdTsCompiler.d.ts +1 -0
  18. package/dist/build-tools/SdTsCompiler.js +5 -1
  19. package/dist/build-tools/SdTsCompiler.js.map +1 -1
  20. package/dist/builders/SdCliClientBuilder.d.ts +1 -0
  21. package/dist/builders/SdCliClientBuilder.js +62 -27
  22. package/dist/builders/SdCliClientBuilder.js.map +1 -1
  23. package/dist/builders/SdCliServerBuilder.d.ts +6 -2
  24. package/dist/builders/SdCliServerBuilder.js +107 -141
  25. package/dist/builders/SdCliServerBuilder.js.map +1 -1
  26. package/dist/builders/SdCliTsLibBuilder.d.ts +6 -3
  27. package/dist/builders/SdCliTsLibBuilder.js +42 -45
  28. package/dist/builders/SdCliTsLibBuilder.js.map +1 -1
  29. package/dist/commons.d.ts +22 -2
  30. package/dist/entry/SdCliElectron.js +3 -3
  31. package/dist/entry/SdCliElectron.js.map +1 -1
  32. package/dist/entry/SdCliProject.d.ts +0 -3
  33. package/dist/entry/SdCliProject.js +10 -33
  34. package/dist/entry/SdCliProject.js.map +1 -1
  35. package/dist/index.d.ts +4 -0
  36. package/dist/index.js +4 -0
  37. package/dist/index.js.map +1 -1
  38. package/dist/sd-cli.js +27 -21
  39. package/dist/sd-cli.js.map +1 -1
  40. package/dist/utils/SdMemoryLoadResultCache.d.ts +9 -0
  41. package/dist/utils/SdMemoryLoadResultCache.js +39 -0
  42. package/dist/utils/SdMemoryLoadResultCache.js.map +1 -0
  43. package/dist/utils/SdSourceFileCache.d.ts +5 -0
  44. package/dist/utils/SdSourceFileCache.js +9 -0
  45. package/dist/utils/SdSourceFileCache.js.map +1 -0
  46. package/lib/cordova-entry.js +22 -0
  47. package/package.json +19 -16
  48. package/src/build-cluster.ts +26 -36
  49. package/src/build-tools/SdCliCordova.ts +240 -0
  50. package/src/build-tools/SdCliNgRoutesFileGenerator.ts +80 -0
  51. package/src/build-tools/SdLinter.ts +12 -1
  52. package/src/build-tools/SdNgBundler.ts +428 -288
  53. package/src/build-tools/SdTsBundler.ts +86 -86
  54. package/src/build-tools/SdTsCompiler.ts +6 -1
  55. package/src/builders/SdCliClientBuilder.ts +76 -34
  56. package/src/builders/SdCliServerBuilder.ts +64 -63
  57. package/src/builders/SdCliTsLibBuilder.ts +58 -50
  58. package/src/commons.ts +24 -2
  59. package/src/entry/SdCliElectron.ts +3 -3
  60. package/src/entry/SdCliProject.ts +12 -41
  61. package/src/index.ts +4 -0
  62. package/src/sd-cli.ts +31 -21
  63. package/src/utils/SdMemoryLoadResultCache.ts +44 -0
  64. package/src/utils/SdSourceFileCache.ts +6 -0
@@ -53,23 +53,22 @@ else {
53
53
  if (message.cmd === "watch") {
54
54
  // [library] javascript
55
55
  if (pkgConf.type === "library" && !FsUtil.exists(path.resolve(message.pkgPath, "tsconfig.json"))) {
56
- if (message.withLint) {
57
- await new SdCliJsLibLinter(message.pkgPath)
58
- .on("change", () => {
59
- sendMessage({
60
- type: "change",
61
- req: message
62
- });
63
- })
64
- .on("complete", (result) => {
65
- sendMessage({
66
- type: "complete",
67
- result,
68
- req: message
69
- });
70
- })
71
- .watchAsync();
72
- }
56
+ await new SdCliJsLibLinter(message.pkgPath)
57
+ .on("change", () => {
58
+ sendMessage({
59
+ type: "change",
60
+ req: message
61
+ });
62
+ })
63
+ .on("complete", (result) => {
64
+ sendMessage({
65
+ type: "complete",
66
+ result,
67
+ req: message
68
+ });
69
+ })
70
+ .watchAsync();
71
+
73
72
  sendMessage({
74
73
  type: "ready",
75
74
  req: message
@@ -77,7 +76,7 @@ else {
77
76
  }
78
77
  // [library] typescript
79
78
  else if (pkgConf.type === "library" && FsUtil.exists(path.resolve(message.pkgPath, "tsconfig.json"))) {
80
- await new SdCliTsLibBuilder(message.pkgPath, message.withLint)
79
+ await new SdCliTsLibBuilder(message.projConf, message.pkgPath)
81
80
  .on("change", () => {
82
81
  sendMessage({
83
82
  type: "change",
@@ -99,7 +98,7 @@ else {
99
98
  }
100
99
  // [server]
101
100
  else if (pkgConf.type === "server") {
102
- await new SdCliServerBuilder(message.projConf, message.pkgPath, message.withLint)
101
+ await new SdCliServerBuilder(message.projConf, message.pkgPath)
103
102
  .on("change", () => {
104
103
  sendMessage({
105
104
  type: "change",
@@ -148,25 +147,16 @@ else {
148
147
  else { // build
149
148
  // [library] javascript
150
149
  if (pkgConf.type === "library" && !FsUtil.exists(path.resolve(message.pkgPath, "tsconfig.json"))) {
151
- if (message.withLint) {
152
- const result = await new SdCliJsLibLinter(message.pkgPath).buildAsync();
153
- sendMessage({
154
- type: "complete",
155
- result,
156
- req: message
157
- });
158
- }
159
- else {
160
- sendMessage({
161
- type: "complete",
162
- result: undefined,
163
- req: message
164
- });
165
- }
150
+ const result = await new SdCliJsLibLinter(message.pkgPath).buildAsync();
151
+ sendMessage({
152
+ type: "complete",
153
+ result,
154
+ req: message
155
+ });
166
156
  }
167
157
  // [library] typescript
168
158
  else if (pkgConf.type === "library" && FsUtil.exists(path.resolve(message.pkgPath, "tsconfig.json"))) {
169
- const result = await new SdCliTsLibBuilder(message.pkgPath, message.withLint).buildAsync();
159
+ const result = await new SdCliTsLibBuilder(message.projConf, message.pkgPath).buildAsync();
170
160
  sendMessage({
171
161
  type: "complete",
172
162
  result,
@@ -175,7 +165,7 @@ else {
175
165
  }
176
166
  // [server]
177
167
  else if (pkgConf.type === "server") {
178
- const result = await new SdCliServerBuilder(message.projConf, message.pkgPath, message.withLint).buildAsync();
168
+ const result = await new SdCliServerBuilder(message.projConf, message.pkgPath).buildAsync();
179
169
  sendMessage({
180
170
  type: "complete",
181
171
  result,
@@ -0,0 +1,240 @@
1
+ import {INpmConfig, ISdCliClientBuilderCordovaConfig} from "../commons";
2
+ import * as path from "path";
3
+ import {FsUtil, Logger, SdProcess} from "@simplysm/sd-core-node";
4
+ import xml2js from "xml2js";
5
+
6
+ const BIN_PATH = path.resolve(process.cwd(), "node_modules/.bin/cordova.cmd");
7
+
8
+ export class SdCliCordova {
9
+ protected readonly _logger = Logger.get(["simplysm", "sd-cli", "SdCliCordova"]);
10
+
11
+ private readonly _platforms: string[];
12
+ private readonly _npmConfig: INpmConfig;
13
+
14
+ public constructor(private readonly _opt: {
15
+ pkgPath: string;
16
+ config: ISdCliClientBuilderCordovaConfig;
17
+ cordovaPath: string;
18
+ }) {
19
+ this._platforms = Object.keys(this._opt.config.platform ?? {browser: {}});
20
+ this._npmConfig = FsUtil.readJson(path.resolve(this._opt.pkgPath, "package.json"));
21
+ // this._logger = Logger.get(["simplysm", "sd-cli", this.constructor.name, this._npmConfig.name]);
22
+ }
23
+
24
+ private async _execAsync(cmd: string, cwd: string): Promise<void> {
25
+ this._logger.debug(cmd);
26
+ const msg = await SdProcess.spawnAsync(cmd, {cwd});
27
+ this._logger.debug(msg);
28
+ }
29
+
30
+ public async initializeAsync(): Promise<void> {
31
+ if (FsUtil.exists(this._opt.cordovaPath)) {
32
+ this._logger.log("이미 생성되어있는 '.cordova'를 사용합니다.");
33
+ }
34
+ else {
35
+ await this._execAsync(`${BIN_PATH} telemetry on`, this._opt.pkgPath);
36
+
37
+ // 프로젝트 생성
38
+ await this._execAsync(`${BIN_PATH} create "${this._opt.cordovaPath}" "${this._opt.config.appId}" "${this._opt.config.appName}"`, process.cwd());
39
+ }
40
+
41
+ // platforms 폴더 혹시 없으면 생성
42
+ await FsUtil.mkdirsAsync(path.resolve(this._opt.cordovaPath, "platforms"));
43
+
44
+ // www 폴더 혹시 없으면 생성
45
+ await FsUtil.mkdirsAsync(path.resolve(this._opt.cordovaPath, "www"));
46
+
47
+ // 미설치 빌드 플랫폼 신규 생성
48
+ const alreadyPlatforms = await FsUtil.readdirAsync(path.resolve(this._opt.cordovaPath, "platforms"));
49
+ for (const platform of this._platforms) {
50
+ if (!alreadyPlatforms.includes(platform)) {
51
+ await this._execAsync(`${BIN_PATH} platform add ${platform}`, this._opt.cordovaPath);
52
+ }
53
+ }
54
+
55
+ // 설치 미빌드 플랫폼 삭제
56
+ for (const alreadyPlatform of alreadyPlatforms) {
57
+ if (!this._platforms.includes(alreadyPlatform)) {
58
+ await this._execAsync(`${BIN_PATH} platform remove ${alreadyPlatform}`, this._opt.cordovaPath);
59
+ }
60
+ }
61
+
62
+ // 설치된 미사용 플러그인 삭제
63
+ const pluginsFetch = FsUtil.exists(path.resolve(this._opt.cordovaPath, "plugins/fetch.json"))
64
+ ? await FsUtil.readJsonAsync(path.resolve(this._opt.cordovaPath, "plugins/fetch.json"))
65
+ : undefined;
66
+ const alreadyPluginIds = pluginsFetch != undefined
67
+ ? Object.values(pluginsFetch)
68
+ .map((item: any) => (item.source.id !== undefined ? item.source.id : item.source.url))
69
+ : [];
70
+ const usePlugins = ["cordova-plugin-ionic-webview", ...this._opt.config.plugins ?? []].distinct();
71
+
72
+ for (const alreadyPluginId of alreadyPluginIds) {
73
+ let hasPlugin = false;
74
+ for (const usePlugin of usePlugins) {
75
+ if (
76
+ (usePlugin.includes("@") && alreadyPluginId === usePlugin) ||
77
+ (!usePlugin.includes("@") && alreadyPluginId.replace(/@.*$/, "") === usePlugin)
78
+ ) {
79
+ hasPlugin = true;
80
+ break;
81
+ }
82
+ }
83
+
84
+ if (!hasPlugin) {
85
+ await this._execAsync(`${BIN_PATH} plugin remove ${alreadyPluginId.replace(/@.*$/, "")}`, this._opt.cordovaPath);
86
+ }
87
+ }
88
+
89
+ // 미설치 플러그인들 설치
90
+ for (const usePlugin of usePlugins) {
91
+ if (
92
+ (usePlugin.includes("@") && !alreadyPluginIds.includes(usePlugin)) ||
93
+ (!usePlugin.includes("@") && !alreadyPluginIds.map((alreadyPluginId) => alreadyPluginId.replace(/@.*$/, "")).includes(usePlugin))
94
+ ) {
95
+ await this._execAsync(`${BIN_PATH} plugin add ${usePlugin}`, this._opt.cordovaPath);
96
+ }
97
+ }
98
+
99
+ // ANDROID SIGN 파일 복사
100
+ if (this._opt.config.platform?.android?.sign) {
101
+ await FsUtil.copyAsync(
102
+ path.resolve(this._opt.pkgPath, "src", this._opt.config.platform.android.sign.keystore),
103
+ path.resolve(this._opt.cordovaPath, "android.keystore")
104
+ );
105
+ }
106
+ else {
107
+ await FsUtil.removeAsync(path.resolve(this._opt.cordovaPath, "android.keystore"));
108
+ // SIGN을 안쓸경우 아래 파일이 생성되어 있으면 오류남
109
+ await FsUtil.removeAsync(path.resolve(this._opt.cordovaPath, "platforms/android/release-signing.properties"));
110
+ }
111
+
112
+ // 빌드 옵션 파일 생성
113
+ await FsUtil.writeJsonAsync(
114
+ path.resolve(this._opt.cordovaPath, "build.json"),
115
+ {
116
+ ...this._opt.config.platform?.android ? {
117
+ android: {
118
+ release: {
119
+ packageType: this._opt.config.platform.android.bundle ? "bundle" : "apk",
120
+ ...this._opt.config.platform.android.sign ? {
121
+ keystore: path.resolve(this._opt.cordovaPath, "android.keystore"),
122
+ storePassword: this._opt.config.platform.android.sign.storePassword,
123
+ alias: this._opt.config.platform.android.sign.alias,
124
+ password: this._opt.config.platform.android.sign.password,
125
+ keystoreType: this._opt.config.platform.android.sign.keystoreType
126
+ } : {}
127
+ }
128
+ }
129
+ } : {}
130
+ }
131
+ );
132
+
133
+ // ICON 파일 복사
134
+ if (this._opt.config.icon !== undefined) {
135
+ await FsUtil.copyAsync(path.resolve(this._opt.pkgPath, "src", this._opt.config.icon), path.resolve(this._opt.cordovaPath, "res/icon", path.basename(this._opt.config.icon)));
136
+ }
137
+ else {
138
+ await FsUtil.removeAsync(path.resolve(this._opt.cordovaPath, "res/icon"));
139
+ }
140
+
141
+ // CONFIG: 초기값 백업
142
+ const configFilePath = path.resolve(this._opt.cordovaPath, "config.xml");
143
+ const configBackFilePath = path.resolve(this._opt.cordovaPath, "config.xml.bak");
144
+ if (!FsUtil.exists(configBackFilePath)) {
145
+ await FsUtil.copyAsync(configFilePath, configBackFilePath);
146
+ }
147
+
148
+ // CONFIG: 초기값 읽기
149
+ const configFileContent = await FsUtil.readFileAsync(configBackFilePath);
150
+ const configXml = await xml2js.parseStringPromise(configFileContent);
151
+
152
+
153
+ // CONFIG: 버전 설정
154
+ configXml.widget.$.version = this._npmConfig.version;
155
+
156
+ // CONFIG: ICON 설정
157
+ if (this._opt.config.icon !== undefined) {
158
+ configXml["widget"]["icon"] = [{"$": {"src": "res/icon/" + path.basename(this._opt.config.icon)}}];
159
+ }
160
+
161
+ // CONFIG: 접근허용 세팅
162
+ configXml["widget"]["access"] = [{"$": {"origin": "*"}}];
163
+ configXml["widget"]["allow-navigation"] = [{"$": {"href": "*"}}];
164
+ configXml["widget"]["allow-intent"] = [{"$": {"href": "*"}}];
165
+ configXml["widget"]["preference"] = [{"$": {"name": "MixedContentMode", "value": "0"}}];
166
+
167
+ // CONFIG: ANDROID usesCleartextTraffic 설정
168
+ if (this._opt.config.platform?.android) {
169
+ configXml.widget.$["xmlns:android"] = "http://schemas.android.com/apk/res/android";
170
+
171
+ configXml["widget"]["platform"] = configXml["widget"]["platform"] ?? [];
172
+ configXml["widget"]["platform"].push({
173
+ "$": {
174
+ "name": "android"
175
+ },
176
+ "edit-config": [{
177
+ "$": {
178
+ "file": "app/src/main/AndroidManifest.xml",
179
+ "mode": "merge",
180
+ "target": "/manifest/application"
181
+ },
182
+ "application": [{
183
+ "$": {
184
+ "android:usesCleartextTraffic": "true"
185
+ }
186
+ }]
187
+ }]
188
+ });
189
+ }
190
+
191
+ // CONFIG: 파일 새로 쓰기
192
+ const configResultContent = new xml2js.Builder().buildObject(configXml);
193
+ await FsUtil.writeFileAsync(configFilePath, configResultContent);
194
+
195
+ // 각 플랫폼 www 준비
196
+ await this._execAsync(`${BIN_PATH} prepare`, this._opt.cordovaPath);
197
+ }
198
+
199
+ public async buildAsync(outPath: string): Promise<void> {
200
+ // 실행
201
+ const buildType = this._opt.config.debug ? "debug" : "release";
202
+ for (const platform of this._platforms) {
203
+ await this._execAsync(`${BIN_PATH} build ${platform} --${buildType}`, this._opt.cordovaPath);
204
+ }
205
+
206
+ // 결과물 복사: ANDROID
207
+ if (this._opt.config.platform?.android) {
208
+ const targetOutPath = path.resolve(outPath, "android");
209
+ const apkFileName = this._opt.config.platform.android.sign ? `app-${buildType}.apk` : `app-${buildType}-unsigned.apk`;
210
+ const latestDistApkFileName = path.basename(`${this._opt.config.appName}${this._opt.config.platform.android.sign ? "" : "-unsigned"}-latest.apk`);
211
+ await FsUtil.mkdirsAsync(targetOutPath);
212
+ await FsUtil.copyAsync(
213
+ path.resolve(this._opt.cordovaPath, "platforms/android/app/build/outputs/apk", buildType, apkFileName),
214
+ path.resolve(targetOutPath, latestDistApkFileName)
215
+ );
216
+ // 자동업데이트를 위한 파일 쓰기
217
+ await FsUtil.copyAsync(
218
+ path.resolve(this._opt.cordovaPath, "platforms/android/app/build/outputs/apk", buildType, apkFileName),
219
+ path.resolve(path.resolve(targetOutPath, "updates"), this._npmConfig.version + ".apk")
220
+ );
221
+ }
222
+ }
223
+
224
+ public static async runWebviewOnDeviceAsync(opt: {
225
+ platform: string,
226
+ pkgName: string,
227
+ url?: string
228
+ }): Promise<void> {
229
+ const cordovaPath = path.resolve(process.cwd(), `packages/${opt.pkgName}/.cordova/`);
230
+
231
+ if (opt.url !== undefined) {
232
+ await FsUtil.removeAsync(path.resolve(cordovaPath, "www"));
233
+ await FsUtil.mkdirsAsync(path.resolve(cordovaPath, "www"));
234
+ await FsUtil.writeFileAsync(path.resolve(cordovaPath, "www/index.html"), `'${opt.url}'로 이동중... <script>setTimeout(function () {window.location.href = "${opt.url.replace(/\/$/, "")}/${opt.pkgName}/cordova/"}, 3000);</script>`.trim());
235
+ }
236
+
237
+ const binPath = path.resolve(process.cwd(), "node_modules/.bin/cordova.cmd");
238
+ await SdProcess.spawnAsync(`${binPath} run ${opt.platform} --device`, {cwd: cordovaPath}, true);
239
+ }
240
+ }
@@ -0,0 +1,80 @@
1
+ import path from "path";
2
+ import {FsUtil, PathUtil, SdFsWatcher} from "@simplysm/sd-core-node";
3
+ import {StringUtil} from "@simplysm/sd-core-common";
4
+
5
+ export class SdCliNgRoutesFileGenerator {
6
+ public static async watchAsync(pkgPath: string): Promise<void> {
7
+ const routesFilePath = path.resolve(pkgPath, "src/routes.ts");
8
+ let cache = FsUtil.exists(routesFilePath) ? FsUtil.readFile(routesFilePath) : undefined;
9
+
10
+ SdFsWatcher
11
+ .watch([path.resolve(pkgPath, "src")])
12
+ .onChange({}, async () => {
13
+ cache = await this.runAsync(pkgPath, cache);
14
+ });
15
+
16
+ cache = await this.runAsync(pkgPath, cache);
17
+ }
18
+
19
+ public static async runAsync(pkgPath: string, cache?: string): Promise<string> {
20
+ const appDirPath = path.resolve(pkgPath, "src/app");
21
+ const routesFilePath = path.resolve(pkgPath, "src/routes.ts");
22
+
23
+ // 내부 파일들 import
24
+ const result: TInfo = new Map();
25
+ const filePaths = await FsUtil.globAsync(path.resolve(appDirPath, "**/*Page.ts"));
26
+ for (const filePath of filePaths.orderBy()) {
27
+ const relModulePath = PathUtil.posix(path.relative(appDirPath, filePath)).slice(0, -3);
28
+ const codes = relModulePath.slice(0, -4).split("/").map(item => StringUtil.toKebabCase(item));
29
+
30
+ let cursorItem!: { relModulePath?: string; children: TInfo };
31
+ let cursor = result;
32
+
33
+ for (const code of codes) {
34
+ cursorItem = cursor.getOrCreate(code, {children: new Map()});
35
+ cursor = cursorItem.children;
36
+ }
37
+
38
+ cursorItem.relModulePath = relModulePath;
39
+ }
40
+
41
+
42
+ const fn = (currInfo: TInfo, indent: number): string => {
43
+ const indentStr = new Array(indent).fill(" ").join("");
44
+
45
+ let cont = "";
46
+ for (const [key, val] of currInfo) {
47
+ cont += indentStr + "{\n";
48
+ cont += indentStr + ` path: "${key}",\n`;
49
+ if (val.relModulePath != null) {
50
+ cont += indentStr + ` loadComponent: () => import("./app/${val.relModulePath}").then((m) => m.${path.basename(val.relModulePath)}),\n`;
51
+ cont += indentStr + ` canDeactivate: [sdCanDeactivateGuard],\n`;
52
+ }
53
+ if (val.children.size > 0) {
54
+ cont += indentStr + ` children: [\n`;
55
+ cont += fn(val.children, indent + 4) + "\n";
56
+ cont += indentStr + ` ]\n`;
57
+ }
58
+ cont += indentStr + "},\n";
59
+ }
60
+ return cont.trimEnd();
61
+ };
62
+
63
+ const content = `
64
+ import {sdCanDeactivateGuard} from "@simplysm/sd-angular";
65
+ import {Routes} from "@angular/router";
66
+
67
+ export const routes: Routes = [
68
+ ${fn(result, 2)}
69
+ ];`.trim();
70
+ if (content.trim() !== cache?.trim()) {
71
+ await FsUtil.writeFileAsync(routesFilePath, content);
72
+ }
73
+ return content;
74
+ }
75
+ }
76
+
77
+ type TInfo = Map<string, {
78
+ relModulePath?: string;
79
+ children: TInfo
80
+ }>;
@@ -5,6 +5,17 @@ import path from "path";
5
5
 
6
6
  export class SdLinter {
7
7
  public static async lintAsync(filePaths: string[], programOrPkgPath?: ts.Program | string): Promise<ISdCliPackageBuildResult[]> {
8
+ const sourceFilePaths = filePaths.filter((item) =>
9
+ (!item.endsWith(".d.ts") && item.endsWith(".ts")) ||
10
+ item.endsWith(".js") ||
11
+ item.endsWith(".cjs") ||
12
+ item.endsWith(".mjs")
13
+ );
14
+
15
+ if (sourceFilePaths.length === 0) {
16
+ return [];
17
+ }
18
+
8
19
  const linter = new ESLint(programOrPkgPath !== null ? {
9
20
  overrideConfig: {
10
21
  overrides: [
@@ -37,7 +48,7 @@ export class SdLinter {
37
48
  }
38
49
  } : undefined);
39
50
 
40
- const lintResults = await linter.lintFiles(filePaths);
51
+ const lintResults = await linter.lintFiles(sourceFilePaths);
41
52
 
42
53
  return lintResults.mapMany((lintResult) => lintResult.messages.map((msg) => ({
43
54
  filePath: lintResult.filePath,