@sanity/pkg-utils 1.0.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 (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/bin/pkg-utils +2 -0
  4. package/dist/_build-3336bcb3.cjs +5432 -0
  5. package/dist/_build-3336bcb3.cjs.map +1 -0
  6. package/dist/cli.cjs +42 -0
  7. package/dist/cli.cjs.map +1 -0
  8. package/dist/index.cjs +37 -0
  9. package/dist/index.cjs.map +1 -0
  10. package/dist/index.d.ts +136 -0
  11. package/dist/index.js +5412 -0
  12. package/dist/index.js.map +1 -0
  13. package/package.json +107 -0
  14. package/src/build/_parseTasks.ts +85 -0
  15. package/src/build/_types.ts +25 -0
  16. package/src/build/build.ts +87 -0
  17. package/src/build/index.ts +2 -0
  18. package/src/build/tasks/_types.ts +8 -0
  19. package/src/build/tasks/dts/_buildTypes.ts +62 -0
  20. package/src/build/tasks/dts/_createApiExtractorConfig.ts +88 -0
  21. package/src/build/tasks/dts/_createTSDocConfig.ts +57 -0
  22. package/src/build/tasks/dts/_extractTypes.ts +101 -0
  23. package/src/build/tasks/dts/_loadTSConfig.ts +18 -0
  24. package/src/build/tasks/dts/dts.ts +60 -0
  25. package/src/build/tasks/dts/index.ts +1 -0
  26. package/src/build/tasks/extract/_extractTask.ts +49 -0
  27. package/src/build/tasks/extract/index.ts +1 -0
  28. package/src/build/tasks/index.ts +4 -0
  29. package/src/build/tasks/rollup/_resolveRollupConfig.ts +95 -0
  30. package/src/build/tasks/rollup/index.ts +1 -0
  31. package/src/build/tasks/rollup/rollup.ts +96 -0
  32. package/src/cli.ts +25 -0
  33. package/src/core/_isRecord.ts +6 -0
  34. package/src/core/config/_loadConfig.ts +30 -0
  35. package/src/core/config/_resolveConfigProperty.ts +12 -0
  36. package/src/core/config/defineConfig.ts +8 -0
  37. package/src/core/config/index.ts +4 -0
  38. package/src/core/config/types.ts +48 -0
  39. package/src/core/index.ts +3 -0
  40. package/src/core/pkg/_loadPkg.ts +13 -0
  41. package/src/core/pkg/_parseExports.ts +41 -0
  42. package/src/core/pkg/_types.ts +18 -0
  43. package/src/core/pkg/index.ts +3 -0
  44. package/src/index.ts +2 -0
@@ -0,0 +1,60 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import path from 'path'
4
+ import {promisify} from 'util'
5
+ import chalk from 'chalk'
6
+ import rimrafCallback from 'rimraf'
7
+ import {_BuildContext} from '../../_types'
8
+ import {_buildTypes} from './_buildTypes'
9
+ import {_extractTypes} from './_extractTypes'
10
+
11
+ const rimraf = promisify(rimrafCallback)
12
+
13
+ /**
14
+ * @internal
15
+ */
16
+ export interface _DtsTask {
17
+ type: 'dts'
18
+ exportId: string
19
+ exportPath: string
20
+ source: string
21
+ output: string
22
+ }
23
+
24
+ /**
25
+ * @internal
26
+ */
27
+ export async function _dtsTask(ctx: _BuildContext, task: _DtsTask): Promise<void> {
28
+ const {cwd, dist, files, tsconfig} = ctx
29
+ const exportPath = task.exportPath === '.' ? './index' : task.exportPath
30
+
31
+ console.log('=================================================================================')
32
+ console.log(chalk.gray('task '), 'd.ts')
33
+ console.log(chalk.gray('source '), path.join('', task.source))
34
+ console.log(chalk.gray('export '), path.join(dist, `${exportPath}.d.ts`))
35
+
36
+ const distPath = path.resolve(cwd, dist)
37
+ const tmpPath = path.resolve(cwd, dist, 'tmp')
38
+
39
+ const tsconfigPath = path.resolve(cwd, tsconfig || 'tsconfig.json')
40
+
41
+ const types = await _buildTypes({
42
+ cwd,
43
+ outDir: tmpPath,
44
+ sourcePath: task.source,
45
+ tsconfigPath,
46
+ })
47
+
48
+ await _extractTypes({
49
+ cwd,
50
+ exportPath,
51
+ files,
52
+ projectPath: cwd,
53
+ sourcePath: types.path,
54
+ tsconfigPath,
55
+ distPath,
56
+ })
57
+
58
+ // Delete tmp directory
59
+ await rimraf(tmpPath)
60
+ }
@@ -0,0 +1 @@
1
+ export * from './dts'
@@ -0,0 +1,49 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import fs from 'fs/promises'
4
+ import path from 'path'
5
+ import {extract, transform} from '@sanity/tsdoc-to-portable-text'
6
+ import chalk from 'chalk'
7
+ import mkdirp from 'mkdirp'
8
+ import {_BuildContext} from '../../_types'
9
+
10
+ /**
11
+ * @internal
12
+ */
13
+ export interface _ExtractTask {
14
+ type: 'extract'
15
+ mainEntryPointPath: string
16
+ }
17
+
18
+ export async function _extractTask(ctx: _BuildContext, task: _ExtractTask): Promise<void> {
19
+ const {mainEntryPointPath} = task
20
+
21
+ console.log('=================================================================================')
22
+ console.log(chalk.gray('task '), 'extract')
23
+ console.log(
24
+ chalk.gray('source '),
25
+ path.relative(ctx.cwd, path.resolve(ctx.cwd, mainEntryPointPath))
26
+ )
27
+
28
+ const extracted = await extract(ctx.cwd, {
29
+ tsconfigPath: path.resolve(ctx.cwd, ctx.tsconfig || 'tsconfig.json'),
30
+ })
31
+
32
+ const transformed = transform(extracted, {
33
+ package: {
34
+ version: ctx.pkg.version,
35
+ },
36
+ })
37
+
38
+ const apiJsonDirPath = path.resolve(ctx.cwd, 'etc/api', ctx.pkg.name)
39
+
40
+ await mkdirp(apiJsonDirPath)
41
+
42
+ const jsonPath = path.resolve(apiJsonDirPath, `${ctx.pkg.version}.json`)
43
+
44
+ if (transformed.length) {
45
+ await fs.writeFile(jsonPath, JSON.stringify(transformed, null, 2) + '\n')
46
+
47
+ console.log(chalk.gray('result '), path.relative(ctx.cwd, jsonPath))
48
+ }
49
+ }
@@ -0,0 +1 @@
1
+ export * from './_extractTask'
@@ -0,0 +1,4 @@
1
+ export * from './_types'
2
+ export * from './dts'
3
+ export * from './extract'
4
+ export * from './rollup'
@@ -0,0 +1,95 @@
1
+ import commonjs from '@rollup/plugin-commonjs'
2
+ import json from '@rollup/plugin-json'
3
+ import {nodeResolve} from '@rollup/plugin-node-resolve'
4
+ import {InputOptions, OutputOptions} from 'rollup'
5
+ import esbuild from 'rollup-plugin-esbuild'
6
+ import {_BuildContext} from '../../_types'
7
+ import {_RollupTask} from './rollup'
8
+
9
+ /**
10
+ * @internal
11
+ */
12
+ export function _resolveRollupConfig(
13
+ ctx: _BuildContext,
14
+ buildTask: _RollupTask
15
+ ): {
16
+ inputOptions: InputOptions
17
+ outputOptions: OutputOptions
18
+ } {
19
+ const {format, runtime, target} = buildTask
20
+ const {cwd, external, dist: outDir, pkg, tsconfig} = ctx
21
+ const outputExt = format === 'commonjs' ? '.cjs' : pkg.type === 'module' ? '.mjs' : '.js'
22
+
23
+ return {
24
+ inputOptions: {
25
+ context: cwd,
26
+
27
+ external,
28
+
29
+ input: buildTask.entries.reduce<{[entryAlias: string]: string}>((acc, entry) => {
30
+ const key = entry.path === '.' ? 'index' : entry.path.slice(2)
31
+
32
+ return {...acc, [key]: entry.source || ''}
33
+ }, {}),
34
+
35
+ plugins: [
36
+ nodeResolve({
37
+ mainFields: ['module', 'jsnext', 'main'],
38
+ browser: runtime !== 'node',
39
+ exportConditions: [runtime === 'node' ? 'node' : 'browser'],
40
+ extensions: ['.cjs', '.mjs', '.js', '.jsx', '.json', '.node'],
41
+ preferBuiltins: runtime === 'node',
42
+ }),
43
+ commonjs({
44
+ esmExternals: false,
45
+ include: /\/node_modules\//,
46
+ // requireReturnsDefault: 'namespace',
47
+ }),
48
+ json(),
49
+ esbuild({
50
+ // include: /\.[jt]sx?$/, // default, inferred from `loaders` option
51
+ // exclude: /node_modules/, // default
52
+ // sourceMap: false, // by default inferred from rollup's `output.sourcemap` option
53
+ minify: false, // process.env.NODE_ENV === 'production',
54
+ // target: 'es2017', // default, or 'es20XX', 'esnext'
55
+ jsx: 'transform', // default, or 'preserve'
56
+ jsxFactory: 'React.createElement',
57
+ jsxFragment: 'React.Fragment',
58
+ // // Like @rollup/plugin-replace
59
+ // define: {
60
+ // __VERSION__: '"x.y.z"',
61
+ // },
62
+ // plugins: [],
63
+ target,
64
+ // target:
65
+ // target === 'node'
66
+ // ? ['node12']
67
+ // : ['es2020', 'chrome104', 'edge104', 'firefox103', 'safari15'],
68
+ tsconfig: tsconfig || 'tsconfig.json', // 'tsconfig.json', // default
69
+ // Add extra loaders
70
+ loaders: {
71
+ // Add .json files support
72
+ // require @rollup/plugin-commonjs
73
+ '.json': 'json',
74
+ // Enable JSX in .js files too
75
+ // '.js': 'jsx',
76
+ },
77
+ }),
78
+ ],
79
+
80
+ treeshake: {
81
+ propertyReadSideEffects: false,
82
+ },
83
+ },
84
+ outputOptions: {
85
+ chunkFileNames: () => `_[name]-[hash]${outputExt}`,
86
+ dir: outDir,
87
+ entryFileNames: () => `[name]${outputExt}`,
88
+ format,
89
+ esModule: false,
90
+ exports: 'auto',
91
+ freeze: false,
92
+ sourcemap: true,
93
+ },
94
+ }
95
+ }
@@ -0,0 +1 @@
1
+ export * from './rollup'
@@ -0,0 +1,96 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import path from 'path'
4
+ import chalk from 'chalk'
5
+ import {rollup} from 'rollup'
6
+ import {PackageSubPathExportEntry} from '../../../core'
7
+ import {_BuildContext} from '../../_types'
8
+ import {_resolveRollupConfig} from './_resolveRollupConfig'
9
+
10
+ /**
11
+ * @internal
12
+ */
13
+ export interface _RollupTask {
14
+ type: 'rollup'
15
+ buildId: string
16
+ entries: (PackageSubPathExportEntry & {path: string})[]
17
+ runtime: 'node' | 'web'
18
+ format: 'commonjs' | 'esm'
19
+ target: string[]
20
+ }
21
+
22
+ export async function _rollupTask(ctx: _BuildContext, buildTask: _RollupTask): Promise<void> {
23
+ console.log('=================================================================================')
24
+
25
+ console.log(chalk.gray('task '), 'rollup')
26
+ console.log(chalk.gray('target '), buildTask.target.join(', '))
27
+ console.log(chalk.gray('format '), buildTask.format)
28
+
29
+ const {cwd, files, dist: outDir, pkg} = ctx
30
+
31
+ const {inputOptions, outputOptions} = _resolveRollupConfig(ctx, buildTask)
32
+
33
+ // Create bundle
34
+ const bundle = await rollup(inputOptions)
35
+
36
+ // an array of file names this bundle depends on
37
+ // console.log(bundle.watchFiles)
38
+
39
+ // generate output specific code in-memory
40
+ // you can call this function multiple times on the same bundle object
41
+ const {output} = await bundle.generate(outputOptions)
42
+
43
+ for (const chunkOrAsset of output) {
44
+ if (chunkOrAsset.type === 'asset') {
45
+ files.push({
46
+ type: 'asset',
47
+ path: path.resolve(outDir, chunkOrAsset.fileName),
48
+ })
49
+ } else {
50
+ files.push({
51
+ type: 'chunk',
52
+ path: path.resolve(outDir, chunkOrAsset.fileName),
53
+ })
54
+ }
55
+ }
56
+
57
+ // or write the bundle to disk
58
+ await bundle.write(outputOptions)
59
+
60
+ // closes the bundle
61
+ await bundle.close()
62
+
63
+ for (const entry of buildTask.entries) {
64
+ console.log(`- ${path.join(pkg.name, entry.path)}`)
65
+
66
+ console.log(chalk.gray(' source '), path.relative(cwd, path.resolve(cwd, entry.source)))
67
+
68
+ const defaultFile = files.find(
69
+ (f) => entry.default && f.path === path.resolve(cwd, entry.default)
70
+ )
71
+
72
+ const requireFile = files.find(
73
+ (f) => entry.require && f.path === path.resolve(cwd, entry.require)
74
+ )
75
+
76
+ const typesFile = files.find((f) => entry.types && f.path === path.resolve(cwd, entry.types))
77
+
78
+ if (buildTask.format.includes('esm'))
79
+ console.log(
80
+ chalk.gray(' default '),
81
+ defaultFile ? path.relative(cwd, defaultFile.path) : undefined
82
+ )
83
+
84
+ if (buildTask.format.includes('commonjs'))
85
+ console.log(
86
+ chalk.gray(' require '),
87
+ requireFile ? path.relative(cwd, requireFile.path) : undefined
88
+ )
89
+
90
+ if (entry.types)
91
+ console.log(
92
+ chalk.gray(' types '),
93
+ typesFile ? path.relative(cwd, typesFile.path) : undefined
94
+ )
95
+ }
96
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,25 @@
1
+ import cac from 'cac'
2
+ import {build} from './build'
3
+
4
+ const cli = cac()
5
+
6
+ cli
7
+ .command('build', 'Build package')
8
+ .option('--extract', 'Extract API reference')
9
+ .option('--tsconfig [tsconfig]', '[string] tsconfig.json')
10
+ .action(async (options) => {
11
+ await build({
12
+ cwd: process.cwd(),
13
+ extract: options.extract ? Boolean(options.extract) : undefined,
14
+ tsconfig: options.tsconfig,
15
+ })
16
+ })
17
+
18
+ // Display help message when `-h` or `--help` appears
19
+ cli.help()
20
+
21
+ // Display version number when `-v` or `--version` appears
22
+ // It's also used in help message
23
+ cli.version('0.0.0')
24
+
25
+ cli.parse()
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @internal
3
+ */
4
+ export function _isRecord(value: unknown): value is Record<string, unknown> {
5
+ return Boolean(value) && !Array.isArray(value) && typeof value === 'object'
6
+ }
@@ -0,0 +1,30 @@
1
+ import path from 'path'
2
+ import {register} from 'esbuild-register/dist/node'
3
+ import pkgUp from 'pkg-up'
4
+ import {PkgConfigOptions} from './types'
5
+
6
+ /**
7
+ * @internal
8
+ */
9
+ export async function _loadConfig(options: {cwd: string}): Promise<PkgConfigOptions | undefined> {
10
+ const {cwd} = options
11
+
12
+ const pkgPath = await pkgUp({cwd})
13
+
14
+ if (!pkgPath) return undefined
15
+
16
+ const root = path.dirname(pkgPath)
17
+
18
+ try {
19
+ const {unregister} = register({extensions: ['.js', '.ts']})
20
+
21
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
22
+ const mod = require(path.resolve(root, 'package.config.ts'))
23
+
24
+ unregister()
25
+
26
+ return mod.default
27
+ } catch (_) {
28
+ return undefined
29
+ }
30
+ }
@@ -0,0 +1,12 @@
1
+ import {ConfigProperty, ConfigPropertyResolver} from './types'
2
+
3
+ /**
4
+ * @internal
5
+ */
6
+ export function _resolveConfigProperty<T>(prop: ConfigProperty<T>, initialValue: T): T {
7
+ if (typeof prop === 'function') {
8
+ return (prop as ConfigPropertyResolver<T>)(initialValue)
9
+ }
10
+
11
+ return prop
12
+ }
@@ -0,0 +1,8 @@
1
+ import {PkgConfigOptions} from './types'
2
+
3
+ /**
4
+ * @public
5
+ */
6
+ export function defineConfig(configOptions: PkgConfigOptions): PkgConfigOptions {
7
+ return configOptions
8
+ }
@@ -0,0 +1,4 @@
1
+ export * from './_loadConfig'
2
+ export * from './_resolveConfigProperty'
3
+ export * from './defineConfig'
4
+ export * from './types'
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @public
3
+ */
4
+ export interface PackageSubPathExportEntry {
5
+ runtime: 'node' | 'web'
6
+
7
+ // paths
8
+ source: string
9
+ require?: string
10
+ default?: string
11
+ types?: string
12
+ }
13
+
14
+ /**
15
+ * @public
16
+ */
17
+ export type ConfigPropertyResolver<T> = (prev: T) => T
18
+
19
+ /**
20
+ * @public
21
+ */
22
+ export type ConfigProperty<T> = ConfigPropertyResolver<T> | T
23
+
24
+ /**
25
+ * @public
26
+ */
27
+ export interface PackageExports {
28
+ [path: string]: PackageSubPathExportEntry
29
+ }
30
+
31
+ /**
32
+ * @public
33
+ */
34
+ export interface PkgConfigOptions {
35
+ /**
36
+ * Directory of distributed & bundled files.
37
+ */
38
+ dist?: string
39
+ exports?: ConfigProperty<PackageExports>
40
+ /**
41
+ * Packages to exclude from the bundles.
42
+ */
43
+ external?: ConfigProperty<string[]>
44
+ /**
45
+ * Directory of source files.
46
+ */
47
+ src?: string
48
+ }
@@ -0,0 +1,3 @@
1
+ export * from './_isRecord'
2
+ export * from './config'
3
+ export * from './pkg'
@@ -0,0 +1,13 @@
1
+ import pkgUp from 'pkg-up'
2
+ import {_PackageJSON} from './_types'
3
+
4
+ /**
5
+ * @internal
6
+ */
7
+ export async function _loadPkg(options: {cwd: string}): Promise<_PackageJSON> {
8
+ const {cwd} = options
9
+
10
+ const pkgPath = await pkgUp({cwd})
11
+
12
+ return pkgPath ? require(pkgPath) : undefined
13
+ }
@@ -0,0 +1,41 @@
1
+ import {_isRecord} from '../_isRecord'
2
+ import {PackageSubPathExportEntry} from '../config'
3
+ import {_PackageJSON} from './_types'
4
+
5
+ /**
6
+ * @internal
7
+ */
8
+ export function _parseExports(pkg: _PackageJSON): (PackageSubPathExportEntry & {path: string})[] {
9
+ const rootExport: PackageSubPathExportEntry & {path: string} = {
10
+ path: '.',
11
+ runtime: 'web',
12
+
13
+ source: pkg.source || 'index.js',
14
+ require: pkg.main,
15
+ default: pkg.module,
16
+ types: pkg.types,
17
+ }
18
+
19
+ const extraExports: (PackageSubPathExportEntry & {path: string})[] = []
20
+
21
+ if (pkg.exports) {
22
+ for (const [exportPath, exportEntry] of Object.entries(pkg.exports)) {
23
+ if (_isRecord(exportEntry)) {
24
+ if (exportPath === '.') {
25
+ Object.assign(rootExport, exportEntry)
26
+ } else {
27
+ extraExports.push({
28
+ path: exportPath,
29
+ runtime: 'web',
30
+ source: exportEntry.source,
31
+ ...exportEntry,
32
+ })
33
+ }
34
+ } else {
35
+ throw new Error('string entries are not supported')
36
+ }
37
+ }
38
+ }
39
+
40
+ return [rootExport, ...extraExports]
41
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @internal
3
+ */
4
+ export interface _PackageJSON {
5
+ type?: 'module'
6
+ version: string
7
+ private?: boolean
8
+ name: string
9
+ bin?: Record<string, string>
10
+ dependencies?: Record<string, string>
11
+ devDependencies?: Record<string, string>
12
+ peerDependencies?: Record<string, string>
13
+ exports?: Record<string, string | Record<string, string>>
14
+ main?: string
15
+ source?: string
16
+ module?: string
17
+ types?: string
18
+ }
@@ -0,0 +1,3 @@
1
+ export * from './_loadPkg'
2
+ export * from './_parseExports'
3
+ export * from './_types'
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './build'
2
+ export * from './core'