noshift.js 0.2.0 → 0.3.0
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-ja.md +2 -2
- package/README.md +2 -2
- package/bin/cli.js +1 -1
- package/commands/clean.js +8 -4
- package/commands/compile.js +16 -9
- package/commands/create.js +99 -140
- package/commands/dev.js +20 -10
- package/commands/init.js +12 -6
- package/commands/run.js +5 -1
- package/package.json +1 -1
- package/src/logger.js +52 -0
- package/src/signal-handler.js +46 -0
package/README-ja.md
CHANGED
|
@@ -54,7 +54,7 @@ nsc --init
|
|
|
54
54
|
{
|
|
55
55
|
"compilerOptions": {
|
|
56
56
|
"rootDir": "src",
|
|
57
|
-
"outDir": "
|
|
57
|
+
"outDir": "dist"
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
```
|
|
@@ -62,7 +62,7 @@ nsc --init
|
|
|
62
62
|
| オプション | デフォルト | 説明 |
|
|
63
63
|
|---|---|---|
|
|
64
64
|
| `compilerOptions.rootDir` | `"src"` | ソースディレクトリ |
|
|
65
|
-
| `compilerOptions.outDir` | `"
|
|
65
|
+
| `compilerOptions.outDir` | `"dist"` | 出力ディレクトリ |
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ Generated automatically by `nsc --init` or `nsc create`.
|
|
|
54
54
|
{
|
|
55
55
|
"compilerOptions": {
|
|
56
56
|
"rootDir": "src",
|
|
57
|
-
"outDir": "
|
|
57
|
+
"outDir": "dist"
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
```
|
|
@@ -62,7 +62,7 @@ Generated automatically by `nsc --init` or `nsc create`.
|
|
|
62
62
|
| Option | Default | Description |
|
|
63
63
|
|---|---|---|
|
|
64
64
|
| `compilerOptions.rootDir` | `"src"` | Source directory |
|
|
65
|
-
| `compilerOptions.outDir` | `"
|
|
65
|
+
| `compilerOptions.outDir` | `"dist"` | Output directory |
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
package/bin/cli.js
CHANGED
|
@@ -16,7 +16,7 @@ const program = new Command();
|
|
|
16
16
|
program
|
|
17
17
|
.name("nsc")
|
|
18
18
|
.description("NoShift.js compiler")
|
|
19
|
-
.version(pkg.version)
|
|
19
|
+
.version(pkg.version, '-v, --version', 'output the version number')
|
|
20
20
|
.option("-w, --watch", "Watch for file changes and recompile")
|
|
21
21
|
.option("--init", "Create a nsjsconfig.json in the current directory")
|
|
22
22
|
.option("--clean", "Delete the output directory (outDir)")
|
package/commands/clean.js
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { rm, access } from "fs/promises";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { loadConfig } from "../src/config.js";
|
|
4
|
+
import { handleSigint } from "../src/signal-handler.js";
|
|
5
|
+
import * as logger from "../src/logger.js";
|
|
4
6
|
|
|
5
7
|
export default async function clean() {
|
|
8
|
+
handleSigint();
|
|
9
|
+
|
|
6
10
|
const cwd = process.cwd();
|
|
7
11
|
|
|
8
12
|
let config;
|
|
9
13
|
try {
|
|
10
14
|
config = await loadConfig(cwd);
|
|
11
15
|
} catch (e) {
|
|
12
|
-
|
|
16
|
+
logger.errorCode("NS0", e.message);
|
|
13
17
|
process.exit(1);
|
|
14
18
|
}
|
|
15
19
|
|
|
@@ -18,12 +22,12 @@ export default async function clean() {
|
|
|
18
22
|
try {
|
|
19
23
|
await access(outDir);
|
|
20
24
|
} catch {
|
|
21
|
-
|
|
22
|
-
`Nothing to clean (
|
|
25
|
+
logger.info(
|
|
26
|
+
`Nothing to clean (${logger.highlight(config.compilerOptions.outDir)} does not exist).`,
|
|
23
27
|
);
|
|
24
28
|
return;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
await rm(outDir, { recursive: true, force: true });
|
|
28
|
-
|
|
32
|
+
logger.success(`Deleted ${logger.highlight(config.compilerOptions.outDir)}`);
|
|
29
33
|
}
|
package/commands/compile.js
CHANGED
|
@@ -2,6 +2,8 @@ import { promises as fs } from "fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import convert from "../src/convert.js";
|
|
4
4
|
import { loadConfig } from "../src/config.js";
|
|
5
|
+
import { handleSigint } from "../src/signal-handler.js";
|
|
6
|
+
import * as logger from "../src/logger.js";
|
|
5
7
|
|
|
6
8
|
async function findNsjsFiles(dir) {
|
|
7
9
|
let entries;
|
|
@@ -25,13 +27,15 @@ async function findNsjsFiles(dir) {
|
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export default async function compile() {
|
|
30
|
+
handleSigint();
|
|
31
|
+
|
|
28
32
|
const cwd = process.cwd();
|
|
29
33
|
|
|
30
34
|
let config;
|
|
31
35
|
try {
|
|
32
36
|
config = await loadConfig(cwd);
|
|
33
37
|
} catch (e) {
|
|
34
|
-
|
|
38
|
+
logger.errorCode("NS0", e.message);
|
|
35
39
|
process.exit(1);
|
|
36
40
|
}
|
|
37
41
|
|
|
@@ -41,14 +45,15 @@ export default async function compile() {
|
|
|
41
45
|
const files = await findNsjsFiles(rootDir);
|
|
42
46
|
|
|
43
47
|
if (files === null) {
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
logger.errorCode(
|
|
49
|
+
"NS0",
|
|
50
|
+
`rootDir '${config.compilerOptions.rootDir}' not found.`,
|
|
46
51
|
);
|
|
47
52
|
process.exit(1);
|
|
48
53
|
}
|
|
49
54
|
|
|
50
55
|
if (files.length === 0) {
|
|
51
|
-
|
|
56
|
+
logger.info("No .nsjs files found.");
|
|
52
57
|
return;
|
|
53
58
|
}
|
|
54
59
|
|
|
@@ -68,22 +73,24 @@ export default async function compile() {
|
|
|
68
73
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
69
74
|
await fs.writeFile(destPath, js, "utf-8");
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
logger.dim(
|
|
72
77
|
` ${relative.replace(/\\/g, "/")} → ${path.relative(cwd, destPath).replace(/\\/g, "/")}`,
|
|
73
78
|
);
|
|
74
79
|
compiled++;
|
|
75
80
|
} catch (e) {
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
logger.errorCode(
|
|
82
|
+
"NS1",
|
|
83
|
+
`${relative.replace(/\\/g, "/")}: ${e.message}`,
|
|
78
84
|
);
|
|
79
85
|
errors++;
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
|
|
89
|
+
console.log("");
|
|
83
90
|
if (errors > 0) {
|
|
84
|
-
|
|
91
|
+
logger.error(`Found ${errors} error(s). Compiled ${compiled} file(s).`);
|
|
85
92
|
process.exit(1);
|
|
86
93
|
} else {
|
|
87
|
-
|
|
94
|
+
logger.success(`Compiled ${compiled} file(s).`);
|
|
88
95
|
}
|
|
89
96
|
}
|
package/commands/create.js
CHANGED
|
@@ -2,154 +2,101 @@ import { execSync } from "child_process";
|
|
|
2
2
|
import fs from "fs/promises";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import inquirer from "inquirer";
|
|
5
|
+
import { handleSigint, isUserCancelled } from "../src/signal-handler.js";
|
|
6
|
+
import * as logger from "../src/logger.js";
|
|
5
7
|
|
|
6
8
|
export default async function create(projectNameArg) {
|
|
9
|
+
handleSigint();
|
|
10
|
+
|
|
7
11
|
const cwd = process.cwd();
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
nextSteps: {
|
|
51
|
-
en: "Next: cd {name} && nsc compile",
|
|
52
|
-
ja: "次のステップ: cd {name} && nsc compile",
|
|
13
|
+
try {
|
|
14
|
+
// Project name
|
|
15
|
+
let projectName = projectNameArg;
|
|
16
|
+
if (!projectName) {
|
|
17
|
+
const answer = await inquirer.prompt([
|
|
18
|
+
{
|
|
19
|
+
type: "input",
|
|
20
|
+
name: "projectName",
|
|
21
|
+
message: "Project name:",
|
|
22
|
+
default: "my-noshift-app",
|
|
23
|
+
},
|
|
24
|
+
]);
|
|
25
|
+
projectName = answer.projectName;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const projectPath = path.join(cwd, projectName);
|
|
29
|
+
|
|
30
|
+
// Create project directory
|
|
31
|
+
logger.step("Creating project directory...");
|
|
32
|
+
await fs.mkdir(projectPath, { recursive: true });
|
|
33
|
+
logger.dim(` ${projectPath}`);
|
|
34
|
+
|
|
35
|
+
process.chdir(projectPath);
|
|
36
|
+
|
|
37
|
+
// npm init
|
|
38
|
+
logger.step("Initializing npm...");
|
|
39
|
+
execSync("npm init -y", { stdio: "ignore" });
|
|
40
|
+
|
|
41
|
+
// Add scripts to package.json
|
|
42
|
+
const pkgPath = path.join(projectPath, "package.json");
|
|
43
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, "utf-8"));
|
|
44
|
+
pkg.scripts = pkg.scripts ?? {};
|
|
45
|
+
pkg.scripts.compile = "nsc compile";
|
|
46
|
+
pkg.scripts.dev = "nsc dev";
|
|
47
|
+
await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
48
|
+
|
|
49
|
+
// Create nsjsconfig.json
|
|
50
|
+
const nsjsconfig = {
|
|
51
|
+
compilerOptions: {
|
|
52
|
+
rootDir: "src",
|
|
53
|
+
outDir: "dist",
|
|
53
54
|
},
|
|
54
|
-
}
|
|
55
|
+
};
|
|
56
|
+
await fs.writeFile(
|
|
57
|
+
"nsjsconfig.json",
|
|
58
|
+
JSON.stringify(nsjsconfig, null, 2) + "\n",
|
|
59
|
+
);
|
|
60
|
+
logger.success("Created nsjsconfig.json");
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (!projectName) {
|
|
59
|
-
const answer = await inquirer.prompt([
|
|
62
|
+
// Prettier
|
|
63
|
+
const { usePrettier } = await inquirer.prompt([
|
|
60
64
|
{
|
|
61
|
-
type: "
|
|
62
|
-
name: "
|
|
63
|
-
message:
|
|
64
|
-
default:
|
|
65
|
+
type: "confirm",
|
|
66
|
+
name: "usePrettier",
|
|
67
|
+
message: "Format compiled output with Prettier?",
|
|
68
|
+
default: true,
|
|
65
69
|
},
|
|
66
70
|
]);
|
|
67
|
-
projectName = answer.projectName;
|
|
68
|
-
}
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
rootDir: "src",
|
|
92
|
-
outDir: "build",
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
await fs.writeFile(
|
|
96
|
-
"nsjsconfig.json",
|
|
97
|
-
JSON.stringify(nsjsconfig, null, 2) + "\n",
|
|
98
|
-
);
|
|
99
|
-
console.log(t("creatingConfig"));
|
|
100
|
-
|
|
101
|
-
// Prettier
|
|
102
|
-
const { usePrettier } = await inquirer.prompt([
|
|
103
|
-
{
|
|
104
|
-
type: "confirm",
|
|
105
|
-
name: "usePrettier",
|
|
106
|
-
message: t("usePrettier"),
|
|
107
|
-
default: true,
|
|
108
|
-
},
|
|
109
|
-
]);
|
|
110
|
-
|
|
111
|
-
if (usePrettier) {
|
|
112
|
-
console.log(t("installingPrettier"));
|
|
113
|
-
execSync("npm install --save-dev prettier", { stdio: "inherit" });
|
|
114
|
-
await fs.writeFile(".prettierignore", "build/\nnode_modules/\n");
|
|
72
|
+
if (usePrettier) {
|
|
73
|
+
logger.step("Installing Prettier...");
|
|
74
|
+
execSync("npm install --save-dev prettier", { stdio: "ignore" });
|
|
75
|
+
await fs.writeFile(".prettierignore", "dist/\nnode_modules/\n");
|
|
76
|
+
await fs.writeFile(
|
|
77
|
+
".prettierrc",
|
|
78
|
+
JSON.stringify(
|
|
79
|
+
{ semi: true, singleQuote: false, trailingComma: "es5" },
|
|
80
|
+
null,
|
|
81
|
+
2,
|
|
82
|
+
) + "\n",
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Install noshift.js
|
|
87
|
+
logger.step("Installing noshift.js...");
|
|
88
|
+
execSync("npm install noshift.js", { stdio: "ignore" });
|
|
89
|
+
|
|
90
|
+
// Create project files
|
|
91
|
+
logger.step("Creating project files...");
|
|
92
|
+
await fs.mkdir("src", { recursive: true });
|
|
115
93
|
await fs.writeFile(
|
|
116
|
-
".
|
|
117
|
-
|
|
118
|
-
{ semi: true, singleQuote: false, trailingComma: "es5" },
|
|
119
|
-
null,
|
|
120
|
-
2,
|
|
121
|
-
) + "\n",
|
|
94
|
+
"src/index.nsjs",
|
|
95
|
+
"console.log^8^2Hello, World!^2^9;\n",
|
|
122
96
|
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// noshift.js をインストール
|
|
126
|
-
console.log(t("installingNoshift"));
|
|
127
|
-
execSync("npm install noshift.js", { stdio: "inherit" });
|
|
128
|
-
|
|
129
|
-
// src/index.nsjs
|
|
130
|
-
await fs.mkdir("src", { recursive: true });
|
|
131
|
-
await fs.writeFile("src/index.nsjs", "console.log^8^2Hello, World!^2^9;\n");
|
|
132
97
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
lang === "ja"
|
|
136
|
-
? `# ${projectName}
|
|
137
|
-
|
|
138
|
-
[NoShift.js](https://github.com/otoneko1102/NoShift.js) プロジェクトです。
|
|
139
|
-
|
|
140
|
-
## コンパイル
|
|
141
|
-
|
|
142
|
-
\`\`\`bash
|
|
143
|
-
npm run compile
|
|
144
|
-
\`\`\`
|
|
145
|
-
|
|
146
|
-
## 開発 (出力確認)
|
|
147
|
-
|
|
148
|
-
\`\`\`bash
|
|
149
|
-
npm run dev
|
|
150
|
-
\`\`\`
|
|
151
|
-
`
|
|
152
|
-
: `# ${projectName}
|
|
98
|
+
// README.md
|
|
99
|
+
const readme = `# ${projectName}
|
|
153
100
|
|
|
154
101
|
A [NoShift.js](https://github.com/otoneko1102/NoShift.js) project.
|
|
155
102
|
|
|
@@ -159,15 +106,27 @@ A [NoShift.js](https://github.com/otoneko1102/NoShift.js) project.
|
|
|
159
106
|
npm run compile
|
|
160
107
|
\`\`\`
|
|
161
108
|
|
|
162
|
-
## Dev (
|
|
109
|
+
## Dev (watch mode)
|
|
163
110
|
|
|
164
111
|
\`\`\`bash
|
|
165
112
|
npm run dev
|
|
166
113
|
\`\`\`
|
|
167
114
|
`;
|
|
168
115
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
116
|
+
await fs.writeFile("README.md", readme);
|
|
117
|
+
|
|
118
|
+
// Success message
|
|
119
|
+
console.log("");
|
|
120
|
+
logger.success("Project created successfully!");
|
|
121
|
+
console.log("");
|
|
122
|
+
logger.info("Next steps:");
|
|
123
|
+
console.log(` ${logger.highlight(`cd ${projectName}`)}`);
|
|
124
|
+
console.log(` ${logger.highlight("npm run compile")}`);
|
|
125
|
+
console.log("");
|
|
126
|
+
} catch (error) {
|
|
127
|
+
if (isUserCancelled(error)) {
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
173
132
|
}
|
package/commands/dev.js
CHANGED
|
@@ -2,6 +2,8 @@ import { promises as fs, watch } from "fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import convert from "../src/convert.js";
|
|
4
4
|
import { loadConfig } from "../src/config.js";
|
|
5
|
+
import { handleSigint } from "../src/signal-handler.js";
|
|
6
|
+
import * as logger from "../src/logger.js";
|
|
5
7
|
|
|
6
8
|
function timestamp() {
|
|
7
9
|
return new Date().toLocaleTimeString("en-GB"); // HH:MM:SS
|
|
@@ -36,7 +38,7 @@ async function compileFile(file, rootDir, outDir, cwd) {
|
|
|
36
38
|
const js = convert(code);
|
|
37
39
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
38
40
|
await fs.writeFile(destPath, js, "utf-8");
|
|
39
|
-
|
|
41
|
+
logger.dim(
|
|
40
42
|
`[${timestamp()}] ${relative} → ${path.relative(cwd, destPath).replace(/\\/g, "/")}`,
|
|
41
43
|
);
|
|
42
44
|
}
|
|
@@ -48,7 +50,7 @@ export default async function dev() {
|
|
|
48
50
|
try {
|
|
49
51
|
config = await loadConfig(cwd);
|
|
50
52
|
} catch (e) {
|
|
51
|
-
|
|
53
|
+
logger.errorCode("NS0", e.message);
|
|
52
54
|
process.exit(1);
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -58,13 +60,14 @@ export default async function dev() {
|
|
|
58
60
|
// 初回フルコンパイル
|
|
59
61
|
const files = await findNsjsFiles(rootDir);
|
|
60
62
|
if (files === null) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
logger.errorCode(
|
|
64
|
+
"NS0",
|
|
65
|
+
`rootDir '${config.compilerOptions.rootDir}' not found.`,
|
|
63
66
|
);
|
|
64
67
|
process.exit(1);
|
|
65
68
|
}
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
logger.info(`Starting compilation in watch mode...`);
|
|
68
71
|
|
|
69
72
|
await fs.mkdir(outDir, { recursive: true });
|
|
70
73
|
|
|
@@ -73,13 +76,19 @@ export default async function dev() {
|
|
|
73
76
|
await compileFile(file, rootDir, outDir, cwd);
|
|
74
77
|
} catch (e) {
|
|
75
78
|
const rel = path.relative(rootDir, file).replace(/\\/g, "/");
|
|
76
|
-
|
|
79
|
+
logger.errorCode("NS1", `${rel}: ${e.message}`);
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
`
|
|
83
|
+
logger.info(
|
|
84
|
+
`Watching for file changes in '${logger.highlight(config.compilerOptions.rootDir)}'... (Press Ctrl+C to stop)`,
|
|
82
85
|
);
|
|
86
|
+
console.log("");
|
|
87
|
+
|
|
88
|
+
// Ctrl+C で終了
|
|
89
|
+
handleSigint(() => {
|
|
90
|
+
logger.info("Stopped watching.");
|
|
91
|
+
});
|
|
83
92
|
|
|
84
93
|
// デバウンス用マップ (ファイルパス → タイマーID)
|
|
85
94
|
const debounceMap = new Map();
|
|
@@ -105,8 +114,9 @@ export default async function dev() {
|
|
|
105
114
|
if (e.code === "ENOENT") {
|
|
106
115
|
// ファイルが削除された場合はスキップ
|
|
107
116
|
} else {
|
|
108
|
-
|
|
109
|
-
|
|
117
|
+
logger.errorCode(
|
|
118
|
+
"NS1",
|
|
119
|
+
`${filename.replace(/\\/g, "/")}: ${e.message}`,
|
|
110
120
|
);
|
|
111
121
|
}
|
|
112
122
|
}
|
package/commands/init.js
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import { writeFile, access } from "fs/promises";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import { handleSigint } from "../src/signal-handler.js";
|
|
4
|
+
import * as logger from "../src/logger.js";
|
|
3
5
|
|
|
4
6
|
const DEFAULT_CONFIG = {
|
|
5
7
|
compilerOptions: {
|
|
6
8
|
rootDir: "src",
|
|
7
|
-
outDir: "
|
|
9
|
+
outDir: "dist",
|
|
8
10
|
},
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
export default async function init() {
|
|
14
|
+
handleSigint();
|
|
15
|
+
|
|
12
16
|
const configPath = path.join(process.cwd(), "nsjsconfig.json");
|
|
13
17
|
|
|
14
18
|
try {
|
|
15
19
|
await access(configPath);
|
|
16
|
-
|
|
17
|
-
"
|
|
20
|
+
logger.errorCode(
|
|
21
|
+
"NS4",
|
|
22
|
+
"nsjsconfig.json already exists in the current directory.",
|
|
18
23
|
);
|
|
19
24
|
process.exit(1);
|
|
20
25
|
} catch {
|
|
@@ -22,7 +27,8 @@ export default async function init() {
|
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
await writeFile(configPath, JSON.stringify(DEFAULT_CONFIG, null, 2) + "\n");
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
logger.success("Created nsjsconfig.json");
|
|
31
|
+
logger.dim(` compilerOptions.rootDir : ${DEFAULT_CONFIG.compilerOptions.rootDir}`);
|
|
32
|
+
logger.dim(` compilerOptions.outDir : ${DEFAULT_CONFIG.compilerOptions.outDir}`);
|
|
33
|
+
console.log("");
|
|
28
34
|
}
|
package/commands/run.js
CHANGED
|
@@ -2,15 +2,19 @@ import { promises as fs } from "fs";
|
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { spawn } from "child_process";
|
|
4
4
|
import convert from "../src/convert.js";
|
|
5
|
+
import { handleSigint } from "../src/signal-handler.js";
|
|
6
|
+
import * as logger from "../src/logger.js";
|
|
5
7
|
|
|
6
8
|
export default async function run(file) {
|
|
9
|
+
handleSigint();
|
|
10
|
+
|
|
7
11
|
const filePath = path.resolve(process.cwd(), file);
|
|
8
12
|
|
|
9
13
|
let code;
|
|
10
14
|
try {
|
|
11
15
|
code = await fs.readFile(filePath, "utf-8");
|
|
12
16
|
} catch {
|
|
13
|
-
|
|
17
|
+
logger.errorCode("NS2", `File not found: ${filePath}`);
|
|
14
18
|
process.exit(1);
|
|
15
19
|
}
|
|
16
20
|
|
package/package.json
CHANGED
package/src/logger.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// シンプルなロガーユーティリティ(ANSI エスケープコードを使用)
|
|
2
|
+
|
|
3
|
+
const colors = {
|
|
4
|
+
reset: "\x1b[0m",
|
|
5
|
+
bright: "\x1b[1m",
|
|
6
|
+
dim: "\x1b[2m",
|
|
7
|
+
red: "\x1b[31m",
|
|
8
|
+
green: "\x1b[32m",
|
|
9
|
+
yellow: "\x1b[33m",
|
|
10
|
+
blue: "\x1b[34m",
|
|
11
|
+
magenta: "\x1b[35m",
|
|
12
|
+
cyan: "\x1b[36m",
|
|
13
|
+
gray: "\x1b[90m",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function success(message) {
|
|
17
|
+
console.log(`${colors.green}✓${colors.reset} ${message}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function error(message) {
|
|
21
|
+
console.error(`${colors.red}✗${colors.reset} ${message}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function info(message) {
|
|
25
|
+
console.log(`${colors.blue}ℹ${colors.reset} ${message}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function warn(message) {
|
|
29
|
+
console.log(`${colors.yellow}⚠${colors.reset} ${message}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function step(message) {
|
|
33
|
+
console.log(`${colors.cyan}→${colors.reset} ${message}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function dim(message) {
|
|
37
|
+
console.log(`${colors.dim}${message}${colors.reset}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function bold(text) {
|
|
41
|
+
return `${colors.bright}${text}${colors.reset}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function highlight(text) {
|
|
45
|
+
return `${colors.cyan}${text}${colors.reset}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function errorCode(code, message) {
|
|
49
|
+
console.error(
|
|
50
|
+
`${colors.red}error ${code}:${colors.reset} ${message}`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// シグナルハンドリングユーティリティ
|
|
2
|
+
|
|
3
|
+
let isHandlerRegistered = false;
|
|
4
|
+
let cleanupCallbacks = [];
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Ctrl+C (SIGINT) を適切にハンドリングする
|
|
8
|
+
* @param {Function} cleanup - クリーンアップ時に実行する関数(オプション)
|
|
9
|
+
*/
|
|
10
|
+
export function handleSigint(cleanup) {
|
|
11
|
+
if (cleanup) {
|
|
12
|
+
cleanupCallbacks.push(cleanup);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (!isHandlerRegistered) {
|
|
16
|
+
isHandlerRegistered = true;
|
|
17
|
+
|
|
18
|
+
process.on("SIGINT", async () => {
|
|
19
|
+
console.log("\n"); // 改行を追加してきれいに終了
|
|
20
|
+
|
|
21
|
+
// すべてのクリーンアップコールバックを実行
|
|
22
|
+
for (const cb of cleanupCallbacks) {
|
|
23
|
+
try {
|
|
24
|
+
await cb();
|
|
25
|
+
} catch (e) {
|
|
26
|
+
// エラーは無視
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
process.exit(0);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* inquirer のキャンセルエラーをチェック
|
|
37
|
+
* @param {Error} error
|
|
38
|
+
* @returns {boolean}
|
|
39
|
+
*/
|
|
40
|
+
export function isUserCancelled(error) {
|
|
41
|
+
return (
|
|
42
|
+
error &&
|
|
43
|
+
(error.name === "ExitPromptError" ||
|
|
44
|
+
error.message === "User force closed the prompt")
|
|
45
|
+
);
|
|
46
|
+
}
|