Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for package bin field #16

Merged
merged 4 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

# build-tools

`@fp-tx/build-tools` is a thin wrapper around `tsup` for the purpose of building dual ESM/CJS packages. It contains a chief export `makeConfig` which will read from a configurable source directory and determine which files to include as entrypoints. Using these entrypoints, it also adds a dynamic "exports" field with `import` and `default` fields based on the determined entrypoints and module type (determined by `package.json > type`).
`@fp-tx/build-tools` is a thin wrapper around `tsup` for the purpose of building dual ESM/CJS packages. It contains a chief export `makeConfig` which will read from a configurable source directory and determine which files to include as entrypoints. Using these entrypoints, it also adds a dynamic "exports" field with `import` and `default` fields based on the determined entrypoints and module type (determined by `package.json > type`). Additionally it adds the appropriate `main`, `module`, `types`, and `bin` (if applicable) to the emitted package.json.

Additionally, `build-tools` will emit smart declaration files with rewritten import, export, and `declare module` paths.

Expand All @@ -24,7 +24,7 @@ const config = makeConfig(
buildType: 'dual',
buildMode: {
type: 'Single',
entrypoint: 'index.ts',
entrypoint: './src/index.ts',
},
iife: false,

Expand Down Expand Up @@ -71,15 +71,17 @@ npm install -D tsup @fp-tx/build-tools

## Configuration Parameters

| Parameter | Type | Description | Default |
| ------------------ | ----------------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------- |
| iife | `boolean` | Include IIFE generation as fallback. This setting is recommended for single-target builds | `false` |
| emitTypes | `boolean` | Generate `.d.ts`, and `.d.cts` or `.d.mts` files | `true` |
| dtsConfig | `string` | The `tsconfig.json` for types generation | `tsconfig.json` |
| srcDir | `string` | The source directory to read from | `'src'` |
| basePath | `string` | The current working directory | `'.'` |
| buildMode | `BuildMode` | Determines the package entrypoints, "Single" and `entrypoint` or "Multi" and `entrypointGlobs` | `{ type: "Single", entrypoint: "index.ts" }` |
| buildType | `cjs`, `esm`, or `dual` | Determines the output module format along with `package.json > type` | `dual` |
| omittedPackageKeys | `ReadonlyArray<string>` | Array of keys to omit from the package.json file | `["devDependencies", "scripts"]` |
| copyFiles | `ReadonlyArray<string>` | Whether to copy non-typescript files | `['README.md', 'LICENSE']` |
| outDir | `string` | The output directory | `dist` |
| Parameter | Type | Description | Default |
| -------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| iife | `boolean` | Include IIFE generation as fallback. This setting is recommended for single-target builds | `false` |
| emitTypes | `boolean` | Generate `.d.ts`, and `.d.cts` or `.d.mts` files | `true` |
| dtsConfig | `string` | The `tsconfig.json` for types generation | `tsconfig.json` |
| srcDir | `string` | The source directory to read from | `'src'` |
| basePath | `string` | The current working directory | `'.'` |
| buildMode | `BuildMode` | Determines the package entrypoints, "Single" and `entrypoint` or "Multi" and `entrypointGlobs` | `{ type: "Single", entrypoint: "index.ts" }` |
| buildType | `cjs`, `esm`, or `dual` | Determines the output module format along with `package.json > type` | `dual` |
| omittedPackageKeys | `ReadonlyArray<string>` | Array of keys to omit from the package.json file | `["devDependencies", "scripts"]` |
| copyFiles | `ReadonlyArray<string>` | Whether to copy non-typescript files | `['README.md', 'LICENSE']` |
| outDir | `string` | The output directory | `dist` |
| dtsCompilerOverrides | `Partial<CompilerOptions>` | Overrides to override build-tools imposed tsconfig defaults. **Only use this option if you know what you are doing** | `{}` |
| bin | `string` or `Record<string, string>` | `ts` file entrypoints to fill the emitted package `bin` field | `null` |
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"husky": "^8.0.3",
"jest": "^29.7.0",
"lint-staged": "^15.1.0",
"prettier": "~3.1.0",
"prettier": "~3.1.1",
"prettier-plugin-jsdoc": "^1.1.1",
"tsc-files": "^1.1.4",
"tsup": "^8.0.0",
Expand Down Expand Up @@ -88,5 +88,10 @@
"eslint --fix-type layout --fix --cache",
"pnpm run prerelease"
]
},
"pnpm": {
"patchedDependencies": {
"lru-cache@10.4.3": "patches/lru-cache@10.4.3.patch"
}
}
}
13 changes: 13 additions & 0 deletions patches/lru-cache@10.4.3.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/dist/commonjs/index.d.ts b/dist/commonjs/index.d.ts
index f59de7602a528afde714e56dcf8c25ee496e39fb..804042b5ff381b8594307296de29d31d1b564c92 100644
--- a/dist/commonjs/index.d.ts
+++ b/dist/commonjs/index.d.ts
@@ -837,7 +837,7 @@ export declare namespace LRUCache {
*
* Changing any of these will alter the defaults for subsequent method calls.
*/
-export declare class LRUCache<K extends {}, V extends {}, FC = unknown> implements Map<K, V> {
+export declare class LRUCache<K extends {}, V extends {}, FC = unknown> {
#private;
/**
* {@link LRUCache.OptionsBase.ttl}
11 changes: 8 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 36 additions & 1 deletion src/BuildService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,35 @@ export const BuildServiceLive: RTE.ReaderTaskEither<
),
),
),
// Validate Bin Field
RTE.tapEither(({ config, entrypoints }) =>
pipe(
config.bin,
E.fromPredicate(
binField => {
if (binField === null) {
return true
} else if (typeof binField === 'string') {
return entrypoints.includes(normalizePath(binField))
} else {
return pipe(
binField,
RR.every(file => entrypoints.includes(normalizePath(file))),
)
}
},
binField =>
new BuildServiceError(
`The \`bin\` field (${JSON.stringify(
binField,
)}) files must be listed as entrypoints in \`buildMode\`. Received entrypoints: [${entrypoints.join(
',',
)}]`,
null,
),
),
),
),
RTE.let('resolvedIndex', ({ config, entrypoints }) =>
config.buildMode.type === 'Single'
? config.buildMode.entrypoint
Expand Down Expand Up @@ -160,6 +189,7 @@ export const BuildServiceLive: RTE.ReaderTaskEither<
module: __,
exports: ___,
types: ____,
bin: preBin,
...rest
},
}) =>
Expand All @@ -170,7 +200,7 @@ export const BuildServiceLive: RTE.ReaderTaskEither<
),
RTE.flatMapTaskEither(Exports.pkgExports),
RTE.map(
([exports, main, module, types]): RR.ReadonlyRecord<string, unknown> => ({
([exports, main, module, types, bin]): RR.ReadonlyRecord<string, unknown> => ({
name,
version,
description,
Expand All @@ -181,6 +211,7 @@ export const BuildServiceLive: RTE.ReaderTaskEither<
module,
types,
exports,
bin: bin ?? preBin,
...pipe(
rest,
RR.filterWithIndex(key => !config.omittedPackageKeys.includes(key)),
Expand Down Expand Up @@ -394,6 +425,10 @@ export const BuildServiceLive: RTE.ReaderTaskEither<

const rootDirRegex = /^\.\/(.*).(m|c)?ts/

function normalizePath(p: string): string {
return path.join(path.dirname(p), path.basename(p))
}

export const configuration: R.Reader<
BuildService,
BuildServiceMethods['configuration']
Expand Down
12 changes: 12 additions & 0 deletions src/ConfigService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ export type ConfigParameters = {
* @default { }
*/
readonly dtsCompilerOverrides?: Partial<CompilerOptions>

/**
* Allows you to specify the package-command entrypoints as TypeScript files that will
* be re-pointed to their emitted javascript files.
*
* @remarks
* **Any binary file specified in this key or record must be an entrypoint, an error
* will be raised if that file is excluded from the entrypoint globs**
*/
readonly bin?: string | Record<string, string> | null
}

export class ConfigService {
Expand All @@ -136,6 +146,7 @@ export class ConfigService {
emitTypes = true,
dtsConfig = 'tsconfig.json',
dtsCompilerOverrides = {},
bin = null,
}: ConfigParameters) {
this[ConfigServiceSymbol] = {
buildType,
Expand All @@ -149,6 +160,7 @@ export class ConfigService {
buildMode,
emitTypes,
dtsCompilerOverrides,
bin,
}
}
}
Expand Down
Loading
Loading