create-gen-app 0.2.1 → 0.2.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.
Files changed (47) hide show
  1. package/README.md +73 -49
  2. package/cache/cache-manager.d.ts +60 -0
  3. package/cache/cache-manager.js +228 -0
  4. package/cache/types.d.ts +22 -0
  5. package/cache/types.js +2 -0
  6. package/esm/cache/cache-manager.js +191 -0
  7. package/esm/cache/types.js +1 -0
  8. package/esm/git/git-cloner.js +92 -0
  9. package/esm/git/types.js +1 -0
  10. package/esm/index.js +26 -53
  11. package/esm/{replace.js → template/replace.js} +2 -2
  12. package/esm/template/templatizer.js +69 -0
  13. package/esm/template/types.js +1 -0
  14. package/esm/utils/npm-version-check.js +52 -0
  15. package/esm/utils/types.js +1 -0
  16. package/git/git-cloner.d.ts +32 -0
  17. package/git/git-cloner.js +129 -0
  18. package/git/types.d.ts +15 -0
  19. package/git/types.js +2 -0
  20. package/index.d.ts +19 -6
  21. package/index.js +27 -75
  22. package/package.json +5 -5
  23. package/{extract.d.ts → template/extract.d.ts} +1 -1
  24. package/{prompt.d.ts → template/prompt.d.ts} +1 -1
  25. package/{replace.d.ts → template/replace.d.ts} +1 -1
  26. package/{replace.js → template/replace.js} +2 -2
  27. package/template/templatizer.d.ts +29 -0
  28. package/template/templatizer.js +106 -0
  29. package/template/types.d.ts +11 -0
  30. package/template/types.js +2 -0
  31. package/utils/npm-version-check.d.ts +17 -0
  32. package/utils/npm-version-check.js +57 -0
  33. package/utils/types.d.ts +6 -0
  34. package/utils/types.js +2 -0
  35. package/cache.d.ts +0 -13
  36. package/cache.js +0 -76
  37. package/clone.d.ts +0 -15
  38. package/clone.js +0 -86
  39. package/esm/cache.js +0 -38
  40. package/esm/clone.js +0 -49
  41. package/esm/template-cache.js +0 -223
  42. package/template-cache.d.ts +0 -59
  43. package/template-cache.js +0 -260
  44. /package/esm/{extract.js → template/extract.js} +0 -0
  45. /package/esm/{prompt.js → template/prompt.js} +0 -0
  46. /package/{extract.js → template/extract.js} +0 -0
  47. /package/{prompt.js → template/prompt.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-gen-app",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "author": "Dan Lynch <pyramation@gmail.com>",
5
5
  "description": "Clone and customize template repositories with variable replacement",
6
6
  "main": "index.js",
@@ -28,13 +28,13 @@
28
28
  "test:watch": "jest --watch"
29
29
  },
30
30
  "dependencies": {
31
- "appstash": "0.2.3",
32
- "inquirerer": "2.1.8"
31
+ "appstash": "0.2.4",
32
+ "inquirerer": "2.1.9"
33
33
  },
34
34
  "devDependencies": {
35
35
  "copyfiles": "^2.4.1",
36
- "makage": "0.1.6"
36
+ "makage": "0.1.8"
37
37
  },
38
38
  "keywords": [],
39
- "gitHead": "d0068bfc4eb3bd041e3ce97d9e4da2fba7c5f84a"
39
+ "gitHead": "872fb2ae9f7e3d541e94271c26099bd85d5237d2"
40
40
  }
