jiek 2.0.2-alpha.1 → 2.0.2-alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/README.md +78 -0
  2. package/bin/jiek-build.js +16 -0
  3. package/bin/jiek.js +13 -0
  4. package/dist/cli-only-build.cjs +701 -0
  5. package/dist/cli-only-build.d.cts +91 -0
  6. package/dist/cli-only-build.d.ts +91 -0
  7. package/dist/cli-only-build.js +693 -0
  8. package/dist/cli.cjs +4638 -0
  9. package/dist/cli.d.cts +14 -0
  10. package/dist/cli.d.ts +14 -0
  11. package/dist/cli.js +4608 -0
  12. package/dist/index.cjs +5 -0
  13. package/dist/index.d.cts +112 -0
  14. package/dist/index.d.ts +112 -0
  15. package/dist/index.js +3 -0
  16. package/dist/package.json +125 -0
  17. package/dist/rollup/index.cjs +4893 -0
  18. package/dist/rollup/index.d.cts +10 -0
  19. package/dist/rollup/index.d.ts +10 -0
  20. package/dist/rollup/index.js +4880 -0
  21. package/package.json +7 -39
  22. package/src/cli-only-build.ts +7 -0
  23. package/src/cli.ts +2 -0
  24. package/src/commands/base.ts +18 -0
  25. package/src/commands/build.ts +459 -0
  26. package/src/commands/descriptions.ts +17 -0
  27. package/src/commands/meta.ts +5 -0
  28. package/src/commands/publish.ts +242 -0
  29. package/src/index.ts +8 -0
  30. package/src/inner.ts +11 -0
  31. package/src/rollup/base.ts +137 -0
  32. package/src/rollup/index.ts +565 -0
  33. package/src/rollup/plugins/progress.ts +26 -0
  34. package/src/rollup/plugins/skip.ts +21 -0
  35. package/src/rollup/utils/commonOptions.ts +9 -0
  36. package/src/rollup/utils/externalResolver.ts +35 -0
  37. package/src/rollup/utils/globalResolver.ts +13 -0
  38. package/src/rollup/utils/withMinify.ts +18 -0
  39. package/src/utils/filterSupport.ts +91 -0
  40. package/src/utils/getExports.ts +140 -0
  41. package/src/utils/getRoot.ts +16 -0
  42. package/src/utils/getWD.ts +31 -0
  43. package/src/utils/loadConfig.ts +111 -0
  44. package/src/utils/recusiveListFiles.ts +13 -0
  45. package/src/utils/ts.ts +94 -0
  46. package/src/utils/tsRegister.ts +26 -0
