@sanity/pkg-utils 2.2.16 → 2.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.
Files changed (84) hide show
  1. package/README.md +16 -7
  2. package/dist/_chunks/{build-ba8f4eab.cjs → build-0aed2000.cjs} +11 -8
  3. package/dist/_chunks/build-0aed2000.cjs.map +1 -0
  4. package/dist/_chunks/{buildAction-f35f5fe0.cjs → buildAction-196fba7b.cjs} +2 -2
  5. package/dist/_chunks/{buildAction-f35f5fe0.cjs.map → buildAction-196fba7b.cjs.map} +1 -1
  6. package/dist/_chunks/{check-c18ac13f.cjs → check-2deafe2a.cjs} +25 -31
  7. package/dist/_chunks/check-2deafe2a.cjs.map +1 -0
  8. package/dist/_chunks/{checkAction-be47c642.cjs → checkAction-7ac5a05e.cjs} +2 -2
  9. package/dist/_chunks/{checkAction-be47c642.cjs.map → checkAction-7ac5a05e.cjs.map} +1 -1
  10. package/dist/_chunks/{index-b295a336.cjs → index-984e18d1.cjs} +6 -3
  11. package/dist/_chunks/index-984e18d1.cjs.map +1 -0
  12. package/dist/_chunks/init-ab36343b.cjs +469 -0
  13. package/dist/_chunks/init-ab36343b.cjs.map +1 -0
  14. package/dist/_chunks/initAction-d18cf4f2.cjs +16 -0
  15. package/dist/_chunks/initAction-d18cf4f2.cjs.map +1 -0
  16. package/dist/_chunks/logger-c593f06b.cjs +97 -0
  17. package/dist/_chunks/logger-c593f06b.cjs.map +1 -0
  18. package/dist/_chunks/{resolveBuildContext-2239fc5e.cjs → resolveBuildContext-5ef90110.cjs} +13 -92
  19. package/dist/_chunks/resolveBuildContext-5ef90110.cjs.map +1 -0
  20. package/dist/_chunks/{watch-5bfb8b28.cjs → watch-63a93eb0.cjs} +10 -7
  21. package/dist/_chunks/watch-63a93eb0.cjs.map +1 -0
  22. package/dist/_chunks/{watchAction-788563ea.cjs → watchAction-95c0b481.cjs} +2 -2
  23. package/dist/_chunks/{watchAction-788563ea.cjs.map → watchAction-95c0b481.cjs.map} +1 -1
  24. package/dist/cli.cjs +17 -7
  25. package/dist/cli.cjs.map +1 -1
  26. package/dist/index.cjs +12 -7
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.ts +87 -0
  29. package/dist/index.js +465 -32
  30. package/dist/index.js.map +1 -1
  31. package/package.json +93 -79
  32. package/src/cli/index.ts +12 -3
  33. package/src/cli/initAction.ts +13 -0
  34. package/src/node/build.ts +1 -1
  35. package/src/node/check.ts +4 -2
  36. package/src/node/core/config/findConfigFile.ts +6 -14
  37. package/src/node/core/config/index.ts +1 -1
  38. package/src/node/core/config/loadConfig.ts +2 -1
  39. package/src/node/core/contexts/buildContext.ts +2 -1
  40. package/src/node/core/findCommonPath.test.ts +1 -0
  41. package/src/node/core/index.ts +3 -2
  42. package/src/node/core/pkg/loadPkg.ts +1 -0
  43. package/src/node/core/pkg/loadPkgWithReporting.ts +1 -0
  44. package/src/node/core/pkg/types.ts +13 -0
  45. package/src/node/core/pkg/validatePkg.ts +1 -0
  46. package/src/node/core/template/createFromTemplate.ts +85 -0
  47. package/src/node/core/template/define.ts +6 -0
  48. package/src/node/core/template/index.ts +3 -0
  49. package/src/node/core/template/types.ts +45 -0
  50. package/src/node/fileExists.ts +12 -0
  51. package/src/node/globFiles.ts +1 -1
  52. package/src/node/index.ts +1 -0
  53. package/src/node/init.ts +55 -0
  54. package/src/node/isEmptyDirectory.ts +5 -0
  55. package/src/node/printExtractMessages.ts +2 -1
  56. package/src/node/printPackageTree.ts +4 -13
  57. package/src/node/resolveBuildContext.ts +5 -4
  58. package/src/node/resolveBuildTasks.ts +2 -1
  59. package/src/node/resolveWatchTasks.ts +3 -2
  60. package/src/node/tasks/dts/buildTypes.ts +1 -0
  61. package/src/node/tasks/dts/createApiExtractorConfig.ts +1 -1
  62. package/src/node/tasks/dts/createTSDocConfig.ts +1 -1
  63. package/src/node/tasks/dts/doExtract.ts +2 -1
  64. package/src/node/tasks/dts/dtsTask.ts +1 -0
  65. package/src/node/tasks/dts/dtsWatchTask.ts +1 -0
  66. package/src/node/tasks/dts/extractTypes.ts +4 -3
  67. package/src/node/tasks/dts/getExtractMessagesConfig.ts +2 -1
  68. package/src/node/tasks/dts/printDiagnostic.ts +2 -1
  69. package/src/node/tasks/index.ts +1 -1
  70. package/src/node/tasks/node/reexportCjsTask.ts +3 -2
  71. package/src/node/tasks/rollup/resolveRollupConfig.ts +2 -1
  72. package/src/node/tasks/rollup/rollupTask.ts +2 -1
  73. package/src/node/tasks/rollup/rollupWatchTask.ts +2 -1
  74. package/src/node/tasks/types.ts +2 -1
  75. package/src/node/templates/default/index.ts +1 -0
  76. package/src/node/templates/default/template.ts +553 -0
  77. package/src/node/templates/index.ts +1 -0
  78. package/src/node/watch.ts +2 -1
  79. package/src/node/watchConfigFiles.ts +1 -0
  80. package/dist/_chunks/build-ba8f4eab.cjs.map +0 -1
  81. package/dist/_chunks/check-c18ac13f.cjs.map +0 -1
  82. package/dist/_chunks/index-b295a336.cjs.map +0 -1
  83. package/dist/_chunks/resolveBuildContext-2239fc5e.cjs.map +0 -1
  84. package/dist/_chunks/watch-5bfb8b28.cjs.map +0 -1