@@ -1,4 +1,4 @@
1
- import { ExtractedVariables } from "./types";
1
+ import { ExtractedVariables } from "../types";
2
2
  /**
3
3
  * Extract all variables from a template directory
4
4
  * @param templateDir - Path to the template directory
@@ -1,5 +1,5 @@
1
1
  import { Question } from "inquirerer";
2
- import { ExtractedVariables } from "./types";
2
+ import { ExtractedVariables } from "../types";
3
3
  /**
4
4
  * Generate questions from extracted variables
5
5
  * @param extractedVariables - Variables extracted from the template
@@ -1,4 +1,4 @@
1
- import { ExtractedVariables } from './types';
1
+ import { ExtractedVariables } from '../types';
2
2
  /**
3
3
  * Replace variables in all files in the template directory
4
4
  * @param templateDir - Path to the template directory
@@ -38,7 +38,7 @@ const fs = __importStar(require("fs"));
38
38
  const path = __importStar(require("path"));
39
39
  const stream_1 = require("stream");
40
40
  const promises_1 = require("stream/promises");
41
- const licenses_1 = require("./licenses");
41
+ const licenses_1 = require("../licenses");
42
42
  /**
43
43
  * Replace variables in all files in the template directory
44
44
  * @param templateDir - Path to the template directory
@@ -143,7 +143,7 @@ async function replaceInFile(sourcePath, destPath, extractedVariables, answers)
143
143
  fs.mkdirSync(destDir, { recursive: true });
144
144
  }
145
145
  const replaceTransform = new stream_1.Transform({
146
- transform(chunk, encoding, callback) {
146
+ transform(chunk, _encoding, callback) {
147
147
  let content = chunk.toString();
148
148
  for (const replacer of extractedVariables.contentReplacers) {
149
149
  if (answers[replacer.variable] !== undefined) {
@@ -0,0 +1,29 @@
1
+ import { ExtractedVariables } from '../types';
2
+ import { ProcessOptions, TemplatizerResult } from './types';
3
+ export declare class Templatizer {
4
+ constructor();
5
+ /**
6
+ * Process a local template directory (extract + prompt + replace)
7
+ * @param templateDir - Local directory path (MUST be local, NOT git URL)
8
+ * @param outputDir - Output directory for generated project
9
+ * @param options - Processing options (argv overrides, noTty)
10
+ * @returns Processing result
11
+ */
12
+ process(templateDir: string, outputDir: string, options?: ProcessOptions): Promise<TemplatizerResult>;
13
+ /**
14
+ * Extract variables from template directory
15
+ */
16
+ extract(templateDir: string): Promise<ExtractedVariables>;
17
+ /**
18
+ * Prompt user for variables
19
+ */
20
+ prompt(extracted: ExtractedVariables, argv?: Record<string, any>, noTty?: boolean): Promise<Record<string, any>>;
21
+ /**
22
+ * Replace variables in template
23
+ */
24
+ replace(templateDir: string, outputDir: string, extracted: ExtractedVariables, answers: Record<string, any>): Promise<void>;
25
+ /**
26
+ * Validate template directory exists and has content
27
+ */
28
+ validateTemplateDir(templateDir: string): void;
29
+ }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Templatizer = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const extract_1 = require("./extract");
40
+ const prompt_1 = require("./prompt");
41
+ const replace_1 = require("./replace");
42
+ class Templatizer {
43
+ constructor() {
44
+ // Pure template processor - no configuration needed
45
+ }
46
+ /**
47
+ * Process a local template directory (extract + prompt + replace)
48
+ * @param templateDir - Local directory path (MUST be local, NOT git URL)
49
+ * @param outputDir - Output directory for generated project
50
+ * @param options - Processing options (argv overrides, noTty)
51
+ * @returns Processing result
52
+ */
53
+ async process(templateDir, outputDir, options) {
54
+ this.validateTemplateDir(templateDir);
55
+ // Handle subdirectory within template
56
+ const actualTemplateDir = options?.fromPath
57
+ ? path.join(templateDir, options.fromPath)
58
+ : templateDir;
59
+ this.validateTemplateDir(actualTemplateDir);
60
+ // Extract variables
61
+ const variables = await this.extract(actualTemplateDir);
62
+ // Prompt for values
63
+ const answers = await this.prompt(variables, options?.argv, options?.noTty);
64
+ // Replace variables
65
+ await this.replace(actualTemplateDir, outputDir, variables, answers);
66
+ return {
67
+ outputDir,
68
+ variables,
69
+ answers,
70
+ };
71
+ }
72
+ /**
73
+ * Extract variables from template directory
74
+ */
75
+ async extract(templateDir) {
76
+ return (0, extract_1.extractVariables)(templateDir);
77
+ }
78
+ /**
79
+ * Prompt user for variables
80
+ */
81
+ async prompt(extracted, argv, noTty) {
82
+ return (0, prompt_1.promptUser)(extracted, argv ?? {}, noTty ?? false);
83
+ }
84
+ /**
85
+ * Replace variables in template
86
+ */
87
+ async replace(templateDir, outputDir, extracted, answers) {
88
+ return (0, replace_1.replaceVariables)(templateDir, outputDir, extracted, answers);
89
+ }
90
+ /**
91
+ * Validate template directory exists and has content
92
+ */
93
+ validateTemplateDir(templateDir) {
94
+ if (!fs.existsSync(templateDir)) {
95
+ throw new Error(`Template directory does not exist: ${templateDir}`);
96
+ }
97
+ if (!fs.statSync(templateDir).isDirectory()) {
98
+ throw new Error(`Template path is not a directory: ${templateDir}`);
99
+ }
100
+ const entries = fs.readdirSync(templateDir);
101
+ if (entries.length === 0) {
102
+ throw new Error(`Template directory is empty: ${templateDir}`);
103
+ }
104
+ }
105
+ }
106
+ exports.Templatizer = Templatizer;
@@ -0,0 +1,11 @@
1
+ import { ExtractedVariables } from '../types';
2
+ export interface ProcessOptions {
3
+ argv?: Record<string, any>;
4
+ noTty?: boolean;
5
+ fromPath?: string;
6
+ }
7
+ export interface TemplatizerResult {
8
+ outputDir: string;
9
+ variables: ExtractedVariables;
10
+ answers: Record<string, any>;
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ import { VersionCheckResult } from './types';
2
+ /**
3
+ * Check if current package version is outdated compared to npm registry
4
+ * @param packageName - Package name to check
5
+ * @param currentVersion - Current version string
6
+ * @returns Version comparison result
7
+ */
8
+ export declare function checkNpmVersion(packageName: string, currentVersion: string): Promise<VersionCheckResult>;
9
+ /**
10
+ * Compare two semver version strings
11
+ * Returns: -1 if v1 < v2, 0 if equal, 1 if v1 > v2
12
+ */
13
+ export declare function compareVersions(v1: string, v2: string): number;
14
+ /**
15
+ * Print version warning to console if outdated
16
+ */
17
+ export declare function warnIfOutdated(packageName: string, result: VersionCheckResult): void;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkNpmVersion = checkNpmVersion;
4
+ exports.compareVersions = compareVersions;
5
+ exports.warnIfOutdated = warnIfOutdated;
6
+ const child_process_1 = require("child_process");
7
+ /**
8
+ * Check if current package version is outdated compared to npm registry
9
+ * @param packageName - Package name to check
10
+ * @param currentVersion - Current version string
11
+ * @returns Version comparison result
12
+ */
13
+ async function checkNpmVersion(packageName, currentVersion) {
14
+ try {
15
+ const latestVersion = (0, child_process_1.execSync)(`npm view ${packageName} version`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] }).trim();
16
+ const isOutdated = compareVersions(currentVersion, latestVersion) < 0;
17
+ return {
18
+ currentVersion,
19
+ latestVersion,
20
+ isOutdated,
21
+ };
22
+ }
23
+ catch (error) {
24
+ return {
25
+ currentVersion,
26
+ latestVersion: null,
27
+ isOutdated: false,
28
+ error: error instanceof Error ? error.message : String(error),
29
+ };
30
+ }
31
+ }
32
+ /**
33
+ * Compare two semver version strings
34
+ * Returns: -1 if v1 < v2, 0 if equal, 1 if v1 > v2
35
+ */
36
+ function compareVersions(v1, v2) {
37
+ const parts1 = v1.split('.').map(Number);
38
+ const parts2 = v2.split('.').map(Number);
39
+ for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
40
+ const p1 = parts1[i] || 0;
41
+ const p2 = parts2[i] || 0;
42
+ if (p1 < p2)
43
+ return -1;
44
+ if (p1 > p2)
45
+ return 1;
46
+ }
47
+ return 0;
48
+ }
49
+ /**
50
+ * Print version warning to console if outdated
51
+ */
52
+ function warnIfOutdated(packageName, result) {
53
+ if (result.isOutdated && result.latestVersion) {
54
+ console.warn(`\n⚠️ New version available: ${result.currentVersion} → ${result.latestVersion}`);
55
+ console.warn(` Run: npm install -g ${packageName}@latest\n`);
56
+ }
57
+ }
@@ -0,0 +1,6 @@
1
+ export interface VersionCheckResult {
2
+ currentVersion: string;
3
+ latestVersion: string | null;
4
+ isOutdated: boolean;
5
+ error?: string;
6
+ }
package/utils/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/cache.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import { CacheOptions } from "./types";
2
- export interface TemplateSource {
3
- templateDir: string;
4
- cacheUsed: boolean;
5
- cleanup: () => void;
6
- }
7
- interface PrepareTemplateArgs {
8
- templateUrl: string;
9
- branch?: string;
10
- cache: CacheOptions | false;
11
- }
12
- export declare function prepareTemplateDirectory(args: PrepareTemplateArgs): Promise<TemplateSource>;
13
- export { TemplateCache } from "./template-cache";
package/cache.js DELETED
@@ -1,76 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.TemplateCache = void 0;
37
- exports.prepareTemplateDirectory = prepareTemplateDirectory;
38
- const fs = __importStar(require("fs"));
39
- const clone_1 = require("./clone");
40
- const template_cache_1 = require("./template-cache");
41
- async function prepareTemplateDirectory(args) {
42
- const { templateUrl, branch, cache } = args;
43
- const templateCache = new template_cache_1.TemplateCache(cache);
44
- if (!templateCache.isEnabled()) {
45
- const tempDir = await (0, clone_1.cloneRepo)(templateUrl, { branch });
46
- return {
47
- templateDir: tempDir,
48
- cacheUsed: false,
49
- cleanup: () => cleanupDir(tempDir),
50
- };
51
- }
52
- // Try to get from cache
53
- const cachedPath = templateCache.get(templateUrl, branch);
54
- if (cachedPath) {
55
- return {
56
- templateDir: cachedPath,
57
- cacheUsed: true,
58
- cleanup: () => { },
59
- };
60
- }
61
- // Cache miss or expired - clone and cache
62
- const cachePath = templateCache.set(templateUrl, branch);
63
- return {
64
- templateDir: cachePath,
65
- cacheUsed: false,
66
- cleanup: () => { },
67
- };
68
- }
69
- function cleanupDir(dir) {
70
- if (fs.existsSync(dir)) {
71
- fs.rmSync(dir, { recursive: true, force: true });
72
- }
73
- }
74
- // Re-export TemplateCache for external use
75
- var template_cache_2 = require("./template-cache");
76
- Object.defineProperty(exports, "TemplateCache", { enumerable: true, get: function () { return template_cache_2.TemplateCache; } });
package/clone.d.ts DELETED
@@ -1,15 +0,0 @@
1
- export interface CloneOptions {
2
- branch?: string;
3
- }
4
- /**
5
- * Clone a repository to a temporary directory
6
- * @param url - Repository URL (GitHub or any git URL)
7
- * @returns Path to the cloned repository
8
- */
9
- export declare function cloneRepo(url: string, options?: CloneOptions): Promise<string>;
10
- /**
11
- * Normalize a URL to a git-cloneable format
12
- * @param url - Input URL
13
- * @returns Normalized git URL
14
- */
15
- export declare function normalizeGitUrl(url: string): string;
package/clone.js DELETED
@@ -1,86 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.cloneRepo = cloneRepo;
37
- exports.normalizeGitUrl = normalizeGitUrl;
38
- const child_process_1 = require("child_process");
39
- const fs = __importStar(require("fs"));
40
- const os = __importStar(require("os"));
41
- const path = __importStar(require("path"));
42
- /**
43
- * Clone a repository to a temporary directory
44
- * @param url - Repository URL (GitHub or any git URL)
45
- * @returns Path to the cloned repository
46
- */
47
- async function cloneRepo(url, options = {}) {
48
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "create-gen-"));
49
- const { branch } = options;
50
- try {
51
- const gitUrl = normalizeGitUrl(url);
52
- const branchArgs = branch ? ` --branch ${branch} --single-branch` : "";
53
- const depthArgs = " --depth 1"; // use shallow clone for speed; remove if future features need full history
54
- (0, child_process_1.execSync)(`git clone${branchArgs}${depthArgs} ${gitUrl} ${tempDir}`, {
55
- stdio: "inherit",
56
- });
57
- const gitDir = path.join(tempDir, ".git");
58
- if (fs.existsSync(gitDir)) {
59
- fs.rmSync(gitDir, { recursive: true, force: true });
60
- }
61
- return tempDir;
62
- }
63
- catch (error) {
64
- if (fs.existsSync(tempDir)) {
65
- fs.rmSync(tempDir, { recursive: true, force: true });
66
- }
67
- const errorMessage = error instanceof Error ? error.message : String(error);
68
- throw new Error(`Failed to clone repository: ${errorMessage}`);
69
- }
70
- }
71
- /**
72
- * Normalize a URL to a git-cloneable format
73
- * @param url - Input URL
74
- * @returns Normalized git URL
75
- */
76
- function normalizeGitUrl(url) {
77
- if (url.startsWith("git@") ||
78
- url.startsWith("https://") ||
79
- url.startsWith("http://")) {
80
- return url;
81
- }
82
- if (/^[\w-]+\/[\w-]+$/.test(url)) {
83
- return `https://github.com/${url}.git`;
84
- }
85
- return url;
86
- }
package/esm/cache.js DELETED
@@ -1,38 +0,0 @@
1
- import * as fs from "fs";
2
- import { cloneRepo } from "./clone";
3
- import { TemplateCache } from "./template-cache";
4
- export async function prepareTemplateDirectory(args) {
5
- const { templateUrl, branch, cache } = args;
6
- const templateCache = new TemplateCache(cache);
7
- if (!templateCache.isEnabled()) {
8
- const tempDir = await cloneRepo(templateUrl, { branch });
9
- return {
10
- templateDir: tempDir,
11
- cacheUsed: false,
12
- cleanup: () => cleanupDir(tempDir),
13
- };
14
- }
15
- // Try to get from cache
16
- const cachedPath = templateCache.get(templateUrl, branch);
17
- if (cachedPath) {
18
- return {
19
- templateDir: cachedPath,
20
- cacheUsed: true,
21
- cleanup: () => { },
22
- };
23
- }
24
- // Cache miss or expired - clone and cache
25
- const cachePath = templateCache.set(templateUrl, branch);
26
- return {
27
- templateDir: cachePath,
28
- cacheUsed: false,
29
- cleanup: () => { },
30
- };
31
- }
32
- function cleanupDir(dir) {
33
- if (fs.existsSync(dir)) {
34
- fs.rmSync(dir, { recursive: true, force: true });
35
- }
36
- }
37
- // Re-export TemplateCache for external use
38
- export { TemplateCache } from "./template-cache";
package/esm/clone.js DELETED
@@ -1,49 +0,0 @@
1
- import { execSync } from "child_process";
2
- import * as fs from "fs";
3
- import * as os from "os";
4
- import * as path from "path";
5
- /**
6
- * Clone a repository to a temporary directory
7
- * @param url - Repository URL (GitHub or any git URL)
8
- * @returns Path to the cloned repository
9
- */
10
- export async function cloneRepo(url, options = {}) {
11
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "create-gen-"));
12
- const { branch } = options;
13
- try {
14
- const gitUrl = normalizeGitUrl(url);
15
- const branchArgs = branch ? ` --branch ${branch} --single-branch` : "";
16
- const depthArgs = " --depth 1"; // use shallow clone for speed; remove if future features need full history
17
- execSync(`git clone${branchArgs}${depthArgs} ${gitUrl} ${tempDir}`, {
18
- stdio: "inherit",
19
- });
20
- const gitDir = path.join(tempDir, ".git");
21
- if (fs.existsSync(gitDir)) {
22
- fs.rmSync(gitDir, { recursive: true, force: true });
23
- }
24
- return tempDir;
25
- }
26
- catch (error) {
27
- if (fs.existsSync(tempDir)) {
28
- fs.rmSync(tempDir, { recursive: true, force: true });
29
- }
30
- const errorMessage = error instanceof Error ? error.message : String(error);
31
- throw new Error(`Failed to clone repository: ${errorMessage}`);
32
- }
33
- }
34
- /**
35
- * Normalize a URL to a git-cloneable format
36
- * @param url - Input URL
37
- * @returns Normalized git URL
38
- */
39
- export function normalizeGitUrl(url) {
40
- if (url.startsWith("git@") ||
41
- url.startsWith("https://") ||
42
- url.startsWith("http://")) {
43
- return url;
44
- }
45
- if (/^[\w-]+\/[\w-]+$/.test(url)) {
46
- return `https://github.com/${url}.git`;
47
- }
48
- return url;
49
- }