Skip to content

Commit 97965d2

Browse files
committed
feat(config): a simple-release config loader
1 parent 943c641 commit 97965d2

File tree

7 files changed

+265
-0
lines changed

7 files changed

+265
-0
lines changed

packages/config/.eslintrc.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": [
3+
"@trigen/eslint-config/typescript",
4+
"@trigen/eslint-config/typescript-requiring-type-checking",
5+
"@trigen/eslint-config/jest"
6+
],
7+
"parserOptions": {
8+
"tsconfigRootDir": "./packages/config",
9+
"project": ["./tsconfig.json"]
10+
},
11+
"rules": {
12+
"@typescript-eslint/naming-convention": "off"
13+
}
14+
}

packages/config/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# @simple-release/config
2+
3+
[![ESM-only package][package]][package-url]
4+
[![NPM version][npm]][npm-url]
5+
[![Node version][node]][node-url]
6+
[![Dependencies status][deps]][deps-url]
7+
[![Install size][size]][size-url]
8+
[![Build status][build]][build-url]
9+
[![Coverage status][coverage]][coverage-url]
10+
11+
[package]: https://img.shields.io/badge/package-ESM--only-ffe536.svg
12+
[package-url]: https://nodejs.org/api/esm.html
13+
14+
[npm]: https://img.shields.io/npm/v/@simple-release/config.svg
15+
[npm-url]: https://www.npmjs.com/package/@simple-release/config
16+
17+
[node]: https://img.shields.io/node/v/@simple-release/config.svg
18+
[node-url]: https://nodejs.org
19+
20+
[deps]: https://img.shields.io/librariesio/release/npm/@simple-release/config
21+
[deps-url]: https://libraries.io/npm/@simple-release%2Fconfig/tree
22+
23+
[size]: https://packagephobia.com/badge?p=@simple-release/config
24+
[size-url]: https://packagephobia.com/result?p=@simple-release/config
25+
26+
[build]: https://img.shields.io/github/actions/workflow/status/TrigenSoftware/simple-release/tests.yml?branch=main
27+
[build-url]: https://github.com/TrigenSoftware/simple-release/actions
28+
29+
[coverage]: https://coveralls.io/repos/github/TrigenSoftware/simple-release/badge.svg?branch=main
30+
[coverage-url]: https://coveralls.io/github/TrigenSoftware/simple-release?branch=main
31+
32+
A simple-release config loader.
33+
34+
## Install
35+
36+
```bash
37+
# pnpm
38+
pnpm add @simple-release/config
39+
# yarn
40+
yarn add @simple-release/config
41+
# npm
42+
npm i @simple-release/config
43+
```
44+
45+
## Usage
46+
47+
This package provides a function to find and load js config file for simple-release. Possible config file names are:
48+
49+
- `.simple-release.js`
50+
- `.simple-release.cjs`
51+
- `.simple-release.mjs`
52+
53+
```js
54+
import { load } from '@simple-release/config'
55+
56+
await load() // Returns config object or null
57+
await load({ config: true }) // Returns config object or throws an error if config is not found
58+
await load({ [propertyName]: true }) // Returns config object with desired property or null or throws an error if property is not set in config
59+
```

packages/config/package.json

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"name": "@simple-release/config",
3+
"type": "module",
4+
"version": "1.0.0",
5+
"description": "A simple-release config loader.",
6+
"author": {
7+
"name": "Dan Onoshko",
8+
"email": "[email protected]",
9+
"url": "https://github.com/dangreen"
10+
},
11+
"license": "MIT",
12+
"homepage": "https://github.com/TrigenSoftware/simple-release/tree/master/packages/config#readme",
13+
"funding": "https://ko-fi.com/dangreen",
14+
"repository": {
15+
"type": "git",
16+
"url": "https://github.com/TrigenSoftware/simple-release.git",
17+
"directory": "packages/config"
18+
},
19+
"bugs": {
20+
"url": "https://github.com/TrigenSoftware/simple-release/issues"
21+
},
22+
"keywords": [
23+
"simple-release",
24+
"config",
25+
"loader"
26+
],
27+
"engines": {
28+
"node": ">=18"
29+
},
30+
"exports": "./src/index.ts",
31+
"publishConfig": {
32+
"exports": {
33+
"types": "./dist/index.d.ts",
34+
"import": "./dist/index.js"
35+
},
36+
"directory": "package",
37+
"linkDirectory": false
38+
},
39+
"files": [
40+
"dist"
41+
],
42+
"scripts": {
43+
"clear:package": "del ./package",
44+
"clear:dist": "del ./dist",
45+
"clear": "del ./package ./dist ./coverage",
46+
"prepublishOnly": "run build clear:package clean-publish",
47+
"postpublish": "pnpm clear:package",
48+
"build": "tsc -p tsconfig.build.json",
49+
"lint": "eslint --parser-options tsconfigRootDir:. '**/*.{js,ts}'",
50+
"test:types": "tsc --noEmit",
51+
"test": "run -p lint test:types"
52+
},
53+
"dependencies": {
54+
"@simple-release/core": "workspace:^",
55+
"find-up-simple": "^1.0.1"
56+
}
57+
}

