1- import { writeFile , access } from "fs/promises" ;
1+ import { writeFile , readFile , access } from "fs/promises" ;
22import path from "path" ;
33import { handleSigint } from "../src/signal-handler.js" ;
44import * as logger from "../src/logger.js" ;
5+ import { askConfirm } from "../src/prompt.js" ;
56
67const DEFAULT_CONFIG = {
78 compileroptions : {
@@ -12,29 +13,152 @@ const DEFAULT_CONFIG = {
1213 } ,
1314} ;
1415
16+ /** .prettierrc 系のファイル名(優先順) */
17+ const PRETTIERRC_FILES = [
18+ ".prettierrc" ,
19+ ".prettierrc.json" ,
20+ ".prettierrc.yml" ,
21+ ".prettierrc.yaml" ,
22+ ".prettierrc.json5" ,
23+ ".prettierrc.cjs" ,
24+ ".prettierrc.mjs" ,
25+ "prettier.config.js" ,
26+ "prettier.config.cjs" ,
27+ "prettier.config.mjs" ,
28+ ] ;
29+
30+ const PLUGIN_NAME = "prettier-plugin-noshift.js" ;
31+
32+ /**
33+ * 既存の .prettierrc / .prettierrc.json を読み込み plugins に追加する。
34+ * JSON 形式のみ自動編集可能。それ以外は手動追加を案内する。
35+ * @param {string } filePath
36+ */
37+ async function addPluginToExistingConfig ( filePath ) {
38+ const basename = path . basename ( filePath ) ;
39+ const isJson =
40+ basename === ".prettierrc" ||
41+ basename === ".prettierrc.json" ;
42+
43+ if ( ! isJson ) {
44+ logger . warn (
45+ `Found ${ basename } — please add "${ PLUGIN_NAME } " to the plugins array manually.` ,
46+ ) ;
47+ return ;
48+ }
49+
50+ try {
51+ const raw = await readFile ( filePath , "utf-8" ) ;
52+ const config = JSON . parse ( raw ) ;
53+ const plugins = Array . isArray ( config . plugins ) ? config . plugins : [ ] ;
54+
55+ if ( plugins . includes ( PLUGIN_NAME ) ) {
56+ logger . info ( `${ basename } already contains "${ PLUGIN_NAME } ".` ) ;
57+ return ;
58+ }
59+
60+ plugins . push ( PLUGIN_NAME ) ;
61+ config . plugins = plugins ;
62+ await writeFile ( filePath , JSON . stringify ( config , null , 2 ) + "\n" ) ;
63+ logger . success ( `Added "${ PLUGIN_NAME } " to ${ basename } ` ) ;
64+ } catch ( err ) {
65+ logger . error ( `Failed to update ${ basename } : ${ err . message } ` ) ;
66+ logger . warn ( `Please add "${ PLUGIN_NAME } " to the plugins array manually.` ) ;
67+ }
68+ }
69+
70+ /**
71+ * 新しい .prettierrc を作成する
72+ */
73+ async function createPrettierConfig ( ) {
74+ const prettierConfig = {
75+ semi : true ,
76+ singleQuote : false ,
77+ trailingComma : "es5" ,
78+ plugins : [ PLUGIN_NAME ] ,
79+ } ;
80+ await writeFile ( ".prettierrc" , JSON . stringify ( prettierConfig , null , 2 ) + "\n" ) ;
81+ logger . success ( "Created .prettierrc" ) ;
82+ }
83+
1584export default async function init ( ) {
1685 handleSigint ( ) ;
1786
18- const configPath = path . join ( process . cwd ( ) , "nsjsconfig.json" ) ;
87+ const cwd = process . cwd ( ) ;
88+ const configPath = path . join ( cwd , "nsjsconfig.json" ) ;
1989
90+ // ── nsjsconfig.json ──
91+ let configExists = false ;
2092 try {
2193 await access ( configPath ) ;
22- logger . errorCode (
23- "NS4" ,
24- "nsjsconfig.json already exists in the current directory." ,
25- ) ;
26- process . exit ( 1 ) ;
94+ configExists = true ;
2795 } catch {
28- // ファイルが存在しないのが正常
96+ // not found — OK
97+ }
98+
99+ if ( configExists ) {
100+ logger . warn ( "nsjsconfig.json already exists in the current directory." ) ;
101+ const overwrite = await askConfirm ( "Overwrite?" , false ) ;
102+ if ( ! overwrite ) {
103+ logger . info ( "Skipped nsjsconfig.json" ) ;
104+ } else {
105+ await writeFile (
106+ configPath ,
107+ JSON . stringify ( DEFAULT_CONFIG , null , 2 ) + "\n" ,
108+ ) ;
109+ logger . success ( "Overwritten nsjsconfig.json" ) ;
110+ }
111+ } else {
112+ await writeFile (
113+ configPath ,
114+ JSON . stringify ( DEFAULT_CONFIG , null , 2 ) + "\n" ,
115+ ) ;
116+ logger . success ( "Created nsjsconfig.json" ) ;
29117 }
30118
31- await writeFile ( configPath , JSON . stringify ( DEFAULT_CONFIG , null , 2 ) + "\n" ) ;
32- logger . success ( "Created nsjsconfig.json" ) ;
33119 logger . dim (
34120 ` compileroptions.rootdir : ${ DEFAULT_CONFIG . compileroptions . rootdir } ` ,
35121 ) ;
36122 logger . dim (
37123 ` compileroptions.outdir : ${ DEFAULT_CONFIG . compileroptions . outdir } ` ,
38124 ) ;
125+
126+ // ── Prettier ──
127+ const usePrettier = await askConfirm ( "Set up Prettier?" , true ) ;
128+
129+ if ( usePrettier ) {
130+ // 既存の prettierrc 系ファイルを探す
131+ let existingFile = null ;
132+ for ( const name of PRETTIERRC_FILES ) {
133+ try {
134+ await access ( path . join ( cwd , name ) ) ;
135+ existingFile = name ;
136+ break ;
137+ } catch {
138+ // not found — continue
139+ }
140+ }
141+
142+ if ( existingFile ) {
143+ await addPluginToExistingConfig ( path . join ( cwd , existingFile ) ) ;
144+ } else {
145+ await createPrettierConfig ( ) ;
146+ }
147+
148+ // .prettierignore
149+ const ignorePath = path . join ( cwd , ".prettierignore" ) ;
150+ let ignoreExists = false ;
151+ try {
152+ await access ( ignorePath ) ;
153+ ignoreExists = true ;
154+ } catch {
155+ // not found
156+ }
157+ if ( ! ignoreExists ) {
158+ await writeFile ( ignorePath , "dist/\nnode_modules/\n" ) ;
159+ logger . success ( "Created .prettierignore" ) ;
160+ }
161+ }
162+
39163 console . log ( "" ) ;
40164}
0 commit comments