package/package.json CHANGED
@@ -1,9 +1,6 @@
1
1
  {
2
- "type": "module",
3
2
  "name": "@sanity/pkg-utils",
4
- "version": "2.2.16",
5
- "author": "Sanity.io <hello@sanity.io>",
6
- "license": "MIT",
3
+ "version": "2.3.0",
7
4
  "description": "Simple utilities for modern npm packages.",
8
5
  "keywords": [
9
6
  "sanity-io",
@@ -14,10 +11,17 @@
14
11
  "build",
15
12
  "bundling"
16
13
  ],
17
- "source": "./src/node/index.ts",
18
- "main": "./dist/index.cjs",
19
- "module": "./dist/index.js",
20
- "types": "./dist/index.d.ts",
14
+ "homepage": "https://github.com/sanity-io/pkg-utils#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/sanity-io/pkg-utils/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+ssh://git@github.com/sanity-io/pkg-utils.git"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Sanity.io <hello@sanity.io>",
24
+ "type": "module",
21
25
  "exports": {
22
26
  ".": {
23
27
  "types": "./dist/index.d.ts",
@@ -28,6 +32,10 @@
28
32
  },
29
33
  "./package.json": "./package.json"
30
34
  },
35
+ "main": "./dist/index.cjs",
36
+ "module": "./dist/index.js",
37
+ "source": "./src/node/index.ts",
38
+ "types": "./dist/index.d.ts",
31
39
  "bin": {
32
40
  "pkg": "./bin/pkg-utils.cjs",
33
41
  "pkg-utils": "./bin/pkg-utils.cjs"
@@ -46,7 +54,7 @@
46
54
  "clean": "rimraf dist",
47
55
  "commit": "cz",
48
56
  "extract": "sanity-tsdoc etl --outDir etc/api/@sanity/pkg-utils --tsconfig tsconfig.dist.json",
49
- "format": "prettier --write --cache --ignore-unknown .",
57
+ "format": "prettier --write --cache --ignore-unknown . && eslint . --ext .cjs,.js,.ts,.tsx --fix --quiet",
50
58
  "lint": "eslint . --ext .cjs,.js,.ts,.tsx",
51
59
  "playground:build": "pnpm --filter './playground/**' build",
52
60
  "playground:clean": "pnpm --filter './playground/**' --silent clean",
@@ -55,10 +63,66 @@
55
63
  "test": "run-s playground:clean && rimraf test/env/__tmp__ && vitest run",
56
64
  "watch": "node --loader esbuild-register/loader -r esbuild-register scripts/watch"
57
65
  },
66
+ "commitlint": {
67
+ "extends": [
68
+ "@commitlint/config-conventional"
69
+ ]
70
+ },
71
+ "lint-staged": {
72
+ "*": [
73
+ "prettier --write --cache --ignore-unknown",
74
+ "eslint --ext .cjs,.js,.ts,.tsx --fix"
75
+ ]
76
+ },
77
+ "prettier": {
78
+ "bracketSpacing": false,
79
+ "plugins": [
80
+ "prettier-plugin-packagejson"
81
+ ],
82
+ "printWidth": 100,
83
+ "semi": false,
84
+ "singleQuote": true,
85
+ "tabWidth": 2,
86
+ "overrides": [
87
+ {
88
+ "files": [
89
+ "*.json5"
90
+ ],
91
+ "options": {
92
+ "quoteProps": "preserve",
93
+ "singleQuote": false
94
+ }
95
+ },
96
+ {
97
+ "files": [
98
+ "*.yml"
99
+ ],
100
+ "options": {
101
+ "singleQuote": false
102
+ }
103
+ }
104
+ ]
105
+ },
106
+ "release": {
107
+ "branches": [
108
+ "+([0-9])?(.{+([0-9]),x}).x",
109
+ "main",
110
+ "next",
111
+ {
112
+ "name": "beta",
113
+ "prerelease": true
114
+ },
115
+ {
116
+ "name": "alpha",
117
+ "prerelease": true
118
+ }
119
+ ],
120
+ "extends": "@sanity/semantic-release-preset"
121
+ },
58
122
  "dependencies": {
59
- "@babel/core": "^7.21.8",
60
- "@babel/preset-env": "^7.21.5",
61
- "@babel/types": "^7.21.5",
123
+ "@babel/core": "^7.22.1",
124
+ "@babel/preset-env": "^7.22.2",
125
+ "@babel/types": "^7.22.3",
62
126
  "@microsoft/api-extractor": "^7.35.0",
63
127
  "@microsoft/tsdoc-config": "^0.16.2",
64
128
  "@rollup/plugin-alias": "^5.0.0",
@@ -68,19 +132,25 @@
68
132
  "@rollup/plugin-node-resolve": "^15.0.2",
69
133
  "@rollup/plugin-replace": "^5.0.2",
70
134
  "@rollup/plugin-terser": "^0.4.3",
71
- "browserslist": "^4.21.5",
135
+ "browserslist": "^4.21.7",
72
136
  "cac": "^6.7.14",
73
137
  "chalk": "^4.1.2",
74
138
  "chokidar": "^3.5.3",
75
139
  "esbuild": "^0.17.19",
76
140
  "esbuild-register": "^3.4.2",
77
141
  "find-config": "^1.0.0",
142
+ "get-latest-version": "^5.0.1",
143
+ "git-url-parse": "^13.1.0",
78
144
  "globby": "^11.1.0",
79
145
  "jsonc-parser": "^3.2.0",
80
146
  "mkdirp": "^3.0.1",
147
+ "outdent": "^0.8.0",
148
+ "parse-git-config": "^3.0.0",
81
149
  "pkg-up": "^3.1.0",
82
150
  "prettier": "^2.8.8",
151
+ "prettier-plugin-packagejson": "^2.4.3",
83
152
  "pretty-bytes": "^5.6.0",
153
+ "prompts": "^2.4.2",
84
154
  "recast": "^0.23.2",
85
155
  "rimraf": "^5.0.1",
86
156
  "rollup": "^3.23.0",
@@ -91,15 +161,18 @@
91
161
  "zod": "^3.21.4"
92
162
  },
93
163
  "devDependencies": {
94
- "@commitlint/cli": "^17.4.4",
95
- "@commitlint/config-conventional": "^17.4.4",
164
+ "@commitlint/cli": "^17.6.3",
165
+ "@commitlint/config-conventional": "^17.6.3",
96
166
  "@sanity/pkg-utils": "workspace:*",
97
167
  "@sanity/semantic-release-preset": "4.1.1",
98
- "@types/babel__core": "^7.20.0",
168
+ "@types/babel__core": "^7.20.1",
99
169
  "@types/cpx": "^1.5.2",
100
170
  "@types/find-config": "^1.0.1",
101
- "@types/node": "^18.15.3",
171
+ "@types/git-url-parse": "^9.0.1",
172
+ "@types/node": "^20.2.5",
173
+ "@types/parse-git-config": "^3.0.1",
102
174
  "@types/prettier": "^2.7.2",
175
+ "@types/prompts": "^2.4.4",
103
176
  "@types/treeify": "^1.0.0",
104
177
  "@types/uuid": "^9.0.1",
105
178
  "@typescript-eslint/eslint-plugin": "^5.59.7",
@@ -111,6 +184,7 @@
111
184
  "eslint-config-prettier": "^8.8.0",
112
185
  "eslint-plugin-import": "^2.27.5",
113
186
  "eslint-plugin-prettier": "^4.2.1",
187
+ "eslint-plugin-simple-import-sort": "10.0.0",
114
188
  "husky": "^8.0.3",
115
189
  "lint-staged": "^13.2.2",
116
190
  "npm-run-all": "^4.1.5",
@@ -124,76 +198,16 @@
124
198
  "peerDependencies": {
125
199
  "typescript": "^4.7 || ^5"
126
200
  },
201
+ "packageManager": "pnpm@8.6.0",
127
202
  "engines": {
128
- "node": ">=14.0.0"
129
- },
130
- "lint-staged": {
131
- "*": [
132
- "prettier --write --cache --ignore-unknown"
133
- ]
134
- },
135
- "repository": {
136
- "type": "git",
137
- "url": "git+ssh://git@github.com/sanity-io/pkg-utils.git"
138
- },
139
- "bugs": {
140
- "url": "https://github.com/sanity-io/pkg-utils/issues"
141
- },
142
- "homepage": "https://github.com/sanity-io/pkg-utils#readme",
143
- "commitlint": {
144
- "extends": [
145
- "@commitlint/config-conventional"
146
- ]
203
+ "node": ">=16.0.0"
147
204
  },
148
205
  "publishConfig": {
149
206
  "access": "public"
150
207
  },
151
- "packageManager": "pnpm@7.32.4",
152
208
  "pnpm": {
153
209
  "overrides": {
154
210
  "@sanity/pkg-utils": "workspace:*"
155
211
  }
156
- },
157
- "prettier": {
158
- "bracketSpacing": false,
159
- "printWidth": 100,
160
- "semi": false,
161
- "singleQuote": true,
162
- "tabWidth": 2,
163
- "overrides": [
164
- {
165
- "files": [
166
- "*.json5"
167
- ],
168
- "options": {
169
- "singleQuote": false,
170
- "quoteProps": "preserve"
171
- }
172
- },
173
- {
174
- "files": [
175
- "*.yml"
176
- ],
177
- "options": {
178
- "singleQuote": false
179
- }
180
- }
181
- ]
182
- },
183
- "release": {
184
- "extends": "@sanity/semantic-release-preset",
185
- "branches": [
186
- "+([0-9])?(.{+([0-9]),x}).x",
187
- "main",
188
- "next",
189
- {
190
- "name": "beta",
191
- "prerelease": true
192
- },
193
- {
194
- "name": "alpha",
195
- "prerelease": true
196
- }
197
- ]
198
212
  }
199
213
  }
package/src/cli/index.ts CHANGED
@@ -1,17 +1,18 @@
1
1
  import cac from 'cac'
2
+
2
3
  import {version} from '../../package.json'
3
4
 
4
5
  const cli = cac()
5
6
 
6
- // default commands checks package status
7
7
  cli
8
8
  .command('', 'Check')
9
+ .alias('check') // alias to align with the action name
9
10
  .option('--strict', 'Strict mode')
10
11
  .option('--tsconfig [tsconfig]', '[string] tsconfig.json')
11
12
  .action(async (options) => {
12
- const {checkAction: statusAction} = await import('./checkAction')
13
+ const {checkAction} = await import('./checkAction')
13
14
 
14
- return statusAction(options)
15
+ return checkAction(options)
15
16
  })
16
17
 
17
18
  cli
@@ -25,6 +26,14 @@ cli
25
26
  return buildAction(options)
26
27
  })