packages/config/src/index.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import { findUp } from 'find-up-simple'
3+
import type {
4+
ReleaserStepsOptions,
5+
Project,
6+
GitRepositoryHosting,
7+
ReleaserOptions
8+
} from '@simple-release/core'
9+
10+
const VARIANTS = [
11+
'.simple-release.js',
12+
'.simple-release.mjs',
13+
'.simple-release.cjs'
14+
]
15+
16+
export interface SimpleReleaseConfig<
17+
P extends Project = Project,
18+
G extends GitRepositoryHosting = GitRepositoryHosting
19+
> extends ReleaserStepsOptions<P, G> {
20+
project?: P
21+
hosting?: G
22+
releaser?: Omit<ReleaserOptions, 'project' | 'hosting'>
23+
}
24+
25+
export type SimpleReleaseConfigRequirements = {
26+
config?: boolean
27+
} & {
28+
[K in keyof SimpleReleaseConfig]?: boolean
29+
}
30+
31+
type ApplyRequirements<T extends Record<string, any>, R extends Record<string, any>> = {
32+
[K in keyof T as K extends keyof R ? R[K] extends true ? K : never : never]-?: Exclude<T[K], undefined>
33+
} & {
34+
[K in keyof T as K extends keyof R ? R[K] extends true ? never : K : K]: T[K]
35+
}
36+
37+
type ApplyConfigRequirement<R extends { config?: boolean }, T> = R extends { config: true }
38+
? T
39+
: T | null
40+
41+
type Result<
42+
P extends Project = Project,
43+
G extends GitRepositoryHosting = GitRepositoryHosting,
44+
R extends SimpleReleaseConfigRequirements = SimpleReleaseConfigRequirements
45+
> = ApplyRequirements<SimpleReleaseConfig<P, G>, R> extends infer C
46+
? ApplyConfigRequirement<R, C>
47+
: never
48+
49+
function validate(target: Record<string, any>, rules: Record<string, any>) {
50+
for (const [rule, required] of Object.entries(rules)) {
51+
if (required && target[rule] === undefined) {
52+
throw new Error(`Faild to load config: '${rule}' is required`)
53+
}
54+
}
55+
}
56+
57+
/**
58+
* Load simple-release config.
59+
* @param requirements
60+
* @returns simple-release config
61+
*/
62+
export async function load<
63+
P extends Project = Project,
64+
G extends GitRepositoryHosting = GitRepositoryHosting,
65+
R extends SimpleReleaseConfigRequirements = SimpleReleaseConfigRequirements
66+
>(requirements?: R): Promise<Result<P, G, R>>
67+
68+
export async function load(requirements: Record<string, any> = {}) {
69+
const {
70+
config: configRequired,
71+
...reqs
72+
} = requirements
73+
74+
for (const variant of VARIANTS) {
75+
const foundPath = await findUp(variant)
76+
77+
if (foundPath) {
78+
try {
79+
const module = await import(foundPath) as SimpleReleaseConfig | { default: SimpleReleaseConfig }
80+
const config = 'default' in module ? module.default : module
81+
82+
validate(config, reqs)
83+
84+
return config
85+
} catch (err) {
86+
if (configRequired) {
87+
throw err
88+
}
89+
90+
return null
91+
}
92+
}
93+
}
94+
95+
if (configRequired) {
96+
throw new Error('Config not found')
97+
}
98+
99+
return null
100+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "dist"
5+
},
6+
"include": [
7+
"src"
8+
],
9+
"exclude": [
10+
"**/*.spec.ts"
11+
]
12+
}

packages/config/tsconfig.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "./tsconfig.build.json",
3+
"include": [
4+
"src"
5+
],
6+
"exclude": []
7+
}

pnpm-lock.yaml

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)