@@ -0,0 +1,242 @@
1
+ import * as childProcess from 'node:child_process'
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+
5
+ import { bump, type BumperType, TAGS } from '@jiek/utils/bumper'
6
+ import { program } from 'commander'
7
+ import detectIndent from 'detect-indent'
8
+ import { applyEdits, modify } from 'jsonc-parser'
9
+
10
+ import { actionDone, actionRestore } from '../inner'
11
+ import { getSelectedProjectsGraph } from '../utils/filterSupport'
12
+ import { getExports } from '../utils/getExports'
13
+ import { loadConfig } from '../utils/loadConfig'
14
+ import { outdirDescription } from './descriptions'
15
+
16
+ declare module 'jiek' {
17
+ export interface Config {
18
+ publish?: {
19
+ /**
20
+ * @default false
21
+ */
22
+ withSuffix?: boolean
23
+ /**
24
+ * @default true
25
+ */
26
+ withSource?: boolean
27
+ }
28
+ }
29
+ }
30
+
31
+ const description = `
32
+ Publish package to npm registry, and auto generate exports field and other fields in published package.json.
33
+ If you want to through the options to the \`pnpm publish\` command, you can pass the options after '--'.
34
+ `.trim()
35
+
36
+ program
37
+ .command('publish')
38
+ .description(description)
39
+ .aliases(['pub', 'p'])
40
+ .option('-b, --bumper <bumper>', 'bump version', 'patch')
41
+ .option('-no-b, --no-bumper', 'no bump version')
42
+ .option('-o, --outdir <OUTDIR>', outdirDescription, String, 'dist')
43
+ .option('-s, --silent', 'no output')
44
+ .option('-p, --preview', 'preview publish')
45
+ .action(async ({ outdir, preview, silent, bumper, ...options }: {
46
+ outdir?: string
47
+ preview?: boolean
48
+ silent?: boolean
49
+ bumper: false | BumperType
50
+ }) => {
51
+ let shouldPassThrough = false
52
+
53
+ const passThroughOptions = process.argv
54
+ .reduce(
55
+ (acc, value) => {
56
+ if (shouldPassThrough) {
57
+ acc.push(value)
58
+ }
59
+ if (value === '--') {
60
+ shouldPassThrough = true
61
+ }
62
+ return acc
63
+ },
64
+ [] as string[]
65
+ )
66
+ actionRestore()
67
+
68
+ const { value = {} } = await getSelectedProjectsGraph() ?? {}
69
+ const selectedProjectsGraphEntries = Object.entries(value)
70
+ if (selectedProjectsGraphEntries.length === 0) {
71
+ throw new Error('no packages selected')
72
+ }
73
+ const manifests = selectedProjectsGraphEntries
74
+ .map(([dir, manifest]) => {
75
+ const { name, type, exports: entrypoints = {} } = manifest
76
+ if (!name) {
77
+ throw new Error(`package.json in ${dir} must have a name field`)
78
+ }
79
+
80
+ const pkgIsModule = type === 'module'
81
+ const newManifest = { ...manifest }
82
+ const [resolvedEntrypoints, exports, resolvedOutdir] = getExports({
83
+ entrypoints,
84
+ pkgIsModule,
85
+ pkgName: name,
86
+ config: loadConfig(dir),
87
+ dir,
88
+ defaultOutdir: outdir,
89
+ noFilter: true,
90
+ isPublish: true
91
+ })
92
+ newManifest.exports = {
93
+ ...resolvedEntrypoints,
94
+ ...exports
95
+ }
96
+ return [dir, newManifest, resolvedOutdir] as const
97
+ })
98
+ const passArgs = Object
99
+ .entries(options)
100
+ .reduce((acc, [key, value]) => {
101
+ if (value) {
102
+ acc.push(`--${key}`, value as string)
103
+ }
104
+ return acc
105
+ }, [] as string[])
106
+ for (const [dir, manifest, resolvedOutdir] of manifests) {
107
+ const resolveByDir = (...paths: string[]) => path.resolve(dir, ...paths)
108
+
109
+ const oldJSONString = fs.readFileSync(resolveByDir('package.json'), 'utf-8')
110
+ const oldJSON = JSON.parse(oldJSONString) ?? '0.0.0'
111
+ const newVersion = bumper ? bump(oldJSON.version, bumper) : oldJSON.version
112
+ // TODO detectIndent by editorconfig
113
+ const { indent = ' ' } = detectIndent(oldJSONString)
114
+ const formattingOptions = {
115
+ tabSize: indent.length,
116
+ insertSpaces: true
117
+ }
118
+ let newJSONString = oldJSONString
119
+ newJSONString = applyEdits(
120
+ newJSONString,
121
+ modify(
122
+ newJSONString,
123
+ ['version'],
124
+ newVersion,
125
+ { formattingOptions }
126
+ )
127
+ )
128
+ for (const [key, value] of Object.entries(manifest)) {
129
+ if (JSON.stringify(value) === JSON.stringify(oldJSON[key])) continue
130
+
131
+ if (key !== 'exports') {
132
+ newJSONString = applyEdits(
133
+ newJSONString,
134
+ modify(
135
+ newJSONString,
136
+ ['publishConfig', key],
137
+ value,
138
+ { formattingOptions }
139
+ )
140
+ )
141
+ } else {
142
+ const exports = value as Record<string, unknown>
143
+ for (const [k, v] of Object.entries(exports)) {
144
+ newJSONString = applyEdits(
145
+ newJSONString,
146
+ modify(
147
+ newJSONString,
148
+ ['publishConfig', 'exports', k],
149
+ v,
150
+ { formattingOptions }
151
+ )
152
+ )
153
+ }
154
+ const index = exports?.['.']
155
+ const indexPublishConfig: Record<string, string> = {}
156
+ if (index) {
157
+ switch (typeof index) {
158
+ case 'string':
159
+ indexPublishConfig[
160
+ manifest?.type === 'module' ? 'module' : 'main'
161
+ ] = index
162
+ break
163
+ case 'object': {
164
+ const indexExports = index as Record<string, string>
165
+ indexPublishConfig.main = indexExports['require'] ?? indexExports['default']
166
+ indexPublishConfig.module = indexExports['import'] ?? indexExports['module'] ?? indexExports['default']
167
+ break
168
+ }
169
+ }
170
+ for (const [k, v] of Object.entries(indexPublishConfig)) {
171
+ if (v === undefined) continue
172
+ newJSONString = applyEdits(
173
+ newJSONString,
174
+ modify(
175
+ newJSONString,
176
+ ['publishConfig', k],
177
+ v,
178
+ { formattingOptions }
179
+ )
180
+ )
181
+ }
182
+ }
183
+ }
184
+ }
185
+ newJSONString = applyEdits(
186
+ newJSONString,
187
+ modify(
188
+ newJSONString,
189
+ ['publishConfig', 'typesVersions'],
190
+ {
191
+ '<5.0': {
192
+ '*': [
193
+ '*',
194
+ `${resolvedOutdir}/*`,
195
+ `${resolvedOutdir}/*/index.d.ts`,
196
+ `${resolvedOutdir}/*/index.d.mts`,
197
+ `${resolvedOutdir}/*/index.d.cts`
198
+ ]
199
+ }
200
+ },
201
+ { formattingOptions }
202
+ )
203
+ )
204
+ newJSONString = applyEdits(
205
+ newJSONString,
206
+ modify(newJSONString, ['publishConfig', 'directory'], resolvedOutdir, { formattingOptions })
207
+ )
208
+ !silent && console.log(newJSONString)
209
+ if (preview) {
210
+ continue
211
+ }
212
+ const effects: (() => void)[] = []
213
+ try {
214
+ // fs.renameSync(resolveByDir('package.json'), resolveByDir('package.json.bak'))
215
+
216
+ if (!fs.existsSync(resolveByDir(resolvedOutdir))) {
217
+ fs.mkdirSync(resolveByDir(resolvedOutdir))
218
+ effects.push(() => fs.rmdirSync(resolveByDir(resolvedOutdir), { recursive: true }))
219
+ }
220
+ // fs.writeFileSync(resolveByDir('package.json'), newJSONString)
221
+ fs.writeFileSync(resolveByDir(resolvedOutdir, 'package.json'), newJSONString)
222
+ effects.push(() => fs.unlinkSync(resolveByDir(resolvedOutdir, 'package.json')))
223
+
224
+ const modifyVersionPackageJSON = applyEdits(oldJSONString, modify(oldJSONString, ['version'], newVersion, {}))
225
+ fs.writeFileSync(resolveByDir('package.json'), modifyVersionPackageJSON)
226
+ effects.push(() => fs.writeFileSync(resolveByDir('package.json'), oldJSONString))
227
+
228
+ const args = ['pnpm', 'publish', '--access', 'public', '--no-git-checks', ...passArgs]
229
+ if (bumper && TAGS.includes(bumper)) {
230
+ args.push('--tag', bumper)
231
+ }
232
+ args.push(...passThroughOptions)
233
+ childProcess.execSync(args.join(' '), {
234
+ cwd: dir,
235
+ stdio: 'inherit'
236
+ })
237
+ } finally {
238
+ effects.forEach(effect => effect())
239
+ }
240
+ }
241
+ actionDone()
242
+ })
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type {} from './commands/base'
2
+ import type {} from './commands/build'
3
+ import type {} from './commands/init'
4
+ import type {} from './commands/publish'
5
+
6
+ export interface Config {}
7
+
8
+ export const defineConfig = (config: Config) => config
package/src/inner.ts ADDED
@@ -0,0 +1,11 @@
1
+ let resolve: () => void
2
+
3
+ export let actionFuture: Promise<void>
4
+
5
+ export function actionDone() {
6
+ resolve()
7
+ }
8
+
9
+ export function actionRestore() {
10
+ actionFuture = new Promise<void>(r => resolve = r)
11
+ }
@@ -0,0 +1,137 @@
1
+ import type { InputPluginOption, OutputOptions } from 'rollup'
2
+
3
+ export type Mapping2ROO<K extends keyof OutputOptions> = OutputOptions[K] | {
4
+ js?: OutputOptions[K]
5
+ dts?: OutputOptions[K]
6
+ }
7
+
8
+ export interface ConfigGenerateContext {
9
+ path: string
10
+ name: string
11
+ input: string
12
+ output: string
13
+ external: (string | RegExp)[]
14
+ pkgIsModule: boolean
15
+ conditionals: string[]
16
+ }
17
+
18
+ export type OutputControl = boolean | ((context: ConfigGenerateContext) => boolean)
19
+
20
+ export const BUILDER_TYPES = ['esbuild', 'swc'] as const
21
+
22
+ export const BUILDER_TYPE_PACKAGE_NAME_MAP = {
23
+ esbuild: 'rollup-plugin-esbuild',
24
+ swc: 'rollup-plugin-swc3'
25
+ }
26
+
27
+ export interface TemplateOptions {
28
+ /**
29
+ * When the user configures type: module, the generated output from entry points that don't
30
+ * have cts as a suffix will automatically include the CJS version.
31
+ * if it is not configured, and the generated output from entry points that do not have mts
32
+ * as a suffix will automatically include the ESM version.
33
+ *
34
+ * @default true
35
+ */
36
+ crossModuleConvertor?: boolean
37
+ /**
38
+ * Auto-detect the builder from the installed dependencies.
39
+ * If the builder is not installed, it will prompt the user to install it.
40
+ * If exists multiple builders, it will fall back to the 'esbuild'.
41
+ *
42
+ * @default 'esbuild'
43
+ */
44
+ builder?:
45
+ | typeof BUILDER_TYPES[number]
46
+ | ({
47
+ type: 'esbuild'
48
+ } & import('rollup-plugin-esbuild').Options)
49
+ | ({
50
+ type: 'swc'
51
+ } & import('rollup-plugin-swc3').PluginOptions)
52
+ output?: {
53
+ /**
54
+ * @default true
55
+ *
56
+ * When minify is set to true, the output will with minified files.
57
+ * When minify is set to 'only-minify', the output will direct output minified files.
58
+ */
59
+ minify?: boolean | 'only-minify'
60
+ minifyOptions?:
61
+ | typeof BUILDER_TYPES[number]
62
+ | 'terser'
63
+ | (
64
+ {
65
+ type: 'terser'
66
+ } & import('@rollup/plugin-terser').Options
67
+ )
68
+ | (
69
+ {
70
+ type: 'esbuild'
71
+ } & Parameters<typeof import('rollup-plugin-esbuild').minify>[0]
72
+ )
73
+ | (
74
+ {
75
+ type: 'swc'
76
+ } & Parameters<typeof import('rollup-plugin-swc3').minify>[0]
77
+ )
78
+ /**
79
+ * @default 'dist'
80
+ */
81
+ dir?: Mapping2ROO<'dir'>
82
+ sourcemap?: Mapping2ROO<'sourcemap'>
83
+ strict?: Mapping2ROO<'strict'>
84
+ js?: OutputControl
85
+ dts?: OutputControl
86
+ }
87
+ /**
88
+ * Set the external dependencies of the package.
89
+ */
90
+ external?: (string | RegExp)[]
91
+ plugins?:
92
+ | InputPluginOption
93
+ | ((type: 'js' | 'dts', context: ConfigGenerateContext) => InputPluginOption)
94
+ | {
95
+ js: InputPluginOption
96
+ dts?: InputPluginOption
97
+ }
98
+ | {
99
+ js?: InputPluginOption
100
+ dts: InputPluginOption
101
+ }
102
+ }
103
+
104
+ export type RollupProgressEvent =
105
+ | {
106
+ type: 'init'
107
+ data: {
108
+ leafMap: Map<string, string[][]>
109
+ targetsLength: number
110
+ }
111
+ }
112
+ | {
113
+ type: 'watchChange'
114
+ data: {
115
+ id: string
116
+ name: string
117
+ path: string
118
+ input: string
119
+ }
120
+ }
121
+ | {
122
+ type: 'debug'
123
+ data: unknown
124
+ }
125
+ | {
126
+ type: 'progress'
127
+ data: {
128
+ // name, path, exportConditions, input
129
+ name: string
130
+ path: string
131
+ exportConditions: string[]
132
+ input: string
133
+ tags?: string[]
134
+ event?: string
135
+ message?: string
136
+ }
137
+ }