@a35hie/ts-pkg 0.1.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.
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/inspectionProfiles/Project_Default.xml +38 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.prettierignore +6 -0
- package/.prettierrc +9 -0
- package/LICENSE.txt +201 -0
- package/README.md +151 -0
- package/build.ts +14 -0
- package/bun.lock +73 -0
- package/dist/main.d.ts +147 -0
- package/dist/main.js +297 -0
- package/dist/main.js.map +15 -0
- package/package.config.ts +58 -0
- package/package.json +37 -0
- package/src/generator/createPackageJson.ts +84 -0
- package/src/main.ts +66 -0
- package/src/presets/scripts.ts +59 -0
- package/src/resolvers/dependencies.ts +107 -0
- package/src/schemas/package.ts +122 -0
- package/src/utils/conditions.ts +67 -0
- package/src/utils/merge.ts +91 -0
- package/ts-pkg-config.iml +8 -0
- package/tsconfig.json +32 -0
package/src/main.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PackageConfig,
|
|
3
|
+
StandardPackageJson,
|
|
4
|
+
ScriptPreset,
|
|
5
|
+
DependencyInput,
|
|
6
|
+
ConditionalConfig,
|
|
7
|
+
License,
|
|
8
|
+
} from './schemas/package'
|
|
9
|
+
import {
|
|
10
|
+
createPackageJson,
|
|
11
|
+
writePackageJson,
|
|
12
|
+
type GenerateOptions,
|
|
13
|
+
} from './generator/createPackageJson'
|
|
14
|
+
|
|
15
|
+
export function definePackageConfig(config: PackageConfig): PackageConfig {
|
|
16
|
+
return config
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Run CLI if executed directly
|
|
20
|
+
async function main() {
|
|
21
|
+
const configPath = process.argv[2] ?? 'package.config.ts'
|
|
22
|
+
const outputPath = process.argv[3] ?? 'package.json'
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const configModule = await import(Bun.pathToFileURL(configPath).href)
|
|
26
|
+
const config: PackageConfig = configModule.default ?? configModule
|
|
27
|
+
|
|
28
|
+
await writePackageJson(config, { outputPath })
|
|
29
|
+
} catch (error) {
|
|
30
|
+
if ((error as NodeJS.ErrnoException).code === 'ERR_MODULE_NOT_FOUND') {
|
|
31
|
+
console.error(`❌ Config file not found: ${configPath}`)
|
|
32
|
+
console.error('\nCreate a package.config.ts file with:')
|
|
33
|
+
console.error(`
|
|
34
|
+
import { definePackageConfig } from './src/main'
|
|
35
|
+
|
|
36
|
+
export default definePackageConfig({
|
|
37
|
+
name: 'my-package',
|
|
38
|
+
version: '1.0.0',
|
|
39
|
+
scriptPresets: ['typescript', 'testing'],
|
|
40
|
+
dependencies: ['lodash', 'zod'],
|
|
41
|
+
devDependencies: ['typescript', 'vitest'],
|
|
42
|
+
})
|
|
43
|
+
`)
|
|
44
|
+
process.exit(1)
|
|
45
|
+
}
|
|
46
|
+
throw error
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Export everything
|
|
51
|
+
export {
|
|
52
|
+
createPackageJson,
|
|
53
|
+
writePackageJson,
|
|
54
|
+
type PackageConfig,
|
|
55
|
+
type StandardPackageJson,
|
|
56
|
+
type ScriptPreset,
|
|
57
|
+
type DependencyInput,
|
|
58
|
+
type ConditionalConfig,
|
|
59
|
+
type GenerateOptions,
|
|
60
|
+
type License,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Run if main module
|
|
64
|
+
if (import.meta.main) {
|
|
65
|
+
main()
|
|
66
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ScriptPreset } from '../schemas/package'
|
|
2
|
+
|
|
3
|
+
type ScriptDefinitions = Record<string, string>
|
|
4
|
+
|
|
5
|
+
const scriptPresets: Record<ScriptPreset, ScriptDefinitions> = {
|
|
6
|
+
typescript: {
|
|
7
|
+
build: 'tsc',
|
|
8
|
+
'build:watch': 'tsc --watch',
|
|
9
|
+
typecheck: 'tsc --noEmit',
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
react: {
|
|
13
|
+
dev: 'vite',
|
|
14
|
+
build: 'vite build',
|
|
15
|
+
preview: 'vite preview',
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
node: {
|
|
19
|
+
start: 'node dist/index.js',
|
|
20
|
+
dev: 'tsx watch src/index.ts',
|
|
21
|
+
build: 'tsup src/index.ts --format esm,cjs --dts',
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
testing: {
|
|
25
|
+
test: 'vitest',
|
|
26
|
+
'test:watch': 'vitest watch',
|
|
27
|
+
'test:coverage': 'vitest --coverage',
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
prettier: {
|
|
31
|
+
format: 'prettier --write .',
|
|
32
|
+
'format:check': 'prettier --check .',
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
eslint: {
|
|
36
|
+
lint: 'eslint .',
|
|
37
|
+
'lint:fix': 'eslint . --fix',
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function getPresetScripts(presets: ScriptPreset[]): ScriptDefinitions {
|
|
42
|
+
const merged: ScriptDefinitions = {}
|
|
43
|
+
|
|
44
|
+
for (const preset of presets) {
|
|
45
|
+
const scripts = scriptPresets[preset]
|
|
46
|
+
if (scripts) {
|
|
47
|
+
Object.assign(merged, scripts)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return merged
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function mergeScripts(
|
|
55
|
+
presetScripts: ScriptDefinitions,
|
|
56
|
+
customScripts?: ScriptDefinitions
|
|
57
|
+
): ScriptDefinitions {
|
|
58
|
+
return { ...presetScripts, ...customScripts }
|
|
59
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { DependencyInput } from '../schemas/package'
|
|
2
|
+
|
|
3
|
+
interface NpmPackageInfo {
|
|
4
|
+
'dist-tags': {
|
|
5
|
+
latest: string
|
|
6
|
+
[tag: string]: string
|
|
7
|
+
}
|
|
8
|
+
versions: Record<string, unknown>
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Parse dependency input: 'lodash' | 'lodash@^4' | { lodash: '^4.0.0' }
|
|
12
|
+
function parseDependency(dep: DependencyInput): {
|
|
13
|
+
name: string
|
|
14
|
+
version?: string
|
|
15
|
+
} {
|
|
16
|
+
if (typeof dep === 'string') {
|
|
17
|
+
const atIndex = dep.lastIndexOf('@')
|
|
18
|
+
if (atIndex > 0) {
|
|
19
|
+
return {
|
|
20
|
+
name: dep.slice(0, atIndex),
|
|
21
|
+
version: dep.slice(atIndex + 1),
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return { name: dep }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Object form: { lodash: '^4.0.0' }
|
|
28
|
+
const [name, version] = Object.entries(dep)[0]!
|
|
29
|
+
return { name, version }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Fetch latest version from npm registry
|
|
33
|
+
async function fetchLatestVersion(packageName: string): Promise<string> {
|
|
34
|
+
const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}`
|
|
35
|
+
|
|
36
|
+
const response = await fetch(url, {
|
|
37
|
+
headers: { Accept: 'application/json' },
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
throw new Error(`Failed to fetch ${packageName}: ${response.statusText}`)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const data = (await response.json()) as NpmPackageInfo
|
|
45
|
+
return data['dist-tags'].latest
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Resolve a single dependency to name: version pair
|
|
49
|
+
async function resolveDependency(
|
|
50
|
+
dep: DependencyInput
|
|
51
|
+
): Promise<[string, string]> {
|
|
52
|
+
const { name, version } = parseDependency(dep)
|
|
53
|
+
|
|
54
|
+
if (version) {
|
|
55
|
+
return [name, version]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Auto-resolve latest version with ^ prefix
|
|
59
|
+
const latestVersion = await fetchLatestVersion(name)
|
|
60
|
+
return [name, `^${latestVersion}`]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Resolve all dependencies in parallel with batching
|
|
64
|
+
export async function resolveDependencies(
|
|
65
|
+
deps: DependencyInput[] | undefined
|
|
66
|
+
): Promise<Record<string, string>> {
|
|
67
|
+
if (!deps || deps.length === 0) {
|
|
68
|
+
return {}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const results = await Promise.all(deps.map(resolveDependency))
|
|
72
|
+
|
|
73
|
+
return Object.fromEntries(results)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Cache for resolved versions (persists during single run)
|
|
77
|
+
const versionCache = new Map<string, string>()
|
|
78
|
+
|
|
79
|
+
export async function resolveDependenciesCached(
|
|
80
|
+
deps: DependencyInput[] | undefined
|
|
81
|
+
): Promise<Record<string, string>> {
|
|
82
|
+
if (!deps || deps.length === 0) {
|
|
83
|
+
return {}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const results: [string, string][] = []
|
|
87
|
+
|
|
88
|
+
for (const dep of deps) {
|
|
89
|
+
const { name, version } = parseDependency(dep)
|
|
90
|
+
|
|
91
|
+
if (version) {
|
|
92
|
+
results.push([name, version])
|
|
93
|
+
continue
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Check cache first
|
|
97
|
+
let resolvedVersion = versionCache.get(name)
|
|
98
|
+
if (!resolvedVersion) {
|
|
99
|
+
resolvedVersion = `^${await fetchLatestVersion(name)}`
|
|
100
|
+
versionCache.set(name, resolvedVersion)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
results.push([name, resolvedVersion])
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return Object.fromEntries(results)
|
|
107
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// Common SPDX license identifiers
|
|
2
|
+
export type License =
|
|
3
|
+
| 'MIT'
|
|
4
|
+
| 'Apache-2.0'
|
|
5
|
+
| 'GPL-2.0-only'
|
|
6
|
+
| 'GPL-2.0-or-later'
|
|
7
|
+
| 'GPL-3.0-only'
|
|
8
|
+
| 'GPL-3.0-or-later'
|
|
9
|
+
| 'LGPL-2.1-only'
|
|
10
|
+
| 'LGPL-2.1-or-later'
|
|
11
|
+
| 'LGPL-3.0-only'
|
|
12
|
+
| 'LGPL-3.0-or-later'
|
|
13
|
+
| 'BSD-2-Clause'
|
|
14
|
+
| 'BSD-3-Clause'
|
|
15
|
+
| 'ISC'
|
|
16
|
+
| 'MPL-2.0'
|
|
17
|
+
| 'AGPL-3.0-only'
|
|
18
|
+
| 'AGPL-3.0-or-later'
|
|
19
|
+
| 'Unlicense'
|
|
20
|
+
| 'WTFPL'
|
|
21
|
+
| 'CC0-1.0'
|
|
22
|
+
| 'CC-BY-4.0'
|
|
23
|
+
| 'CC-BY-SA-4.0'
|
|
24
|
+
| 'Zlib'
|
|
25
|
+
| 'BSL-1.0'
|
|
26
|
+
| 'EPL-2.0'
|
|
27
|
+
| 'EUPL-1.2'
|
|
28
|
+
| 'CDDL-1.0'
|
|
29
|
+
| 'Artistic-2.0'
|
|
30
|
+
| 'OSL-3.0'
|
|
31
|
+
| 'AFL-3.0'
|
|
32
|
+
| 'LPPL-1.3c'
|
|
33
|
+
| (string & {}) // Allow custom licenses while preserving autocomplete
|
|
34
|
+
|
|
35
|
+
// Standard package.json fields
|
|
36
|
+
export interface StandardPackageJson {
|
|
37
|
+
name: string
|
|
38
|
+
version?: string
|
|
39
|
+
description?: string
|
|
40
|
+
keywords?: string[]
|
|
41
|
+
homepage?: string
|
|
42
|
+
bugs?: string | { url?: string; email?: string }
|
|
43
|
+
license?: License
|
|
44
|
+
author?: string | { name: string; email?: string; url?: string }
|
|
45
|
+
contributors?: (string | { name: string; email?: string; url?: string })[]
|
|
46
|
+
repository?: string | { type: string; url: string; directory?: string }
|
|
47
|
+
main?: string
|
|
48
|
+
module?: string
|
|
49
|
+
types?: string
|
|
50
|
+
exports?: Record<
|
|
51
|
+
string,
|
|
52
|
+
string | { import?: string; require?: string; types?: string }
|
|
53
|
+
>
|
|
54
|
+
bin?: string | Record<string, string>
|
|
55
|
+
files?: string[]
|
|
56
|
+
scripts?: Record<string, string>
|
|
57
|
+
dependencies?: Record<string, string>
|
|
58
|
+
devDependencies?: Record<string, string>
|
|
59
|
+
peerDependencies?: Record<string, string>
|
|
60
|
+
optionalDependencies?: Record<string, string>
|
|
61
|
+
engines?: Record<string, string>
|
|
62
|
+
os?: string[]
|
|
63
|
+
cpu?: string[]
|
|
64
|
+
private?: boolean
|
|
65
|
+
publishConfig?: Record<string, unknown>
|
|
66
|
+
workspaces?: string[]
|
|
67
|
+
type?: 'module' | 'commonjs'
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Script preset names
|
|
71
|
+
export type ScriptPreset =
|
|
72
|
+
| 'typescript'
|
|
73
|
+
| 'react'
|
|
74
|
+
| 'node'
|
|
75
|
+
| 'testing'
|
|
76
|
+
| 'prettier'
|
|
77
|
+
| 'eslint'
|
|
78
|
+
|
|
79
|
+
// Dependency can be: 'lodash' | 'lodash@^4' | { lodash: '^4.0.0' }
|
|
80
|
+
export type DependencyInput = string | Record<string, string>
|
|
81
|
+
|
|
82
|
+
// Conditional config block
|
|
83
|
+
export interface ConditionalConfig {
|
|
84
|
+
when: {
|
|
85
|
+
env?: string
|
|
86
|
+
platform?: NodeJS.Platform
|
|
87
|
+
nodeVersion?: string
|
|
88
|
+
ci?: boolean
|
|
89
|
+
}
|
|
90
|
+
set: Partial<StandardPackageJson>
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Magical package.json config with extra features
|
|
94
|
+
export interface PackageConfig extends Omit<
|
|
95
|
+
StandardPackageJson,
|
|
96
|
+
'scripts' | 'dependencies' | 'devDependencies' | 'peerDependencies'
|
|
97
|
+
> {
|
|
98
|
+
// Extends another config
|
|
99
|
+
extends?: string | PackageConfig
|
|
100
|
+
|
|
101
|
+
// Script presets: auto-generate common scripts
|
|
102
|
+
scriptPresets?: ScriptPreset[]
|
|
103
|
+
scripts?: Record<string, string>
|
|
104
|
+
|
|
105
|
+
// Magical dependency inputs (auto-resolve versions)
|
|
106
|
+
dependencies?: DependencyInput[]
|
|
107
|
+
devDependencies?: DependencyInput[]
|
|
108
|
+
peerDependencies?: DependencyInput[]
|
|
109
|
+
|
|
110
|
+
// Conditional configuration
|
|
111
|
+
conditions?: ConditionalConfig[]
|
|
112
|
+
|
|
113
|
+
// Auto-infer fields
|
|
114
|
+
autoInfer?: {
|
|
115
|
+
version?: boolean // from git tags
|
|
116
|
+
repository?: boolean // from git remote
|
|
117
|
+
author?: boolean // from git config
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Re-export for backwards compatibility
|
|
122
|
+
export type PackageJson = PackageConfig
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ConditionalConfig, StandardPackageJson } from '../schemas/package'
|
|
2
|
+
import { deepMerge } from './merge'
|
|
3
|
+
|
|
4
|
+
interface ConditionContext {
|
|
5
|
+
env: string
|
|
6
|
+
platform: NodeJS.Platform
|
|
7
|
+
nodeVersion: string
|
|
8
|
+
ci: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getContext(): ConditionContext {
|
|
12
|
+
return {
|
|
13
|
+
env: process.env.NODE_ENV ?? 'development',
|
|
14
|
+
platform: process.platform,
|
|
15
|
+
nodeVersion: process.version,
|
|
16
|
+
ci: process.env.CI === 'true' || process.env.CI === '1',
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function evaluateCondition(
|
|
21
|
+
when: ConditionalConfig['when'],
|
|
22
|
+
context: ConditionContext
|
|
23
|
+
): boolean {
|
|
24
|
+
if (when.env !== undefined && context.env !== when.env) {
|
|
25
|
+
return false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (when.platform !== undefined && context.platform !== when.platform) {
|
|
29
|
+
return false
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (when.ci !== undefined && context.ci !== when.ci) {
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (when.nodeVersion !== undefined) {
|
|
37
|
+
// Simple semver check (starts with)
|
|
38
|
+
if (!context.nodeVersion.startsWith(when.nodeVersion)) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return true
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function applyConditions(
|
|
47
|
+
baseConfig: Partial<StandardPackageJson>,
|
|
48
|
+
conditions: ConditionalConfig[] | undefined
|
|
49
|
+
): Partial<StandardPackageJson> {
|
|
50
|
+
if (!conditions || conditions.length === 0) {
|
|
51
|
+
return baseConfig
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const context = getContext()
|
|
55
|
+
let result = { ...baseConfig }
|
|
56
|
+
|
|
57
|
+
for (const condition of conditions) {
|
|
58
|
+
if (evaluateCondition(condition.when, context)) {
|
|
59
|
+
result = deepMerge(
|
|
60
|
+
result,
|
|
61
|
+
condition.set as Record<string, unknown>
|
|
62
|
+
) as Partial<StandardPackageJson>
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return result
|
|
67
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { PackageConfig } from '../schemas/package'
|
|
2
|
+
|
|
3
|
+
// Deep merge two objects, with source overriding target
|
|
4
|
+
export function deepMerge<T extends Record<string, unknown>>(
|
|
5
|
+
target: T,
|
|
6
|
+
source: Partial<T>
|
|
7
|
+
): T {
|
|
8
|
+
const result = { ...target }
|
|
9
|
+
|
|
10
|
+
for (const key of Object.keys(source) as (keyof T)[]) {
|
|
11
|
+
const sourceValue = source[key]
|
|
12
|
+
const targetValue = target[key]
|
|
13
|
+
|
|
14
|
+
if (sourceValue === undefined) continue
|
|
15
|
+
|
|
16
|
+
if (
|
|
17
|
+
typeof sourceValue === 'object' &&
|
|
18
|
+
sourceValue !== null &&
|
|
19
|
+
!Array.isArray(sourceValue) &&
|
|
20
|
+
typeof targetValue === 'object' &&
|
|
21
|
+
targetValue !== null &&
|
|
22
|
+
!Array.isArray(targetValue)
|
|
23
|
+
) {
|
|
24
|
+
result[key] = deepMerge(
|
|
25
|
+
targetValue as Record<string, unknown>,
|
|
26
|
+
sourceValue as Record<string, unknown>
|
|
27
|
+
) as T[keyof T]
|
|
28
|
+
} else {
|
|
29
|
+
result[key] = sourceValue as T[keyof T]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return result
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Merge arrays (for dependencies)
|
|
37
|
+
export function mergeArrays<T>(
|
|
38
|
+
target: T[] | undefined,
|
|
39
|
+
source: T[] | undefined
|
|
40
|
+
): T[] {
|
|
41
|
+
return [...(target ?? []), ...(source ?? [])]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Resolve extends chain
|
|
45
|
+
export async function resolveExtends(
|
|
46
|
+
config: PackageConfig
|
|
47
|
+
): Promise<PackageConfig> {
|
|
48
|
+
if (!config.extends) {
|
|
49
|
+
return config
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let baseConfig: PackageConfig
|
|
53
|
+
|
|
54
|
+
if (typeof config.extends === 'string') {
|
|
55
|
+
// Import from file path
|
|
56
|
+
const imported = await import(config.extends)
|
|
57
|
+
baseConfig = imported.default ?? imported
|
|
58
|
+
} else {
|
|
59
|
+
baseConfig = config.extends
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Recursively resolve base config's extends
|
|
63
|
+
baseConfig = await resolveExtends(baseConfig)
|
|
64
|
+
|
|
65
|
+
// Merge base into current (current overrides base)
|
|
66
|
+
const { extends: _, ...currentWithoutExtends } = config
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
...baseConfig,
|
|
70
|
+
...currentWithoutExtends,
|
|
71
|
+
// Merge arrays for dependencies
|
|
72
|
+
dependencies: mergeArrays(
|
|
73
|
+
baseConfig.dependencies,
|
|
74
|
+
currentWithoutExtends.dependencies
|
|
75
|
+
),
|
|
76
|
+
devDependencies: mergeArrays(
|
|
77
|
+
baseConfig.devDependencies,
|
|
78
|
+
currentWithoutExtends.devDependencies
|
|
79
|
+
),
|
|
80
|
+
peerDependencies: mergeArrays(
|
|
81
|
+
baseConfig.peerDependencies,
|
|
82
|
+
currentWithoutExtends.peerDependencies
|
|
83
|
+
),
|
|
84
|
+
// Merge objects for scripts
|
|
85
|
+
scripts: { ...baseConfig.scripts, ...currentWithoutExtends.scripts },
|
|
86
|
+
scriptPresets: [
|
|
87
|
+
...(baseConfig.scriptPresets ?? []),
|
|
88
|
+
...(currentWithoutExtends.scriptPresets ?? []),
|
|
89
|
+
],
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="GENERAL_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
+
<exclude-output />
|
|
5
|
+
<content url="file://$MODULE_DIR$" />
|
|
6
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
7
|
+
</component>
|
|
8
|
+
</module>
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Environment setup & latest features
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "Preserve",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
"jsx": "react-jsx",
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
|
|
11
|
+
// Bundler mode
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
// Best practices
|
|
18
|
+
"strict": true,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedIndexedAccess": true,
|
|
22
|
+
"noImplicitOverride": true,
|
|
23
|
+
|
|
24
|
+
// Some stricter flags (disabled by default)
|
|
25
|
+
"noUnusedLocals": false,
|
|
26
|
+
"noUnusedParameters": false,
|
|
27
|
+
"noPropertyAccessFromIndexSignature": false,
|
|
28
|
+
"paths": {
|
|
29
|
+
"@/*": ["./src/*"]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|