@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/dist/main.d.ts ADDED
@@ -0,0 +1,147 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ export type License =
4
+ | 'MIT'
5
+ | 'Apache-2.0'
6
+ | 'GPL-2.0-only'
7
+ | 'GPL-2.0-or-later'
8
+ | 'GPL-3.0-only'
9
+ | 'GPL-3.0-or-later'
10
+ | 'LGPL-2.1-only'
11
+ | 'LGPL-2.1-or-later'
12
+ | 'LGPL-3.0-only'
13
+ | 'LGPL-3.0-or-later'
14
+ | 'BSD-2-Clause'
15
+ | 'BSD-3-Clause'
16
+ | 'ISC'
17
+ | 'MPL-2.0'
18
+ | 'AGPL-3.0-only'
19
+ | 'AGPL-3.0-or-later'
20
+ | 'Unlicense'
21
+ | 'WTFPL'
22
+ | 'CC0-1.0'
23
+ | 'CC-BY-4.0'
24
+ | 'CC-BY-SA-4.0'
25
+ | 'Zlib'
26
+ | 'BSL-1.0'
27
+ | 'EPL-2.0'
28
+ | 'EUPL-1.2'
29
+ | 'CDDL-1.0'
30
+ | 'Artistic-2.0'
31
+ | 'OSL-3.0'
32
+ | 'AFL-3.0'
33
+ | 'LPPL-1.3c'
34
+ | (string & {})
35
+ export interface StandardPackageJson {
36
+ name: string
37
+ version?: string
38
+ description?: string
39
+ keywords?: string[]
40
+ homepage?: string
41
+ bugs?:
42
+ | string
43
+ | {
44
+ url?: string
45
+ email?: string
46
+ }
47
+ license?: License
48
+ author?:
49
+ | string
50
+ | {
51
+ name: string
52
+ email?: string
53
+ url?: string
54
+ }
55
+ contributors?: (
56
+ | string
57
+ | {
58
+ name: string
59
+ email?: string
60
+ url?: string
61
+ }
62
+ )[]
63
+ repository?:
64
+ | string
65
+ | {
66
+ type: string
67
+ url: string
68
+ directory?: string
69
+ }
70
+ main?: string
71
+ module?: string
72
+ types?: string
73
+ exports?: Record<
74
+ string,
75
+ | string
76
+ | {
77
+ import?: string
78
+ require?: string
79
+ types?: string
80
+ }
81
+ >
82
+ bin?: string | Record<string, string>
83
+ files?: string[]
84
+ scripts?: Record<string, string>
85
+ dependencies?: Record<string, string>
86
+ devDependencies?: Record<string, string>
87
+ peerDependencies?: Record<string, string>
88
+ optionalDependencies?: Record<string, string>
89
+ engines?: Record<string, string>
90
+ os?: string[]
91
+ cpu?: string[]
92
+ private?: boolean
93
+ publishConfig?: Record<string, unknown>
94
+ workspaces?: string[]
95
+ type?: 'module' | 'commonjs'
96
+ }
97
+ export type ScriptPreset =
98
+ | 'typescript'
99
+ | 'react'
100
+ | 'node'
101
+ | 'testing'
102
+ | 'prettier'
103
+ | 'eslint'
104
+ export type DependencyInput = string | Record<string, string>
105
+ export interface ConditionalConfig {
106
+ when: {
107
+ env?: string
108
+ platform?: NodeJS.Platform
109
+ nodeVersion?: string
110
+ ci?: boolean
111
+ }
112
+ set: Partial<StandardPackageJson>
113
+ }
114
+ export interface PackageConfig extends Omit<
115
+ StandardPackageJson,
116
+ 'scripts' | 'dependencies' | 'devDependencies' | 'peerDependencies'
117
+ > {
118
+ extends?: string | PackageConfig
119
+ scriptPresets?: ScriptPreset[]
120
+ scripts?: Record<string, string>
121
+ dependencies?: DependencyInput[]
122
+ devDependencies?: DependencyInput[]
123
+ peerDependencies?: DependencyInput[]
124
+ conditions?: ConditionalConfig[]
125
+ autoInfer?: {
126
+ version?: boolean
127
+ repository?: boolean
128
+ author?: boolean
129
+ }
130
+ }
131
+ export interface GenerateOptions {
132
+ indent?: number
133
+ outputPath?: string
134
+ }
135
+ export declare function createPackageJson(
136
+ config: PackageConfig,
137
+ options?: GenerateOptions
138
+ ): Promise<string>
139
+ export declare function writePackageJson(
140
+ config: PackageConfig,
141
+ options?: GenerateOptions
142
+ ): Promise<void>
143
+ export declare function definePackageConfig(
144
+ config: PackageConfig
145
+ ): PackageConfig
146
+
147
+ export {}
package/dist/main.js ADDED
@@ -0,0 +1,297 @@
1
+ import { createRequire } from 'node:module'
2
+ var __require = /* @__PURE__ */ createRequire(import.meta.url)
3
+
4
+ // src/presets/scripts.ts
5
+ var scriptPresets = {
6
+ typescript: {
7
+ build: 'tsc',
8
+ 'build:watch': 'tsc --watch',
9
+ typecheck: 'tsc --noEmit',
10
+ },
11
+ react: {
12
+ dev: 'vite',
13
+ build: 'vite build',
14
+ preview: 'vite preview',
15
+ },
16
+ node: {
17
+ start: 'node dist/index.js',
18
+ dev: 'tsx watch src/index.ts',
19
+ build: 'tsup src/index.ts --format esm,cjs --dts',
20
+ },
21
+ testing: {
22
+ test: 'vitest',
23
+ 'test:watch': 'vitest watch',
24
+ 'test:coverage': 'vitest --coverage',
25
+ },
26
+ prettier: {
27
+ format: 'prettier --write .',
28
+ 'format:check': 'prettier --check .',
29
+ },
30
+ eslint: {
31
+ lint: 'eslint .',
32
+ 'lint:fix': 'eslint . --fix',
33
+ },
34
+ }
35
+ function getPresetScripts(presets) {
36
+ const merged = {}
37
+ for (const preset of presets) {
38
+ const scripts = scriptPresets[preset]
39
+ if (scripts) {
40
+ Object.assign(merged, scripts)
41
+ }
42
+ }
43
+ return merged
44
+ }
45
+ function mergeScripts(presetScripts, customScripts) {
46
+ return { ...presetScripts, ...customScripts }
47
+ }
48
+
49
+ // src/resolvers/dependencies.ts
50
+ function parseDependency(dep) {
51
+ if (typeof dep === 'string') {
52
+ const atIndex = dep.lastIndexOf('@')
53
+ if (atIndex > 0) {
54
+ return {
55
+ name: dep.slice(0, atIndex),
56
+ version: dep.slice(atIndex + 1),
57
+ }
58
+ }
59
+ return { name: dep }
60
+ }
61
+ const [name, version] = Object.entries(dep)[0]
62
+ return { name, version }
63
+ }
64
+ async function fetchLatestVersion(packageName) {
65
+ const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}`
66
+ const response = await fetch(url, {
67
+ headers: { Accept: 'application/json' },
68
+ })
69
+ if (!response.ok) {
70
+ throw new Error(`Failed to fetch ${packageName}: ${response.statusText}`)
71
+ }
72
+ const data = await response.json()
73
+ return data['dist-tags'].latest
74
+ }
75
+ var versionCache = new Map()
76
+ async function resolveDependenciesCached(deps) {
77
+ if (!deps || deps.length === 0) {
78
+ return {}
79
+ }
80
+ const results = []
81
+ for (const dep of deps) {
82
+ const { name, version } = parseDependency(dep)
83
+ if (version) {
84
+ results.push([name, version])
85
+ continue
86
+ }
87
+ let resolvedVersion = versionCache.get(name)
88
+ if (!resolvedVersion) {
89
+ resolvedVersion = `^${await fetchLatestVersion(name)}`
90
+ versionCache.set(name, resolvedVersion)
91
+ }
92
+ results.push([name, resolvedVersion])
93
+ }
94
+ return Object.fromEntries(results)
95
+ }
96
+
97
+ // src/utils/merge.ts
98
+ function deepMerge(target, source) {
99
+ const result = { ...target }
100
+ for (const key of Object.keys(source)) {
101
+ const sourceValue = source[key]
102
+ const targetValue = target[key]
103
+ if (sourceValue === undefined) continue
104
+ if (
105
+ typeof sourceValue === 'object' &&
106
+ sourceValue !== null &&
107
+ !Array.isArray(sourceValue) &&
108
+ typeof targetValue === 'object' &&
109
+ targetValue !== null &&
110
+ !Array.isArray(targetValue)
111
+ ) {
112
+ result[key] = deepMerge(targetValue, sourceValue)
113
+ } else {
114
+ result[key] = sourceValue
115
+ }
116
+ }
117
+ return result
118
+ }
119
+ function mergeArrays(target, source) {
120
+ return [...(target ?? []), ...(source ?? [])]
121
+ }
122
+ async function resolveExtends(config) {
123
+ if (!config.extends) {
124
+ return config
125
+ }
126
+ let baseConfig
127
+ if (typeof config.extends === 'string') {
128
+ const imported = await import(config.extends)
129
+ baseConfig = imported.default ?? imported
130
+ } else {
131
+ baseConfig = config.extends
132
+ }
133
+ baseConfig = await resolveExtends(baseConfig)
134
+ const { extends: _, ...currentWithoutExtends } = config
135
+ return {
136
+ ...baseConfig,
137
+ ...currentWithoutExtends,
138
+ dependencies: mergeArrays(
139
+ baseConfig.dependencies,
140
+ currentWithoutExtends.dependencies
141
+ ),
142
+ devDependencies: mergeArrays(
143
+ baseConfig.devDependencies,
144
+ currentWithoutExtends.devDependencies
145
+ ),
146
+ peerDependencies: mergeArrays(
147
+ baseConfig.peerDependencies,
148
+ currentWithoutExtends.peerDependencies
149
+ ),
150
+ scripts: { ...baseConfig.scripts, ...currentWithoutExtends.scripts },
151
+ scriptPresets: [
152
+ ...(baseConfig.scriptPresets ?? []),
153
+ ...(currentWithoutExtends.scriptPresets ?? []),
154
+ ],
155
+ }
156
+ }
157
+
158
+ // src/utils/conditions.ts
159
+ function getContext() {
160
+ return {
161
+ env: 'development',
162
+ platform: process.platform,
163
+ nodeVersion: process.version,
164
+ ci: process.env.CI === 'true' || process.env.CI === '1',
165
+ }
166
+ }
167
+ function evaluateCondition(when, context) {
168
+ if (when.env !== undefined && context.env !== when.env) {
169
+ return false
170
+ }
171
+ if (when.platform !== undefined && context.platform !== when.platform) {
172
+ return false
173
+ }
174
+ if (when.ci !== undefined && context.ci !== when.ci) {
175
+ return false
176
+ }
177
+ if (when.nodeVersion !== undefined) {
178
+ if (!context.nodeVersion.startsWith(when.nodeVersion)) {
179
+ return false
180
+ }
181
+ }
182
+ return true
183
+ }
184
+ function applyConditions(baseConfig, conditions) {
185
+ if (!conditions || conditions.length === 0) {
186
+ return baseConfig
187
+ }
188
+ const context = getContext()
189
+ let result = { ...baseConfig }
190
+ for (const condition of conditions) {
191
+ if (evaluateCondition(condition.when, context)) {
192
+ result = deepMerge(result, condition.set)
193
+ }
194
+ }
195
+ return result
196
+ }
197
+
198
+ // src/generator/createPackageJson.ts
199
+ async function createPackageJson(config, options = {}) {
200
+ const { indent = 2 } = options
201
+ let resolved = await resolveExtends(config)
202
+ const presetScripts = resolved.scriptPresets
203
+ ? getPresetScripts(resolved.scriptPresets)
204
+ : {}
205
+ const finalScripts = mergeScripts(presetScripts, resolved.scripts)
206
+ const [dependencies, devDependencies, peerDependencies] = await Promise.all([
207
+ resolveDependenciesCached(resolved.dependencies),
208
+ resolveDependenciesCached(resolved.devDependencies),
209
+ resolveDependenciesCached(resolved.peerDependencies),
210
+ ])
211
+ const packageJson = {
212
+ name: resolved.name,
213
+ ...(resolved.version && { version: resolved.version }),
214
+ ...(resolved.description && { description: resolved.description }),
215
+ ...(resolved.keywords?.length && { keywords: resolved.keywords }),
216
+ ...(resolved.homepage && { homepage: resolved.homepage }),
217
+ ...(resolved.bugs && { bugs: resolved.bugs }),
218
+ ...(resolved.license && { license: resolved.license }),
219
+ ...(resolved.author && { author: resolved.author }),
220
+ ...(resolved.contributors?.length && {
221
+ contributors: resolved.contributors,
222
+ }),
223
+ ...(resolved.repository && { repository: resolved.repository }),
224
+ ...(resolved.type && { type: resolved.type }),
225
+ ...(resolved.main && { main: resolved.main }),
226
+ ...(resolved.module && { module: resolved.module }),
227
+ ...(resolved.types && { types: resolved.types }),
228
+ ...(resolved.exports && { exports: resolved.exports }),
229
+ ...(resolved.bin && { bin: resolved.bin }),
230
+ ...(resolved.files?.length && { files: resolved.files }),
231
+ ...(Object.keys(finalScripts).length && { scripts: finalScripts }),
232
+ ...(Object.keys(dependencies).length && { dependencies }),
233
+ ...(Object.keys(devDependencies).length && { devDependencies }),
234
+ ...(Object.keys(peerDependencies).length && { peerDependencies }),
235
+ ...(resolved.optionalDependencies && {
236
+ optionalDependencies: resolved.optionalDependencies,
237
+ }),
238
+ ...(resolved.engines && { engines: resolved.engines }),
239
+ ...(resolved.os?.length && { os: resolved.os }),
240
+ ...(resolved.cpu?.length && { cpu: resolved.cpu }),
241
+ ...(resolved.private !== undefined && { private: resolved.private }),
242
+ ...(resolved.publishConfig && { publishConfig: resolved.publishConfig }),
243
+ ...(resolved.workspaces?.length && { workspaces: resolved.workspaces }),
244
+ }
245
+ const finalPackageJson = applyConditions(packageJson, resolved.conditions)
246
+ return JSON.stringify(finalPackageJson, null, indent)
247
+ }
248
+ async function writePackageJson(config, options = {}) {
249
+ const { outputPath = 'package.json' } = options
250
+ const json = await createPackageJson(config, options)
251
+ await Bun.write(
252
+ outputPath,
253
+ json +
254
+ `
255
+ `
256
+ )
257
+ console.log(`✨ Generated ${outputPath}`)
258
+ }
259
+
260
+ // src/main.ts
261
+ function definePackageConfig(config) {
262
+ return config
263
+ }
264
+ async function main() {
265
+ const configPath = process.argv[2] ?? 'package.config.ts'
266
+ const outputPath = process.argv[3] ?? 'package.json'
267
+ try {
268
+ const configModule = await import(Bun.pathToFileURL(configPath).href)
269
+ const config = configModule.default ?? configModule
270
+ await writePackageJson(config, { outputPath })
271
+ } catch (error) {
272
+ if (error.code === 'ERR_MODULE_NOT_FOUND') {
273
+ console.error(`❌ Config file not found: ${configPath}`)
274
+ console.error(`
275
+ Create a package.config.ts file with:`)
276
+ console.error(`
277
+ import { definePackageConfig } from './src/main'
278
+
279
+ export default definePackageConfig({
280
+ name: 'my-package',
281
+ version: '1.0.0',
282
+ scriptPresets: ['typescript', 'testing'],
283
+ dependencies: ['lodash', 'zod'],
284
+ devDependencies: ['typescript', 'vitest'],
285
+ })
286
+ `)
287
+ process.exit(1)
288
+ }
289
+ throw error
290
+ }
291
+ }
292
+ if (__require.main == __require.module) {
293
+ main()
294
+ }
295
+ export { writePackageJson, definePackageConfig, createPackageJson }
296
+
297
+ //# debugId=B903D397D524CA2964756E2164756E21
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/presets/scripts.ts", "../src/resolvers/dependencies.ts", "../src/utils/merge.ts", "../src/utils/conditions.ts", "../src/generator/createPackageJson.ts", "../src/main.ts"],
4
+ "sourcesContent": [
5
+ "import type { ScriptPreset } from '../schemas/package'\n\ntype ScriptDefinitions = Record<string, string>\n\nconst scriptPresets: Record<ScriptPreset, ScriptDefinitions> = {\n typescript: {\n build: 'tsc',\n 'build:watch': 'tsc --watch',\n typecheck: 'tsc --noEmit',\n },\n\n react: {\n dev: 'vite',\n build: 'vite build',\n preview: 'vite preview',\n },\n\n node: {\n start: 'node dist/index.js',\n dev: 'tsx watch src/index.ts',\n build: 'tsup src/index.ts --format esm,cjs --dts',\n },\n\n testing: {\n test: 'vitest',\n 'test:watch': 'vitest watch',\n 'test:coverage': 'vitest --coverage',\n },\n\n prettier: {\n format: 'prettier --write .',\n 'format:check': 'prettier --check .',\n },\n\n eslint: {\n lint: 'eslint .',\n 'lint:fix': 'eslint . --fix',\n },\n}\n\nexport function getPresetScripts(presets: ScriptPreset[]): ScriptDefinitions {\n const merged: ScriptDefinitions = {}\n\n for (const preset of presets) {\n const scripts = scriptPresets[preset]\n if (scripts) {\n Object.assign(merged, scripts)\n }\n }\n\n return merged\n}\n\nexport function mergeScripts(\n presetScripts: ScriptDefinitions,\n customScripts?: ScriptDefinitions\n): ScriptDefinitions {\n return { ...presetScripts, ...customScripts }\n}\n",
6
+ "import type { DependencyInput } from '../schemas/package'\n\ninterface NpmPackageInfo {\n 'dist-tags': {\n latest: string\n [tag: string]: string\n }\n versions: Record<string, unknown>\n}\n\n// Parse dependency input: 'lodash' | 'lodash@^4' | { lodash: '^4.0.0' }\nfunction parseDependency(dep: DependencyInput): {\n name: string\n version?: string\n} {\n if (typeof dep === 'string') {\n const atIndex = dep.lastIndexOf('@')\n if (atIndex > 0) {\n return {\n name: dep.slice(0, atIndex),\n version: dep.slice(atIndex + 1),\n }\n }\n return { name: dep }\n }\n\n // Object form: { lodash: '^4.0.0' }\n const [name, version] = Object.entries(dep)[0]!\n return { name, version }\n}\n\n// Fetch latest version from npm registry\nasync function fetchLatestVersion(packageName: string): Promise<string> {\n const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}`\n\n const response = await fetch(url, {\n headers: { Accept: 'application/json' },\n })\n\n if (!response.ok) {\n throw new Error(`Failed to fetch ${packageName}: ${response.statusText}`)\n }\n\n const data = (await response.json()) as NpmPackageInfo\n return data['dist-tags'].latest\n}\n\n// Resolve a single dependency to name: version pair\nasync function resolveDependency(\n dep: DependencyInput\n): Promise<[string, string]> {\n const { name, version } = parseDependency(dep)\n\n if (version) {\n return [name, version]\n }\n\n // Auto-resolve latest version with ^ prefix\n const latestVersion = await fetchLatestVersion(name)\n return [name, `^${latestVersion}`]\n}\n\n// Resolve all dependencies in parallel with batching\nexport async function resolveDependencies(\n deps: DependencyInput[] | undefined\n): Promise<Record<string, string>> {\n if (!deps || deps.length === 0) {\n return {}\n }\n\n const results = await Promise.all(deps.map(resolveDependency))\n\n return Object.fromEntries(results)\n}\n\n// Cache for resolved versions (persists during single run)\nconst versionCache = new Map<string, string>()\n\nexport async function resolveDependenciesCached(\n deps: DependencyInput[] | undefined\n): Promise<Record<string, string>> {\n if (!deps || deps.length === 0) {\n return {}\n }\n\n const results: [string, string][] = []\n\n for (const dep of deps) {\n const { name, version } = parseDependency(dep)\n\n if (version) {\n results.push([name, version])\n continue\n }\n\n // Check cache first\n let resolvedVersion = versionCache.get(name)\n if (!resolvedVersion) {\n resolvedVersion = `^${await fetchLatestVersion(name)}`\n versionCache.set(name, resolvedVersion)\n }\n\n results.push([name, resolvedVersion])\n }\n\n return Object.fromEntries(results)\n}\n",
7
+ "import type { PackageConfig, StandardPackageJson } from '../schemas/package'\n\n// Deep merge two objects, with source overriding target\nexport function deepMerge<T extends Record<string, unknown>>(\n target: T,\n source: Partial<T>\n): T {\n const result = { ...target }\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceValue = source[key]\n const targetValue = target[key]\n\n if (sourceValue === undefined) continue\n\n if (\n typeof sourceValue === 'object' &&\n sourceValue !== null &&\n !Array.isArray(sourceValue) &&\n typeof targetValue === 'object' &&\n targetValue !== null &&\n !Array.isArray(targetValue)\n ) {\n result[key] = deepMerge(\n targetValue as Record<string, unknown>,\n sourceValue as Record<string, unknown>\n ) as T[keyof T]\n } else {\n result[key] = sourceValue as T[keyof T]\n }\n }\n\n return result\n}\n\n// Merge arrays (for dependencies)\nexport function mergeArrays<T>(\n target: T[] | undefined,\n source: T[] | undefined\n): T[] {\n return [...(target ?? []), ...(source ?? [])]\n}\n\n// Resolve extends chain\nexport async function resolveExtends(\n config: PackageConfig\n): Promise<PackageConfig> {\n if (!config.extends) {\n return config\n }\n\n let baseConfig: PackageConfig\n\n if (typeof config.extends === 'string') {\n // Import from file path\n const imported = await import(config.extends)\n baseConfig = imported.default ?? imported\n } else {\n baseConfig = config.extends\n }\n\n // Recursively resolve base config's extends\n baseConfig = await resolveExtends(baseConfig)\n\n // Merge base into current (current overrides base)\n const { extends: _, ...currentWithoutExtends } = config\n\n return {\n ...baseConfig,\n ...currentWithoutExtends,\n // Merge arrays for dependencies\n dependencies: mergeArrays(\n baseConfig.dependencies,\n currentWithoutExtends.dependencies\n ),\n devDependencies: mergeArrays(\n baseConfig.devDependencies,\n currentWithoutExtends.devDependencies\n ),\n peerDependencies: mergeArrays(\n baseConfig.peerDependencies,\n currentWithoutExtends.peerDependencies\n ),\n // Merge objects for scripts\n scripts: { ...baseConfig.scripts, ...currentWithoutExtends.scripts },\n scriptPresets: [\n ...(baseConfig.scriptPresets ?? []),\n ...(currentWithoutExtends.scriptPresets ?? []),\n ],\n }\n}\n",
8
+ "import type { ConditionalConfig, StandardPackageJson } from '../schemas/package'\nimport { deepMerge } from './merge'\n\ninterface ConditionContext {\n env: string\n platform: NodeJS.Platform\n nodeVersion: string\n ci: boolean\n}\n\nfunction getContext(): ConditionContext {\n return {\n env: process.env.NODE_ENV ?? 'development',\n platform: process.platform,\n nodeVersion: process.version,\n ci: process.env.CI === 'true' || process.env.CI === '1',\n }\n}\n\nfunction evaluateCondition(\n when: ConditionalConfig['when'],\n context: ConditionContext\n): boolean {\n if (when.env !== undefined && context.env !== when.env) {\n return false\n }\n\n if (when.platform !== undefined && context.platform !== when.platform) {\n return false\n }\n\n if (when.ci !== undefined && context.ci !== when.ci) {\n return false\n }\n\n if (when.nodeVersion !== undefined) {\n // Simple semver check (starts with)\n if (!context.nodeVersion.startsWith(when.nodeVersion)) {\n return false\n }\n }\n\n return true\n}\n\nexport function applyConditions(\n baseConfig: Partial<StandardPackageJson>,\n conditions: ConditionalConfig[] | undefined\n): Partial<StandardPackageJson> {\n if (!conditions || conditions.length === 0) {\n return baseConfig\n }\n\n const context = getContext()\n let result = { ...baseConfig }\n\n for (const condition of conditions) {\n if (evaluateCondition(condition.when, context)) {\n result = deepMerge(\n result,\n condition.set as Record<string, unknown>\n ) as Partial<StandardPackageJson>\n }\n }\n\n return result\n}\n",
9
+ "import type { PackageConfig, StandardPackageJson } from '../schemas/package'\nimport { getPresetScripts, mergeScripts } from '../presets/scripts'\nimport { resolveDependenciesCached } from '../resolvers/dependencies'\nimport { resolveExtends } from '../utils/merge'\nimport { applyConditions } from '../utils/conditions'\n\nexport interface GenerateOptions {\n indent?: number\n outputPath?: string\n}\n\nexport async function createPackageJson(\n config: PackageConfig,\n options: GenerateOptions = {}\n): Promise<string> {\n const { indent = 2 } = options\n\n // Step 1: Resolve extends chain\n let resolved = await resolveExtends(config)\n\n // Step 2: Build scripts from presets + custom\n const presetScripts = resolved.scriptPresets\n ? getPresetScripts(resolved.scriptPresets)\n : {}\n const finalScripts = mergeScripts(presetScripts, resolved.scripts)\n\n // Step 3: Resolve dependency versions\n const [dependencies, devDependencies, peerDependencies] = await Promise.all([\n resolveDependenciesCached(resolved.dependencies),\n resolveDependenciesCached(resolved.devDependencies),\n resolveDependenciesCached(resolved.peerDependencies),\n ])\n\n // Step 4: Build standard package.json\n const packageJson: StandardPackageJson = {\n name: resolved.name,\n ...(resolved.version && { version: resolved.version }),\n ...(resolved.description && { description: resolved.description }),\n ...(resolved.keywords?.length && { keywords: resolved.keywords }),\n ...(resolved.homepage && { homepage: resolved.homepage }),\n ...(resolved.bugs && { bugs: resolved.bugs }),\n ...(resolved.license && { license: resolved.license }),\n ...(resolved.author && { author: resolved.author }),\n ...(resolved.contributors?.length && {\n contributors: resolved.contributors,\n }),\n ...(resolved.repository && { repository: resolved.repository }),\n ...(resolved.type && { type: resolved.type }),\n ...(resolved.main && { main: resolved.main }),\n ...(resolved.module && { module: resolved.module }),\n ...(resolved.types && { types: resolved.types }),\n ...(resolved.exports && { exports: resolved.exports }),\n ...(resolved.bin && { bin: resolved.bin }),\n ...(resolved.files?.length && { files: resolved.files }),\n ...(Object.keys(finalScripts).length && { scripts: finalScripts }),\n ...(Object.keys(dependencies).length && { dependencies }),\n ...(Object.keys(devDependencies).length && { devDependencies }),\n ...(Object.keys(peerDependencies).length && { peerDependencies }),\n ...(resolved.optionalDependencies && {\n optionalDependencies: resolved.optionalDependencies,\n }),\n ...(resolved.engines && { engines: resolved.engines }),\n ...(resolved.os?.length && { os: resolved.os }),\n ...(resolved.cpu?.length && { cpu: resolved.cpu }),\n ...(resolved.private !== undefined && { private: resolved.private }),\n ...(resolved.publishConfig && { publishConfig: resolved.publishConfig }),\n ...(resolved.workspaces?.length && { workspaces: resolved.workspaces }),\n }\n\n // Step 5: Apply conditional configs\n const finalPackageJson = applyConditions(packageJson, resolved.conditions)\n\n return JSON.stringify(finalPackageJson, null, indent)\n}\n\nexport async function writePackageJson(\n config: PackageConfig,\n options: GenerateOptions = {}\n): Promise<void> {\n const { outputPath = 'package.json' } = options\n const json = await createPackageJson(config, options)\n await Bun.write(outputPath, json + '\\n')\n console.log(`✨ Generated ${outputPath}`)\n}\n",
10
+ "import type {\n PackageConfig,\n StandardPackageJson,\n ScriptPreset,\n DependencyInput,\n ConditionalConfig,\n License,\n} from './schemas/package'\nimport {\n createPackageJson,\n writePackageJson,\n type GenerateOptions,\n} from './generator/createPackageJson'\n\nexport function definePackageConfig(config: PackageConfig): PackageConfig {\n return config\n}\n\n// Run CLI if executed directly\nasync function main() {\n const configPath = process.argv[2] ?? 'package.config.ts'\n const outputPath = process.argv[3] ?? 'package.json'\n\n try {\n const configModule = await import(Bun.pathToFileURL(configPath).href)\n const config: PackageConfig = configModule.default ?? configModule\n\n await writePackageJson(config, { outputPath })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ERR_MODULE_NOT_FOUND') {\n console.error(`❌ Config file not found: ${configPath}`)\n console.error('\\nCreate a package.config.ts file with:')\n console.error(`\nimport { definePackageConfig } from './src/main'\n\nexport default definePackageConfig({\n name: 'my-package',\n version: '1.0.0',\n scriptPresets: ['typescript', 'testing'],\n dependencies: ['lodash', 'zod'],\n devDependencies: ['typescript', 'vitest'],\n})\n`)\n process.exit(1)\n }\n throw error\n }\n}\n\n// Export everything\nexport {\n createPackageJson,\n writePackageJson,\n type PackageConfig,\n type StandardPackageJson,\n type ScriptPreset,\n type DependencyInput,\n type ConditionalConfig,\n type GenerateOptions,\n type License,\n}\n\n// Run if main module\nif (import.meta.main) {\n main()\n}\n"
11
+ ],
12
+ "mappings": "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",
13
+ "debugId": "B903D397D524CA2964756E2164756E21",
14
+ "names": []
15
+ }
@@ -0,0 +1,58 @@
1
+ import { definePackageConfig } from '@/main.ts'
2
+
3
+ export default definePackageConfig({
4
+ name: '@a35hie/ts-pkg',
5
+ version: '0.1.0',
6
+ description: 'TypeScript-based package.json with magical features',
7
+ type: 'module',
8
+ license: 'Apache-2.0',
9
+ repository: 'https://github.com/a35hie/TsPkg',
10
+
11
+ // Entry points
12
+ main: 'dist/main.js',
13
+ module: 'dist/main.js',
14
+ types: 'dist/main.d.ts',
15
+ bin: {
16
+ 'ts-pkg': './dist/main.js',
17
+ },
18
+
19
+ // Script presets auto-generate common scripts
20
+ scriptPresets: ['typescript', 'prettier', 'testing'],
21
+
22
+ // Custom scripts (merged with presets, overrides if same name)
23
+ scripts: {
24
+ generate: 'bun run src/main.ts',
25
+ },
26
+
27
+ // Just list package names - versions auto-resolved!
28
+ dependencies: [],
29
+
30
+ devDependencies: ['typescript', 'prettier', '@types/bun'],
31
+
32
+ peerDependencies: [
33
+ 'typescript@^5', // Can specify version constraints
34
+ ],
35
+
36
+ // Conditional configuration based on environment
37
+ conditions: [
38
+ {
39
+ when: { env: 'production' },
40
+ set: {
41
+ private: false,
42
+ },
43
+ },
44
+ {
45
+ when: { ci: true },
46
+ set: {
47
+ scripts: {
48
+ test: 'vitest run --reporter=verbose',
49
+ },
50
+ },
51
+ },
52
+ ],
53
+
54
+ engines: {
55
+ node: '>=18',
56
+ bun: '>=1.0',
57
+ },
58
+ })
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@a35hie/ts-pkg",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript-based package.json with magical features",
5
+ "license": "Apache-2.0",
6
+ "repository": "https://github.com/a35hie/TsPkg",
7
+ "type": "module",
8
+ "main": "dist/main.js",
9
+ "module": "dist/main.js",
10
+ "types": "dist/main.d.ts",
11
+ "bin": {
12
+ "ts-pkg": "./dist/main.js"
13
+ },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "build:watch": "tsc --watch",
17
+ "typecheck": "tsc --noEmit",
18
+ "format": "prettier --write .",
19
+ "format:check": "prettier --check .",
20
+ "test": "vitest",
21
+ "test:watch": "vitest watch",
22
+ "test:coverage": "vitest --coverage",
23
+ "generate": "bun run src/main.ts"
24
+ },
25
+ "devDependencies": {
26
+ "typescript": "^5.9.3",
27
+ "prettier": "^3.8.1",
28
+ "@types/bun": "^1.3.8"
29
+ },
30
+ "peerDependencies": {
31
+ "typescript": "^5"
32
+ },
33
+ "engines": {
34
+ "node": ">=18",
35
+ "bun": ">=1.0"
36
+ }
37
+ }
@@ -0,0 +1,84 @@
1
+ import type { PackageConfig, StandardPackageJson } from '../schemas/package'
2
+ import { getPresetScripts, mergeScripts } from '../presets/scripts'
3
+ import { resolveDependenciesCached } from '../resolvers/dependencies'
4
+ import { resolveExtends } from '../utils/merge'
5
+ import { applyConditions } from '../utils/conditions'
6
+
7
+ export interface GenerateOptions {
8
+ indent?: number
9
+ outputPath?: string
10
+ }
11
+
12
+ export async function createPackageJson(
13
+ config: PackageConfig,
14
+ options: GenerateOptions = {}
15
+ ): Promise<string> {
16
+ const { indent = 2 } = options
17
+
18
+ // Step 1: Resolve extends chain
19
+ let resolved = await resolveExtends(config)
20
+
21
+ // Step 2: Build scripts from presets + custom
22
+ const presetScripts = resolved.scriptPresets
23
+ ? getPresetScripts(resolved.scriptPresets)
24
+ : {}
25
+ const finalScripts = mergeScripts(presetScripts, resolved.scripts)
26
+
27
+ // Step 3: Resolve dependency versions
28
+ const [dependencies, devDependencies, peerDependencies] = await Promise.all([
29
+ resolveDependenciesCached(resolved.dependencies),
30
+ resolveDependenciesCached(resolved.devDependencies),
31
+ resolveDependenciesCached(resolved.peerDependencies),
32
+ ])
33
+
34
+ // Step 4: Build standard package.json
35
+ const packageJson: StandardPackageJson = {
36
+ name: resolved.name,
37
+ ...(resolved.version && { version: resolved.version }),
38
+ ...(resolved.description && { description: resolved.description }),
39
+ ...(resolved.keywords?.length && { keywords: resolved.keywords }),
40
+ ...(resolved.homepage && { homepage: resolved.homepage }),
41
+ ...(resolved.bugs && { bugs: resolved.bugs }),
42
+ ...(resolved.license && { license: resolved.license }),
43
+ ...(resolved.author && { author: resolved.author }),
44
+ ...(resolved.contributors?.length && {
45
+ contributors: resolved.contributors,
46
+ }),
47
+ ...(resolved.repository && { repository: resolved.repository }),
48
+ ...(resolved.type && { type: resolved.type }),
49
+ ...(resolved.main && { main: resolved.main }),
50
+ ...(resolved.module && { module: resolved.module }),
51
+ ...(resolved.types && { types: resolved.types }),
52
+ ...(resolved.exports && { exports: resolved.exports }),
53
+ ...(resolved.bin && { bin: resolved.bin }),
54
+ ...(resolved.files?.length && { files: resolved.files }),
55
+ ...(Object.keys(finalScripts).length && { scripts: finalScripts }),
56
+ ...(Object.keys(dependencies).length && { dependencies }),
57
+ ...(Object.keys(devDependencies).length && { devDependencies }),
58
+ ...(Object.keys(peerDependencies).length && { peerDependencies }),
59
+ ...(resolved.optionalDependencies && {
60
+ optionalDependencies: resolved.optionalDependencies,
61
+ }),
62
+ ...(resolved.engines && { engines: resolved.engines }),
63
+ ...(resolved.os?.length && { os: resolved.os }),
64
+ ...(resolved.cpu?.length && { cpu: resolved.cpu }),
65
+ ...(resolved.private !== undefined && { private: resolved.private }),
66
+ ...(resolved.publishConfig && { publishConfig: resolved.publishConfig }),
67
+ ...(resolved.workspaces?.length && { workspaces: resolved.workspaces }),
68
+ }
69
+
70
+ // Step 5: Apply conditional configs
71
+ const finalPackageJson = applyConditions(packageJson, resolved.conditions)
72
+
73
+ return JSON.stringify(finalPackageJson, null, indent)
74
+ }
75
+
76
+ export async function writePackageJson(
77
+ config: PackageConfig,
78
+ options: GenerateOptions = {}
79
+ ): Promise<void> {
80
+ const { outputPath = 'package.json' } = options
81
+ const json = await createPackageJson(config, options)
82
+ await Bun.write(outputPath, json + '\n')
83
+ console.log(`✨ Generated ${outputPath}`)
84
+ }