27
28
 
29
+ cli.command('init [path]', 'Initialize package').action(async (p) => {
30
+ const {initAction} = await import('./initAction')
31
+
32
+ return initAction({
33
+ path: p,
34
+ })
35
+ })
36
+
28
37
  cli
29
38
  .command('watch', 'Watch package')
30
39
  .option('--strict', 'Strict mode')
@@ -0,0 +1,13 @@
1
+ import {init} from '../node/init'
2
+ import {handleError} from './handleError'
3
+
4
+ export async function initAction(options: {path: string}): Promise<void> {
5
+ try {
6
+ await init({
7
+ cwd: process.cwd(),
8
+ path: options.path,
9
+ })
10
+ } catch (err) {
11
+ handleError(err)
12
+ }
13
+ }
package/src/node/build.ts CHANGED
@@ -3,7 +3,7 @@ import {createLogger} from './logger'
3
3
  import {resolveBuildContext} from './resolveBuildContext'
4
4
  import {resolveBuildTasks} from './resolveBuildTasks'
5
5
  import {createSpinner} from './spinner'
6
- import {BuildTask, TaskHandler, buildTaskHandlers} from './tasks'
6
+ import {BuildTask, buildTaskHandlers, TaskHandler} from './tasks'
7
7
 
8
8
  /**
9
9
  * Build the distribution files of a npm package.
package/src/node/check.ts CHANGED
@@ -1,8 +1,10 @@
1
- import path from 'path'
2
1
  import esbuild, {BuildFailure} from 'esbuild'
2
+ import path from 'path'
3
+
3
4
  import {getPkgExtMap, loadConfig, loadPkgWithReporting} from './core'
5
+ import {fileExists} from './fileExists'
4
6
  import {createLogger} from './logger'
5
- import {fileExists, printPackageTree} from './printPackageTree'
7
+ import {printPackageTree} from './printPackageTree'
6
8
  import {resolveBuildContext} from './resolveBuildContext'
7
9
 
8
10
  /** @public */
