jiek 2.0.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.d.cts CHANGED
@@ -90,59 +90,6 @@ declare module 'jiek' {
90
90
  }
91
91
  }
92
92
 
93
- declare module 'jiek' {
94
- type InitNamedFunction = (argument: string, paths: {
95
- full: string;
96
- relative: string;
97
- basename?: string;
98
- }) => [name?: string, path?: string];
99
- type InitNamed = InitNamedFunction | {
100
- [key: string]: string | InitNamedFunction;
101
- };
102
- interface Config {
103
- init?: {
104
- /**
105
- * the package.json template file path or file content
106
- *
107
- * if it can be parsed as json, it will be parsed
108
- * if it is a relative file path, it will be resolved to an absolute path based on the current working directory
109
- * if it is an absolute file path, it will be used directly
110
- * @default '.jiek.template.package.json'
111
- */
112
- template?: string;
113
- /**
114
- * the readme content
115
- *
116
- * $name will be replaced with the package name
117
- * $license will be replaced with the license
118
- */
119
- readme?: string | ((ctx: {
120
- dir: string;
121
- packageJson: Record<string, any>;
122
- }) => string);
123
- /**
124
- * the readme template file path
125
- * @default '.jiek.template.readme.md'
126
- */
127
- readmeTemplate?: string;
128
- bug?: {
129
- /**
130
- * @default 'bug_report.yml'
131
- */
132
- template?: string;
133
- /**
134
- * @default ['bug']
135
- */
136
- labels?: string[] | ((ctx: {
137
- name: string;
138
- dir: string;
139
- }) => string[]);
140
- };
141
- named?: InitNamed;
142
- };
143
- }
144
- }
145
-
146
93
  declare module 'jiek' {
147
94
  interface Config {
148
95
  publish?: {
package/dist/index.d.ts CHANGED
@@ -90,59 +90,6 @@ declare module 'jiek' {
90
90
  }
91
91
  }
92
92
 
93
- declare module 'jiek' {
94
- type InitNamedFunction = (argument: string, paths: {
95
- full: string;
96
- relative: string;
97
- basename?: string;
98
- }) => [name?: string, path?: string];
99
- type InitNamed = InitNamedFunction | {
100
- [key: string]: string | InitNamedFunction;
101
- };
102
- interface Config {
103
- init?: {
104
- /**
105
- * the package.json template file path or file content
106
- *
107
- * if it can be parsed as json, it will be parsed
108
- * if it is a relative file path, it will be resolved to an absolute path based on the current working directory
109
- * if it is an absolute file path, it will be used directly
110
- * @default '.jiek.template.package.json'
111
- */
112
- template?: string;
113
- /**
114
- * the readme content
115
- *
116
- * $name will be replaced with the package name
117
- * $license will be replaced with the license
118
- */
119
- readme?: string | ((ctx: {
120
- dir: string;
121
- packageJson: Record<string, any>;
122
- }) => string);
123
- /**
124
- * the readme template file path
125
- * @default '.jiek.template.readme.md'
126
- */
127
- readmeTemplate?: string;
128
- bug?: {
129
- /**
130
- * @default 'bug_report.yml'
131
- */
132
- template?: string;
133
- /**
134
- * @default ['bug']
135
- */
136
- labels?: string[] | ((ctx: {
137
- name: string;
138
- dir: string;
139
- }) => string[]);
140
- };
141
- named?: InitNamed;
142
- };
143
- }
144
- }
145
-
146
93
  declare module 'jiek' {
147
94
  interface Config {
148
95
  publish?: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jiek",
3
3
  "type": "module",
4
- "version": "2.0.0",
4
+ "version": "2.0.2",
5
5
  "description": "A lightweight toolkit for compiling and managing libraries based on `package.json` metadata and suitable for `Monorepo`.",
6
6
  "author": "YiJie <yijie4188@gmail.com>",
7
7
  "repository": {
@@ -51,6 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@jiek/rollup-plugin-dts": "^6.2.1",
54
+ "@inquirer/prompts": "^7.1.0",
54
55
  "@rollup/plugin-commonjs": "^28.0.0",
55
56
  "@rollup/plugin-json": "^6.0.1",
56
57
  "@rollup/plugin-node-resolve": "^15.3.0",
@@ -58,14 +59,13 @@
58
59
  "commander": "^12.0.0",
59
60
  "detect-indent": "^6.1.0",
60
61
  "execa": "9.3.1",
61
- "inquirer": "^8.2.6",
62
62
  "js-yaml": "^4.1.0",
63
63
  "jsonc-parser": "^3.2.1",
64
64
  "rollup": "4.13.2",
65
65
  "@jiek/pkger": "^0.2.0",
66
66
  "@jiek/utils": "^0.2.3"
67
67
  },
68
- "optionalDependencies": {
68
+ "peerDependencies": {
69
69
  "@rollup/plugin-terser": "^0.4.4",
70
70
  "@pnpm/filter-workspace-packages": "^7.2.13",
71
71
  "esbuild-register": "^3.5.0",
@@ -75,6 +75,32 @@
75
75
  "rollup-plugin-swc3": "^0.12.1",
76
76
  "typescript": "^4.0.0||^5.0.0"
77
77
  },
78
+ "peerDependenciesMeta": {
79
+ "@rollup/plugin-terser": {
80
+ "optional": true
81
+ },
82
+ "@pnpm/filter-workspace-packages": {
83
+ "optional": true
84
+ },
85
+ "esbuild-register": {
86
+ "optional": true
87
+ },
88
+ "postcss": {
89
+ "optional": true
90
+ },
91
+ "rollup-plugin-postcss": {
92
+ "optional": true
93
+ },
94
+ "rollup-plugin-esbuild": {
95
+ "optional": true
96
+ },
97
+ "rollup-plugin-swc3": {
98
+ "optional": true
99
+ },
100
+ "typescript": {
101
+ "optional": true
102
+ }
103
+ },
78
104
  "devDependencies": {
79
105
  "@npm/types": "^1.0.2",
80
106
  "@pnpm/filter-workspace-packages": "^7.2.13",
package/src/cli.ts CHANGED
@@ -1,3 +1,2 @@
1
- import './commands/init'
2
1
  import './commands/publish'
3
2
  import 'jiek/cli-only-build'
@@ -2,6 +2,7 @@ import fs from 'node:fs'
2
2
  import { createRequire } from 'node:module'
3
3
  import path from 'node:path'
4
4
 
5
+ import { confirm } from '@inquirer/prompts'
5
6
  import { MultiBar, Presets } from 'cli-progress'
6
7
  import { program } from 'commander'
7
8
  import { execaCommand } from 'execa'
@@ -100,12 +101,13 @@ async function checkDependency(dependency: string) {
100
101
  require.resolve(dependency)
101
102
  } catch (e) {
102
103
  console.error(`The package '${dependency}' is not installed, please install it first.`)
103
- const answer = prompt('Do you want to install it now? (Y/n)', 'Y')
104
104
  const { notWorkspace } = getWD()
105
- if (answer === 'Y') {
106
- await execaCommand(`pnpm install -${notWorkspace ? '' : 'w'}D ${dependency}`)
105
+ const command = `pnpm install -${notWorkspace ? '' : 'w'}D ${dependency}`
106
+ if (await confirm({ message: 'Do you want to install it now?' })) {
107
+ await execaCommand(command)
107
108
  } else {
108
- return
109
+ console.warn(`You can run the command '${command}' to install it manually.`)
110
+ process.exit(1)
109
111
  }
110
112
  }
111
113
  }
@@ -1,373 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
-
4
- import { program } from 'commander'
5
- import detectIndent from 'detect-indent'
6
- import inquirer from 'inquirer'
7
- import type { Config, InitNamed } from 'jiek'
8
- import { applyEdits, modify } from 'jsonc-parser'
9
- import { isMatch } from 'micromatch'
10
-
11
- import { getWD } from '../utils/getWD'
12
- import { loadConfig } from '../utils/loadConfig'
13
-
14
- declare module 'jiek' {
15
- export type InitNamedFunction = (
16
- argument: string,
17
- paths: {
18
- full: string
19
- relative: string
20
- basename?: string
21
- }
22
- ) => [name?: string, path?: string]
23
- export type InitNamed =
24
- | InitNamedFunction
25
- | {
26
- [key: string]: string | InitNamedFunction
27
- }
28
- export interface Config {
29
- init?: {
30
- /**
31
- * the package.json template file path or file content
32
- *
33
- * if it can be parsed as json, it will be parsed
34
- * if it is a relative file path, it will be resolved to an absolute path based on the current working directory
35
- * if it is an absolute file path, it will be used directly
36
- * @default '.jiek.template.package.json'
37
- */
38
- template?: string
39
- /**
40
- * the readme content
41
- *
42
- * $name will be replaced with the package name
43
- * $license will be replaced with the license
44
- */
45
- readme?:
46
- | string
47
- | ((ctx: {
48
- dir: string
49
- packageJson: Record<string, any>
50
- }) => string)
51
- /**
52
- * the readme template file path
53
- * @default '.jiek.template.readme.md'
54
- */
55
- readmeTemplate?: string
56
- bug?: {
57
- /**
58
- * @default 'bug_report.yml'
59
- */
60
- template?: string
61
- /**
62
- * @default ['bug']
63
- */
64
- labels?:
65
- | string[]
66
- | ((ctx: {
67
- name: string
68
- dir: string
69
- }) => string[])
70
- }
71
- named?: InitNamed
72
- }
73
- }
74
- }
75
-
76
- const PACKAGE_JSON_TEMPLATE = `{
77
- "name": "",
78
- "version": "0.0.1",
79
- "description": "",
80
- "license": "",
81
- "author": "",
82
- "files": ["dist"],
83
- "exports": {
84
- ".": "./src/index.ts"
85
- },
86
- "scripts": {
87
- },
88
- "homepage": "",
89
- "repository": "",
90
- "bugs": ""
91
- }`.trimStart()
92
- const README_TEMPLATE = `# $name
93
-
94
- ## Installation
95
-
96
- \`\`\`bash
97
- npm install $name
98
- # or
99
- pnpm install $name
100
- # or
101
- yarn add $name
102
- \`\`\`
103
-
104
- ## Usage
105
-
106
-
107
- ## License
108
-
109
- $license
110
- `.trimStart()
111
-
112
- function getTemplateStr(wd: string, template: string | undefined) {
113
- let templateString = template ?? PACKAGE_JSON_TEMPLATE
114
- let isTemplateFile = false
115
- try {
116
- if (template) JSON.parse(template)
117
- } catch (e) {
118
- isTemplateFile = true
119
- }
120
- if (isTemplateFile) {
121
- const templatePath = path.resolve(wd, template!)
122
- templateString = fs.readFileSync(templatePath, 'utf-8')
123
- }
124
- return templateString
125
- }
126
- const wdCache = new Map<string, Record<string, any>>()
127
- function getWDPackageJSONFiled(wd: string, field: string) {
128
- if (wdCache.has(wd)) {
129
- return wdCache.get(wd)![field]
130
- }
131
- const packageJSONPath = path.resolve(wd, 'package.json')
132
- const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, 'utf-8'))
133
- wdCache.set(wd, packageJSON)
134
- return packageJSON[field]
135
- }
136
- async function getName(
137
- named: InitNamed | undefined,
138
- name: string,
139
- {
140
- wd,
141
- cwd,
142
- workspaceName
143
- }: {
144
- wd: string
145
- cwd: string
146
- workspaceName: string
147
- }
148
- ): Promise<[name?: string, path?: string]> {
149
- const relativePath = cwd.replace(`${wd}/`, '')
150
- let basename = path.basename(cwd)
151
-
152
- if (typeof named === 'function') {
153
- return named(name, {
154
- full: wd,
155
- relative: cwd
156
- })
157
- }
158
-
159
- let isParentMatched = false
160
- let matchedKey: string | undefined
161
- let matchedRule: NonNullable<typeof named>[string] | undefined
162
- if (typeof named === 'object') {
163
- const isWD = cwd === wd
164
- if (isWD) {
165
- const { rule } = await inquirer.prompt<{ rule: string }>({
166
- type: 'list',
167
- name: 'rule',
168
- message: 'choose a rule',
169
- default: 'default',
170
- choices: ['default'].concat(Object.keys(named))
171
- })
172
- if (rule !== 'default') {
173
- matchedKey = rule
174
- matchedRule = named[rule]
175
- }
176
- } else {
177
- for (const [key, value] of Object.entries(named)) {
178
- if (isMatch(relativePath, key)) {
179
- matchedKey = key
180
- matchedRule = value
181
- break
182
- }
183
- if (isMatch(`${relativePath}/jiek_ignore_dont_use_same_file_name`, key)) {
184
- isParentMatched = true
185
- matchedKey = key
186
- matchedRule = value
187
- break
188
- }
189
- }
190
- }
191
- }
192
- if (!matchedRule) {
193
- matchedKey = 'packages/*'
194
- matchedRule = `@${workspaceName}/$basename`
195
- }
196
- if (!matchedRule) {
197
- throw new Error('no matched rule')
198
- }
199
- if (!name && isParentMatched) {
200
- basename = await inquirer.prompt<{ name: string }>({
201
- type: 'input',
202
- name: 'name',
203
- message: `the matched rule is \`${String(matchedRule)}\`, please input the basename\n`
204
- }).then(({ name }) => name)
205
- }
206
-
207
- if (typeof matchedRule === 'function') {
208
- return matchedRule(name, {
209
- full: wd,
210
- relative: cwd,
211
- basename: basename
212
- })
213
- }
214
- if (typeof matchedRule === 'string') {
215
- const dirName = name ?? basename
216
- return [
217
- matchedRule.replace(/\$basename/g, dirName),
218
- matchedKey?.replace(/\/\*$/g, `/${dirName}`)
219
- ]
220
- }
221
- throw new Error('no matched rule')
222
- }
223
-
224
- program
225
- .command('init [name]')
226
- .option('-t, --template <template>', 'the package.json template file path or file content')
227
- .action(async () => {
228
- const [, name] = program.args
229
- const cwd = process.cwd()
230
- const { init = {} }: Config = loadConfig() ?? {}
231
- const { wd } = getWD()
232
- const workspaceName = path.basename(wd)
233
-
234
- const {
235
- named,
236
- template,
237
- bug = {},
238
- readme: _readme = README_TEMPLATE,
239
- readmeTemplate
240
- } = init
241
- const resolvedBug = {
242
- template: 'bug_report.yml',
243
- labels: ['bug'],
244
- ...bug
245
- }
246
- let readme = _readme
247
- if (readmeTemplate) {
248
- const readmeTemplatePath = path.resolve(wd, readmeTemplate)
249
- readme = fs.readFileSync(readmeTemplatePath, 'utf-8')
250
- }
251
-
252
- const templateString = getTemplateStr(wd, template)
253
- // TODO detectIndent by editorconfig
254
- const { indent = ' ' } = detectIndent(templateString)
255
- const formattingOptions = {
256
- tabSize: indent.length,
257
- insertSpaces: true
258
- }
259
- const passFields = [
260
- 'license',
261
- 'author'
262
- ]
263
- let newJSONString = templateString
264
- for (const field of passFields) {
265
- newJSONString = applyEdits(
266
- newJSONString,
267
- modify(
268
- newJSONString,
269
- [field],
270
- getWDPackageJSONFiled(wd, field),
271
- { formattingOptions }
272
- )
273
- )
274
- }
275
- let [pkgName, pkgDir] = await getName(named, name, {
276
- wd,
277
- cwd,
278
- workspaceName
279
- })
280
- if (!pkgDir) {
281
- const { dir } = await inquirer.prompt<{ dir: string }>({
282
- type: 'input',
283
- name: 'dir',
284
- message: 'package directory',
285
- default: name
286
- })
287
- pkgDir = dir
288
- }
289
- if (!pkgName) {
290
- const { name: inputName } = await inquirer.prompt<{
291
- name: string
292
- }>({
293
- type: 'input',
294
- name: 'name',
295
- message: 'package name',
296
- default: name
297
- })
298
- pkgName = inputName
299
- }
300
- newJSONString = applyEdits(newJSONString, modify(newJSONString, ['name'], pkgName, { formattingOptions }))
301
-
302
- let pkgRepo = getWDPackageJSONFiled(wd, 'repository')
303
- if (typeof pkgRepo === 'string') {
304
- pkgRepo = {
305
- type: 'git',
306
- url: pkgRepo,
307
- directory: pkgDir
308
- }
309
- }
310
- newJSONString = applyEdits(
311
- newJSONString,
312
- modify(
313
- newJSONString,
314
- ['repository'],
315
- pkgRepo,
316
- { formattingOptions }
317
- )
318
- )
319
- const homepage = `${pkgRepo?.url}/blob/master/${pkgDir}/README.md`
320
- newJSONString = applyEdits(
321
- newJSONString,
322
- modify(
323
- newJSONString,
324
- ['homepage'],
325
- homepage,
326
- { formattingOptions }
327
- )
328
- )
329
- let labels = resolvedBug.labels
330
- if (typeof labels === 'function') {
331
- labels = labels({
332
- name: pkgName,
333
- dir: pkgDir
334
- })
335
- }
336
- labels.push(`scope:${pkgName}`)
337
- const bugs = `${pkgRepo?.url}/issues/new?template=${resolvedBug.template}&labels=${labels.join(',')}`
338
- newJSONString = applyEdits(
339
- newJSONString,
340
- modify(
341
- newJSONString,
342
- ['bugs'],
343
- bugs,
344
- { formattingOptions }
345
- )
346
- )
347
-
348
- function pkgDirTo(to: string) {
349
- if (!pkgDir) throw new Error('pkgDir is not defined')
350
-
351
- return path.resolve(pkgDir, to)
352
- }
353
- if (!fs.existsSync(pkgDir)) fs.mkdirSync(pkgDir)
354
- const pkgJSONFilePath = pkgDirTo('package.json')
355
- if (fs.existsSync(pkgJSONFilePath)) {
356
- throw new Error('package.json already exists')
357
- }
358
- fs.writeFileSync(pkgJSONFilePath, newJSONString)
359
- console.log(newJSONString, 'written to', pkgJSONFilePath)
360
-
361
- const license = getWDPackageJSONFiled(wd, 'license')
362
- const readmeFilePath = pkgDirTo('README.md')
363
- if (typeof readme === 'function') {
364
- readme = readme({
365
- dir: pkgDir,
366
- packageJson: JSON.parse(newJSONString)
367
- })
368
- }
369
- const readmeContent = readme
370
- .replace(/\$name/g, pkgName)
371
- .replace(/\$license/g, license)
372
- fs.writeFileSync(readmeFilePath, readmeContent)
373
- })