@a35hie/ts-pkg 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # ts-pkg-config
1
+ # TS Package Config
2
2
 
3
3
  ✨ TypeScript-based `package.json` with magical features.
4
4
 
@@ -70,9 +70,9 @@ export default definePackageConfig({
70
70
  Generate your `package.json`:
71
71
 
72
72
  ```bash
73
- bun run ts-pkg-config
73
+ bunx ts-pkg
74
74
  # or
75
- bun run src/main.ts package.config.ts package.json
75
+ bunx ts-pkg package.config.ts package.json
76
76
  ```
77
77
 
78
78
  ## Script Presets
package/build.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import dts from 'bun-plugin-dts'
2
2
 
3
+ // Build library
3
4
  await Bun.build({
4
5
  entrypoints: ['./src/main.ts'],
5
6
  outdir: './dist',
@@ -11,4 +12,15 @@ await Bun.build({
11
12
  plugins: [dts()],
12
13
  })
13
14
 
15
+ // Build CLI
16
+ await Bun.build({
17
+ entrypoints: ['./src/cli.ts'],
18
+ outdir: './dist',
19
+ format: 'esm',
20
+ target: 'node',
21
+ splitting: false,
22
+ minify: false,
23
+ banner: '#!/usr/bin/env bun',
24
+ })
25
+
14
26
  console.log('✨ Build complete')
package/dist/cli.js ADDED
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env bun
2
+ import { createRequire } from "node:module";
3
+ var __create = Object.create;
4
+ var __getProtoOf = Object.getPrototypeOf;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __toESM = (mod, isNodeMode, target) => {
9
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
10
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
+ for (let key of __getOwnPropNames(mod))
12
+ if (!__hasOwnProp.call(to, key))
13
+ __defProp(to, key, {
14
+ get: () => mod[key],
15
+ enumerable: true
16
+ });
17
+ return to;
18
+ };
19
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
+
21
+ // src/presets/scripts.ts
22
+ var scriptPresets = {
23
+ typescript: {
24
+ build: "tsc",
25
+ "build:watch": "tsc --watch",
26
+ typecheck: "tsc --noEmit"
27
+ },
28
+ react: {
29
+ dev: "vite",
30
+ build: "vite build",
31
+ preview: "vite preview"
32
+ },
33
+ node: {
34
+ start: "node dist/index.js",
35
+ dev: "tsx watch src/index.ts",
36
+ build: "tsup src/index.ts --format esm,cjs --dts"
37
+ },
38
+ testing: {
39
+ test: "vitest",
40
+ "test:watch": "vitest watch",
41
+ "test:coverage": "vitest --coverage"
42
+ },
43
+ prettier: {
44
+ format: "prettier --write .",
45
+ "format:check": "prettier --check ."
46
+ },
47
+ eslint: {
48
+ lint: "eslint .",
49
+ "lint:fix": "eslint . --fix"
50
+ }
51
+ };
52
+ function getPresetScripts(presets) {
53
+ const merged = {};
54
+ for (const preset of presets) {
55
+ const scripts = scriptPresets[preset];
56
+ if (scripts) {
57
+ Object.assign(merged, scripts);
58
+ }
59
+ }
60
+ return merged;
61
+ }
62
+ function mergeScripts(presetScripts, customScripts) {
63
+ return { ...presetScripts, ...customScripts };
64
+ }
65
+
66
+ // src/resolvers/dependencies.ts
67
+ function parseDependency(dep) {
68
+ if (typeof dep === "string") {
69
+ const atIndex = dep.lastIndexOf("@");
70
+ if (atIndex > 0) {
71
+ return {
72
+ name: dep.slice(0, atIndex),
73
+ version: dep.slice(atIndex + 1)
74
+ };
75
+ }
76
+ return { name: dep };
77
+ }
78
+ const [name, version] = Object.entries(dep)[0];
79
+ return { name, version };
80
+ }
81
+ async function fetchLatestVersion(packageName) {
82
+ const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}`;
83
+ const response = await fetch(url, {
84
+ headers: { Accept: "application/json" }
85
+ });
86
+ if (!response.ok) {
87
+ throw new Error(`Failed to fetch ${packageName}: ${response.statusText}`);
88
+ }
89
+ const data = await response.json();
90
+ return data["dist-tags"].latest;
91
+ }
92
+ var versionCache = new Map;
93
+ async function resolveDependenciesCached(deps) {
94
+ if (!deps) {
95
+ return {};
96
+ }
97
+ if (!Array.isArray(deps)) {
98
+ return deps;
99
+ }
100
+ if (deps.length === 0) {
101
+ return {};
102
+ }
103
+ const results = [];
104
+ for (const dep of deps) {
105
+ const { name, version } = parseDependency(dep);
106
+ if (version) {
107
+ results.push([name, version]);
108
+ continue;
109
+ }
110
+ let resolvedVersion = versionCache.get(name);
111
+ if (!resolvedVersion) {
112
+ resolvedVersion = `^${await fetchLatestVersion(name)}`;
113
+ versionCache.set(name, resolvedVersion);
114
+ }
115
+ results.push([name, resolvedVersion]);
116
+ }
117
+ return Object.fromEntries(results);
118
+ }
119
+
120
+ // src/utils/merge.ts
121
+ function deepMerge(target, source) {
122
+ const result = { ...target };
123
+ for (const key of Object.keys(source)) {
124
+ const sourceValue = source[key];
125
+ const targetValue = target[key];
126
+ if (sourceValue === undefined)
127
+ continue;
128
+ if (typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue) && typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue)) {
129
+ result[key] = deepMerge(targetValue, sourceValue);
130
+ } else {
131
+ result[key] = sourceValue;
132
+ }
133
+ }
134
+ return result;
135
+ }
136
+ function mergeDependencies(target, source) {
137
+ if (!target && !source)
138
+ return;
139
+ if (!target)
140
+ return source;
141
+ if (!source)
142
+ return target;
143
+ if (Array.isArray(target) && Array.isArray(source)) {
144
+ return [...target, ...source];
145
+ }
146
+ if (!Array.isArray(target) && !Array.isArray(source)) {
147
+ return { ...target, ...source };
148
+ }
149
+ const targetObj = Array.isArray(target) ? {} : target;
150
+ const sourceObj = Array.isArray(source) ? {} : source;
151
+ const targetArr = Array.isArray(target) ? target : [];
152
+ const sourceArr = Array.isArray(source) ? source : [];
153
+ return [...targetArr, ...sourceArr, { ...targetObj, ...sourceObj }];
154
+ }
155
+ async function resolveExtends(config) {
156
+ if (!config.extends) {
157
+ return config;
158
+ }
159
+ let baseConfig;
160
+ if (typeof config.extends === "string") {
161
+ const imported = await import(config.extends);
162
+ baseConfig = imported.default ?? imported;
163
+ } else {
164
+ baseConfig = config.extends;
165
+ }
166
+ baseConfig = await resolveExtends(baseConfig);
167
+ const { extends: _, ...currentWithoutExtends } = config;
168
+ return {
169
+ ...baseConfig,
170
+ ...currentWithoutExtends,
171
+ dependencies: mergeDependencies(baseConfig.dependencies, currentWithoutExtends.dependencies),
172
+ devDependencies: mergeDependencies(baseConfig.devDependencies, currentWithoutExtends.devDependencies),
173
+ peerDependencies: mergeDependencies(baseConfig.peerDependencies, currentWithoutExtends.peerDependencies),
174
+ scripts: { ...baseConfig.scripts, ...currentWithoutExtends.scripts },
175
+ scriptPresets: [
176
+ ...baseConfig.scriptPresets ?? [],
177
+ ...currentWithoutExtends.scriptPresets ?? []
178
+ ]
179
+ };
180
+ }
181
+
182
+ // src/utils/conditions.ts
183
+ function getContext() {
184
+ return {
185
+ env: "development",
186
+ platform: process.platform,
187
+ nodeVersion: process.version,
188
+ ci: process.env.CI === "true" || process.env.CI === "1"
189
+ };
190
+ }
191
+ function evaluateCondition(when, context) {
192
+ if (when.env !== undefined && context.env !== when.env) {
193
+ return false;
194
+ }
195
+ if (when.platform !== undefined && context.platform !== when.platform) {
196
+ return false;
197
+ }
198
+ if (when.ci !== undefined && context.ci !== when.ci) {
199
+ return false;
200
+ }
201
+ if (when.nodeVersion !== undefined) {
202
+ if (!context.nodeVersion.startsWith(when.nodeVersion)) {
203
+ return false;
204
+ }
205
+ }
206
+ return true;
207
+ }
208
+ function applyConditions(baseConfig, conditions) {
209
+ if (!conditions || conditions.length === 0) {
210
+ return baseConfig;
211
+ }
212
+ const context = getContext();
213
+ let result = { ...baseConfig };
214
+ for (const condition of conditions) {
215
+ if (evaluateCondition(condition.when, context)) {
216
+ result = deepMerge(result, condition.set);
217
+ }
218
+ }
219
+ return result;
220
+ }
221
+
222
+ // src/generator/createPackageJson.ts
223
+ async function createPackageJson(config, options = {}) {
224
+ const { indent = 2 } = options;
225
+ let resolved = await resolveExtends(config);
226
+ const presetScripts = resolved.scriptPresets ? getPresetScripts(resolved.scriptPresets) : {};
227
+ const finalScripts = mergeScripts(presetScripts, resolved.scripts);
228
+ const [dependencies, devDependencies, peerDependencies] = await Promise.all([
229
+ resolveDependenciesCached(resolved.dependencies),
230
+ resolveDependenciesCached(resolved.devDependencies),
231
+ resolveDependenciesCached(resolved.peerDependencies)
232
+ ]);
233
+ const packageJson = {
234
+ name: resolved.name,
235
+ ...resolved.version && { version: resolved.version },
236
+ ...resolved.description && { description: resolved.description },
237
+ ...resolved.keywords?.length && { keywords: resolved.keywords },
238
+ ...resolved.homepage && { homepage: resolved.homepage },
239
+ ...resolved.bugs && { bugs: resolved.bugs },
240
+ ...resolved.license && { license: resolved.license },
241
+ ...resolved.author && { author: resolved.author },
242
+ ...resolved.contributors?.length && {
243
+ contributors: resolved.contributors
244
+ },
245
+ ...resolved.repository && { repository: resolved.repository },
246
+ ...resolved.type && { type: resolved.type },
247
+ ...resolved.main && { main: resolved.main },
248
+ ...resolved.module && { module: resolved.module },
249
+ ...resolved.types && { types: resolved.types },
250
+ ...resolved.exports && { exports: resolved.exports },
251
+ ...resolved.bin && { bin: resolved.bin },
252
+ ...resolved.files?.length && { files: resolved.files },
253
+ ...Object.keys(finalScripts).length && { scripts: finalScripts },
254
+ ...Object.keys(dependencies).length && { dependencies },
255
+ ...Object.keys(devDependencies).length && { devDependencies },
256
+ ...Object.keys(peerDependencies).length && { peerDependencies },
257
+ ...resolved.optionalDependencies && {
258
+ optionalDependencies: resolved.optionalDependencies
259
+ },
260
+ ...resolved.engines && { engines: resolved.engines },
261
+ ...resolved.os?.length && { os: resolved.os },
262
+ ...resolved.cpu?.length && { cpu: resolved.cpu },
263
+ ...resolved.private !== undefined && { private: resolved.private },
264
+ ...resolved.publishConfig && { publishConfig: resolved.publishConfig },
265
+ ...resolved.workspaces?.length && { workspaces: resolved.workspaces }
266
+ };
267
+ const finalPackageJson = applyConditions(packageJson, resolved.conditions);
268
+ return JSON.stringify(finalPackageJson, null, indent);
269
+ }
270
+ async function writePackageJson(config, options = {}) {
271
+ const { outputPath = "package.json" } = options;
272
+ const json = await createPackageJson(config, options);
273
+ const { writeFile } = await import("node:fs/promises");
274
+ await writeFile(outputPath, json + `
275
+ `);
276
+ console.log(`✨ Generated ${outputPath}`);
277
+ }
278
+
279
+ // src/cli.ts
280
+ import { resolve } from "node:path";
281
+ import { pathToFileURL } from "node:url";
282
+ async function main() {
283
+ const configPath = process.argv[2] ?? "package.config.ts";
284
+ const outputPath = process.argv[3] ?? "package.json";
285
+ const absoluteConfigPath = resolve(process.cwd(), configPath);
286
+ try {
287
+ const configModule = await import(pathToFileURL(absoluteConfigPath).href);
288
+ const config = configModule.default ?? configModule;
289
+ await writePackageJson(config, { outputPath });
290
+ } catch (error) {
291
+ const err = error;
292
+ if (err.code === "ERR_MODULE_NOT_FOUND" || err.code === "ENOENT") {
293
+ console.error(`❌ Config file not found: ${configPath}`);
294
+ console.error(`
295
+ Create a package.config.ts file with:`);
296
+ console.error(`
297
+ import { definePackageConfig } from '@a35hie/ts-pkg'
298
+
299
+ export default definePackageConfig({
300
+ name: 'my-package',
301
+ version: '1.0.0',
302
+ scriptPresets: ['typescript', 'testing'],
303
+ dependencies: ['lodash', 'zod'],
304
+ devDependencies: ['typescript', 'vitest'],
305
+ })
306
+ `);
307
+ process.exit(1);
308
+ }
309
+ console.error("❌ Error:", err.message);
310
+ process.exit(1);
311
+ }
312
+ }
313
+ main();
package/dist/main.d.ts CHANGED
@@ -1,147 +1,87 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
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 & {})
3
+ export type License = "MIT" | "Apache-2.0" | "GPL-2.0-only" | "GPL-2.0-or-later" | "GPL-3.0-only" | "GPL-3.0-or-later" | "LGPL-2.1-only" | "LGPL-2.1-or-later" | "LGPL-3.0-only" | "LGPL-3.0-or-later" | "BSD-2-Clause" | "BSD-3-Clause" | "ISC" | "MPL-2.0" | "AGPL-3.0-only" | "AGPL-3.0-or-later" | "Unlicense" | "WTFPL" | "CC0-1.0" | "CC-BY-4.0" | "CC-BY-SA-4.0" | "Zlib" | "BSL-1.0" | "EPL-2.0" | "EUPL-1.2" | "CDDL-1.0" | "Artistic-2.0" | "OSL-3.0" | "AFL-3.0" | "LPPL-1.3c" | (string & {});
35
4
  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'
5
+ name: string;
6
+ version?: string;
7
+ description?: string;
8
+ keywords?: string[];
9
+ homepage?: string;
10
+ bugs?: string | {
11
+ url?: string;
12
+ email?: string;
13
+ };
14
+ license?: License;
15
+ author?: string | {
16
+ name: string;
17
+ email?: string;
18
+ url?: string;
19
+ };
20
+ contributors?: (string | {
21
+ name: string;
22
+ email?: string;
23
+ url?: string;
24
+ })[];
25
+ repository?: string | {
26
+ type: string;
27
+ url: string;
28
+ directory?: string;
29
+ };
30
+ main?: string;
31
+ module?: string;
32
+ types?: string;
33
+ exports?: Record<string, string | {
34
+ import?: string;
35
+ require?: string;
36
+ types?: string;
37
+ }>;
38
+ bin?: string | Record<string, string>;
39
+ files?: string[];
40
+ scripts?: Record<string, string>;
41
+ dependencies?: Record<string, string>;
42
+ devDependencies?: Record<string, string>;
43
+ peerDependencies?: Record<string, string>;
44
+ optionalDependencies?: Record<string, string>;
45
+ engines?: Record<string, string>;
46
+ os?: string[];
47
+ cpu?: string[];
48
+ private?: boolean;
49
+ publishConfig?: Record<string, unknown>;
50
+ workspaces?: string[];
51
+ type?: "module" | "commonjs";
96
52
  }
97
- export type ScriptPreset =
98
- | 'typescript'
99
- | 'react'
100
- | 'node'
101
- | 'testing'
102
- | 'prettier'
103
- | 'eslint'
104
- export type DependencyInput = string | Record<string, string>
53
+ export type ScriptPreset = "typescript" | "react" | "node" | "testing" | "prettier" | "eslint";
54
+ export type DependencyInput = string | Record<string, string>;
55
+ export type DependenciesInput = DependencyInput[] | Record<string, string>;
105
56
  export interface ConditionalConfig {
106
- when: {
107
- env?: string
108
- platform?: NodeJS.Platform
109
- nodeVersion?: string
110
- ci?: boolean
111
- }
112
- set: Partial<StandardPackageJson>
57
+ when: {
58
+ env?: string;
59
+ platform?: NodeJS.Platform;
60
+ nodeVersion?: string;
61
+ ci?: boolean;
62
+ };
63
+ set: Partial<StandardPackageJson>;
113
64
  }
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
- }
65
+ export interface PackageConfig extends Omit<StandardPackageJson, "scripts" | "dependencies" | "devDependencies" | "peerDependencies"> {
66
+ extends?: string | PackageConfig;
67
+ scriptPresets?: ScriptPreset[];
68
+ scripts?: Record<string, string>;
69
+ dependencies?: DependenciesInput;
70
+ devDependencies?: DependenciesInput;
71
+ peerDependencies?: DependenciesInput;
72
+ conditions?: ConditionalConfig[];
73
+ autoInfer?: {
74
+ version?: boolean;
75
+ repository?: boolean;
76
+ author?: boolean;
77
+ };
130
78
  }
131
79
  export interface GenerateOptions {
132
- indent?: number
133
- outputPath?: string
80
+ indent?: number;
81
+ outputPath?: string;
134
82
  }
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
83
+ export declare function createPackageJson(config: PackageConfig, options?: GenerateOptions): Promise<string>;
84
+ export declare function writePackageJson(config: PackageConfig, options?: GenerateOptions): Promise<void>;
85
+ export declare function definePackageConfig(config: PackageConfig): PackageConfig;
146
86
 
147
- export {}
87
+ export {};