@@ -1,6 +1,7 @@
1
- import {stat} from 'fs/promises'
2
- import path from 'path'
3
1
  import findConfig from 'find-config'
2
+ import path from 'path'
3
+
4
+ import {fileExists} from '../../fileExists'
4
5
 
5
6
  const CONFIG_FILE_NAMES = [
6
7
  'package.config.ts',
@@ -9,7 +10,8 @@ const CONFIG_FILE_NAMES = [
9
10
  'package.config.mjs',
10
11
  ]
11
12
 
12
- export async function findConfigFile(cwd: string): Promise<string | undefined> {
13
+ /** @internal */
14
+ export function findConfigFile(cwd: string): string | undefined {
13
15
  const pkgJsonPath = findConfig('package.json', {cwd})
14
16
 
15
17
  if (!pkgJsonPath) return undefined
@@ -19,7 +21,7 @@ export async function findConfigFile(cwd: string): Promise<string | undefined> {
19
21
  for (const fileName of CONFIG_FILE_NAMES) {
20
22
  const configPath = path.resolve(pkgPath, fileName)
21
23
 
22
- const exists = await fileExists(configPath)
24
+ const exists = fileExists(configPath)
23
25
 
24
26
  if (exists) {
25
27
  return configPath
@@ -28,13 +30,3 @@ export async function findConfigFile(cwd: string): Promise<string | undefined> {
28
30
 
29
31
  return undefined
30
32
  }
31
-
32
- async function fileExists(filePath: string) {
33
- try {
34
- await stat(filePath)
35
-
36
- return true
37
- } catch (_) {
38
- return false
39
- }
40
- }
@@ -1,4 +1,4 @@
1
+ export * from './defineConfig'
1
2
  export * from './loadConfig'
2
3
  export * from './resolveConfigProperty'
3
- export * from './defineConfig'
4
4
  export * from './types'
@@ -1,6 +1,7 @@
1
- import path from 'path'
2
1
  import {register} from 'esbuild-register/dist/node'
2
+ import path from 'path'
3
3
  import pkgUp from 'pkg-up'
4
+
4
5
  import {findConfigFile} from './findConfigFile'
5
6
  import {PkgConfigOptions} from './types'
6
7
 
@@ -1,6 +1,7 @@
1
1
  import ts from 'typescript'
2
+
2
3
  import {Logger} from '../../logger'
3
- import {PkgExports, PkgRuntime, PkgConfigOptions} from '../config'
4
+ import {PkgConfigOptions, PkgExports, PkgRuntime} from '../config'
4
5
  import {PackageJSON, PkgExtMap} from '../pkg'
5
6
 
6
7
  /** @internal */
@@ -1,4 +1,5 @@
1
1
  import {expect, test} from 'vitest'
2
+
2
3
  import {findCommonDirPath} from './findCommonPath'
3
4
 
4
5
  test('should find common parent directory of paths', () => {
@@ -1,6 +1,7 @@
1
- export * from './defaults'
2
- export * from './isRecord'
3
1
  export * from './config'
4
2
  export * from './contexts'
3
+ export * from './defaults'
4
+ export * from './isRecord'
5
5
  export * from './pkg'
6
+ export * from './template'
6
7
  export * from './ts'
@@ -1,5 +1,6 @@
1
1
  import fs from 'fs/promises'
2
2
  import pkgUp from 'pkg-up'
3
+
3
4
  import {PackageJSON} from './types'
4
5
  import {validatePkg} from './validatePkg'
5
6
 
@@ -1,5 +1,6 @@
1
1
  import chalk from 'chalk'
2
2
  import {ZodError} from 'zod'
3
+
3
4
  import {Logger} from '../../logger'
4
5
  import {assertFirst, assertLast, assertOrder} from './helpers'
5
6
  import {loadPkg} from './loadPkg'
@@ -3,7 +3,10 @@ export interface PackageJSON {
3
3
  type?: 'commonjs' | 'module'
4
4
  version: string
5
5
  private?: boolean
6
+ author?: string | {name: string; email?: string; url?: string}
6
7
  name: string
8
+ description?: string
9
+ keywords?: string[]
7
10
  bin?: Record<string, string>
8
11
  dependencies?: Record<string, string>
9
12
  devDependencies?: Record<string, string>
@@ -34,5 +37,15 @@ export interface PackageJSON {
34
37
  source?: string
35
38
  module?: string
36
39
  types?: string
40
+ files?: string[]
41
+ scripts?: Record<string, string>
37
42
  browserslist?: string[]
43
+ engines?: {
44
+ node?: string
45
+ npm?: string
46
+ }
47
+ repository?: string | {type: 'git'; url: string}
48
+ bugs?: string | {url: string; email?: string}
49
+ homepage?: string
50
+ license?: string
38
51
  }
@@ -1,4 +1,5 @@
1
1
  import {z} from 'zod'
2
+
2
3
  import {PackageJSON} from './types'
3
4
 
4
5
  const pkgSchema = z.object({
@@ -0,0 +1,85 @@
1
+ import {writeFile} from 'fs/promises'
2
+ import {mkdirp} from 'mkdirp'
3
+ import {dirname, relative, resolve} from 'path'
4
+ import prompts from 'prompts'
5
+
6
+ import {Logger} from '../../logger'
7
+ import {PkgTemplate} from './types'
8
+
9
+ const promptsTypes = {
10
+ string: 'text' as const,
11
+ }
12
+
13
+ /** @internal */
14
+ export async function createFromTemplate(options: {
15
+ cwd: string
16
+ logger: Logger
17
+ packagePath: string
18
+ template: PkgTemplate
19
+ }): Promise<void> {
20
+ const {cwd, logger, packagePath, template: templateOrResolver} = options
21
+
22
+ const template =
23
+ typeof templateOrResolver === 'function'
24
+ ? await templateOrResolver({cwd, logger, packagePath})
25
+ : templateOrResolver
26
+
27
+ logger.log('create new package at', relative(cwd, packagePath))
28
+
29
+ const templateOptions: Record<string, string> = {}
30
+
31
+ for (const templateOption of template.options) {
32
+ const templateValidate = templateOption.validate
33
+
34
+ const res = await prompts(
35
+ {
36
+ type: promptsTypes[templateOption.type],
37
+ name: templateOption.name,
38
+ message: templateOption.description,
39
+ validate: templateValidate ? (prev) => templateValidate(prev) : undefined,
40
+ initial:
41
+ typeof templateOption.initial === 'function'
42
+ ? templateOption.initial(templateOptions)
43
+ : templateOption.initial,
44
+ },
45
+ {onCancel: () => process.exit(0)}
46
+ )
47
+
48
+ templateOptions[templateOption.name] = templateOption.parse
49
+ ? templateOption.parse(res[templateOption.name])
50
+ : res[templateOption.name]
51
+ }
52
+
53
+ const features: Record<string, boolean> = {}
54
+
55
+ for (const templateFeature of template.features) {
56
+ const res = templateFeature.optional
57
+ ? await prompts(
58
+ {
59
+ type: 'confirm',
60
+ name: 'confirm',
61
+ message: `use ${templateFeature.name}?`,
62
+ initial: templateFeature.initial,
63
+ },
64
+ {onCancel: () => process.exit(0)}
65
+ )
66
+ : undefined
67
+
68
+ features[templateFeature.name] = res?.confirm || !templateFeature.optional
69
+ }
70
+
71
+ const files = await template.getFiles(templateOptions, features)
72
+
73
+ files.sort((a, b) => {
74
+ return a.name.localeCompare(b.name)
75
+ })
76
+
77
+ for (const file of files) {
78
+ const filePath = resolve(packagePath, file.name)
79
+
80
+ await mkdirp(dirname(filePath))
81
+ await writeFile(filePath, file.contents.trim() + '\n')
82
+
83
+ logger.success(`wrote ${relative(cwd, filePath)}`)
84
+ }
85
+ }
@@ -0,0 +1,6 @@
1
+ import {PkgTemplateOption} from './types'
2
+
3
+ /** @public */
4
+ export function defineTemplateOption<T>(option: PkgTemplateOption<T>): PkgTemplateOption<T> {
5
+ return option
6
+ }
@@ -0,0 +1,3 @@
1
+ export * from './createFromTemplate'
2
+ export * from './define'
3
+ export * from './types'
@@ -0,0 +1,45 @@
1
+ import {Logger} from '../../logger'
2
+
3
+ /** @public */
4
+ export interface PkgTemplateFile {
5
+ name: string
6
+ contents: string
7
+ }
8
+
9
+ /** @public */
10
+ export interface PkgTemplateStringOption<T = string> {
11
+ name: string
12
+ type: 'string'
13
+ description: string
14
+ initial?: T | ((options: Record<string, any>) => T)
15
+ parse?: (v: string) => T | null
16
+ validate?: (v: string) => string | true
17
+ }
18
+
19
+ /** @public */
20
+ export type PkgTemplateOption<T = string> = PkgTemplateStringOption<T>
21
+
22
+ /** @public */
23
+ export interface PkgTemplateDefinition {
24
+ options: PkgTemplateStringOption<any>[]
25
+ features: {
26
+ name: string
27
+ optional: boolean
28
+ initial: boolean
29
+ }[]
30
+ getFiles: (
31
+ options: Record<string, any>,
32
+ features: Record<string, boolean>
33
+ ) => Promise<PkgTemplateFile[]>
34
+ }
35
+
36
+ /** @public */
37
+ export type PkgTemplateResolver = (options: {
38
+ cwd: string
39
+ /** @internal */
40
+ logger: Logger
41
+ packagePath: string
42
+ }) => PkgTemplateDefinition | Promise<PkgTemplateDefinition>
43
+
44
+ /** @public */
45
+ export type PkgTemplate = PkgTemplateDefinition | PkgTemplateResolver
@@ -0,0 +1,12 @@
1
+ import {statSync} from 'fs'
2
+
3
+ /** @internal */
4
+ export function fileExists(filePath: string): boolean {
5
+ try {
6
+ statSync(filePath)
7
+
8
+ return true
9
+ } catch (_) {
10
+ return false
11
+ }
12
+ }
@@ -1,5 +1,5 @@
1
- import path from 'path'
2
1
  import globby from 'globby'
2
+ import path from 'path'
3
3
 
4
4
  export function globFiles(patterns: string[]): Promise<string[]> {
5
5
  return globby(patterns.map((pattern) => pattern.split(path.sep).join(path.posix.sep)))
package/src/node/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export * from './build'
2
2
  export * from './check'
3
3
  export * from './core'
4
+ export * from './init'
4
5
  export * from './logger'
5
6
  export * from './resolveBuildTasks'
6
7
  export * from './tasks'