genomic 4.0.1 → 5.0.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/README.md +153 -1127
- package/cache/cache-manager.d.ts +60 -0
- package/cache/cache-manager.js +228 -0
- package/cache/types.d.ts +22 -0
- package/esm/cache/cache-manager.js +191 -0
- package/esm/git/git-cloner.js +92 -0
- package/esm/index.js +41 -4
- package/esm/licenses.js +120 -0
- package/esm/scaffolder/index.js +2 -0
- package/esm/scaffolder/template-scaffolder.js +310 -0
- package/esm/scaffolder/types.js +1 -0
- package/esm/template/extract.js +162 -0
- package/esm/template/prompt.js +103 -0
- package/esm/template/replace.js +110 -0
- package/esm/template/templatizer.js +73 -0
- package/esm/template/types.js +1 -0
- package/esm/types.js +1 -0
- package/esm/utils/npm-version-check.js +52 -0
- package/esm/utils/types.js +1 -0
- package/git/git-cloner.d.ts +32 -0
- package/git/git-cloner.js +129 -0
- package/git/types.d.ts +15 -0
- package/index.d.ts +29 -4
- package/index.js +43 -4
- package/licenses-templates/APACHE-2.0.txt +18 -0
- package/licenses-templates/BSD-3-CLAUSE.txt +28 -0
- package/licenses-templates/CLOSED.txt +20 -0
- package/licenses-templates/GPL-3.0.txt +18 -0
- package/licenses-templates/ISC.txt +16 -0
- package/licenses-templates/MIT.txt +22 -0
- package/licenses-templates/MPL-2.0.txt +8 -0
- package/licenses-templates/UNLICENSE.txt +22 -0
- package/licenses.d.ts +18 -0
- package/licenses.js +162 -0
- package/package.json +9 -14
- package/scaffolder/index.d.ts +2 -0
- package/{question → scaffolder}/index.js +1 -0
- package/scaffolder/template-scaffolder.d.ts +91 -0
- package/scaffolder/template-scaffolder.js +347 -0
- package/scaffolder/types.d.ts +191 -0
- package/scaffolder/types.js +2 -0
- package/template/extract.d.ts +7 -0
- package/template/extract.js +198 -0
- package/template/prompt.d.ts +19 -0
- package/template/prompt.js +107 -0
- package/template/replace.d.ts +9 -0
- package/template/replace.js +146 -0
- package/template/templatizer.d.ts +33 -0
- package/template/templatizer.js +110 -0
- package/template/types.d.ts +18 -0
- package/template/types.js +2 -0
- package/types.d.ts +99 -0
- package/types.js +2 -0
- package/utils/npm-version-check.d.ts +17 -0
- package/utils/npm-version-check.js +57 -0
- package/utils/types.d.ts +6 -0
- package/utils/types.js +2 -0
- package/commander.d.ts +0 -21
- package/commander.js +0 -57
- package/esm/commander.js +0 -50
- package/esm/keypress.js +0 -95
- package/esm/prompt.js +0 -1024
- package/esm/question/index.js +0 -1
- package/esm/resolvers/date.js +0 -11
- package/esm/resolvers/git.js +0 -26
- package/esm/resolvers/index.js +0 -103
- package/esm/resolvers/npm.js +0 -24
- package/esm/resolvers/workspace.js +0 -141
- package/esm/utils.js +0 -12
- package/keypress.d.ts +0 -45
- package/keypress.js +0 -99
- package/prompt.d.ts +0 -116
- package/prompt.js +0 -1032
- package/question/index.d.ts +0 -1
- package/question/types.d.ts +0 -65
- package/resolvers/date.d.ts +0 -5
- package/resolvers/date.js +0 -14
- package/resolvers/git.d.ts +0 -11
- package/resolvers/git.js +0 -30
- package/resolvers/index.d.ts +0 -63
- package/resolvers/index.js +0 -111
- package/resolvers/npm.d.ts +0 -10
- package/resolvers/npm.js +0 -28
- package/resolvers/types.d.ts +0 -12
- package/resolvers/workspace.d.ts +0 -6
- package/resolvers/workspace.js +0 -144
- package/utils.d.ts +0 -2
- package/utils.js +0 -16
- /package/{question → cache}/types.js +0 -0
- /package/esm/{question → cache}/types.js +0 -0
- /package/esm/{resolvers → git}/types.js +0 -0
- /package/{resolvers → git}/types.js +0 -0
package/esm/question/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './types';
|
package/esm/resolvers/date.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Built-in date/time resolvers.
|
|
3
|
-
*/
|
|
4
|
-
export const dateResolvers = {
|
|
5
|
-
'date.year': () => new Date().getFullYear().toString(),
|
|
6
|
-
'date.month': () => (new Date().getMonth() + 1).toString().padStart(2, '0'),
|
|
7
|
-
'date.day': () => new Date().getDate().toString().padStart(2, '0'),
|
|
8
|
-
'date.now': () => new Date().toISOString(),
|
|
9
|
-
'date.iso': () => new Date().toISOString().split('T')[0], // YYYY-MM-DD
|
|
10
|
-
'date.timestamp': () => Date.now().toString(),
|
|
11
|
-
};
|
package/esm/resolvers/git.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
/**
|
|
3
|
-
* Retrieves a git config value.
|
|
4
|
-
* @param key The git config key (e.g., 'user.name', 'user.email')
|
|
5
|
-
* @returns The config value as a string, or undefined if not found or error occurs
|
|
6
|
-
*/
|
|
7
|
-
export function getGitConfig(key) {
|
|
8
|
-
try {
|
|
9
|
-
const result = execSync(`git config --global ${key}`, {
|
|
10
|
-
encoding: 'utf8',
|
|
11
|
-
stdio: ['pipe', 'pipe', 'ignore'] // Suppress stderr
|
|
12
|
-
});
|
|
13
|
-
const trimmed = result.trim();
|
|
14
|
-
return trimmed || undefined; // Treat empty string as undefined
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Built-in git configuration resolvers.
|
|
22
|
-
*/
|
|
23
|
-
export const gitResolvers = {
|
|
24
|
-
'git.user.name': () => getGitConfig('user.name'),
|
|
25
|
-
'git.user.email': () => getGitConfig('user.email'),
|
|
26
|
-
};
|
package/esm/resolvers/index.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { gitResolvers } from './git';
|
|
2
|
-
import { dateResolvers } from './date';
|
|
3
|
-
import { npmResolvers } from './npm';
|
|
4
|
-
import { workspaceResolvers } from './workspace';
|
|
5
|
-
/**
|
|
6
|
-
* A registry for managing default value resolvers.
|
|
7
|
-
* Allows registration of custom resolvers and provides resolution logic.
|
|
8
|
-
*/
|
|
9
|
-
export class DefaultResolverRegistry {
|
|
10
|
-
resolvers;
|
|
11
|
-
constructor(initialResolvers = {}) {
|
|
12
|
-
this.resolvers = { ...initialResolvers };
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Register a custom resolver.
|
|
16
|
-
* @param key The resolver key (e.g., 'git.user.name')
|
|
17
|
-
* @param resolver The resolver function
|
|
18
|
-
*/
|
|
19
|
-
register(key, resolver) {
|
|
20
|
-
this.resolvers[key] = resolver;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Unregister a resolver.
|
|
24
|
-
* @param key The resolver key to remove
|
|
25
|
-
*/
|
|
26
|
-
unregister(key) {
|
|
27
|
-
delete this.resolvers[key];
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Resolve a key to its value.
|
|
31
|
-
* Returns undefined if the resolver doesn't exist or if it throws an error.
|
|
32
|
-
* @param key The resolver key
|
|
33
|
-
* @returns The resolved value or undefined
|
|
34
|
-
*/
|
|
35
|
-
async resolve(key) {
|
|
36
|
-
const resolver = this.resolvers[key];
|
|
37
|
-
if (!resolver) {
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
40
|
-
try {
|
|
41
|
-
const result = await Promise.resolve(resolver());
|
|
42
|
-
// Treat empty strings as undefined
|
|
43
|
-
return result === '' ? undefined : result;
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
// Silent failure - log only in debug mode
|
|
47
|
-
if (process.env.DEBUG === 'genomic') {
|
|
48
|
-
console.error(`[genomic] Resolver '${key}' failed:`, error);
|
|
49
|
-
}
|
|
50
|
-
return undefined;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Check if a resolver exists for the given key.
|
|
55
|
-
* @param key The resolver key
|
|
56
|
-
* @returns True if the resolver exists
|
|
57
|
-
*/
|
|
58
|
-
has(key) {
|
|
59
|
-
return key in this.resolvers;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Get all registered resolver keys.
|
|
63
|
-
* @returns Array of resolver keys
|
|
64
|
-
*/
|
|
65
|
-
keys() {
|
|
66
|
-
return Object.keys(this.resolvers);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Create a copy of this registry with all current resolvers.
|
|
70
|
-
* @returns A new DefaultResolverRegistry instance
|
|
71
|
-
*/
|
|
72
|
-
clone() {
|
|
73
|
-
return new DefaultResolverRegistry({ ...this.resolvers });
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Global resolver registry instance with built-in resolvers.
|
|
78
|
-
* This is the default registry used by Prompter unless a custom one is provided.
|
|
79
|
-
*/
|
|
80
|
-
export const globalResolverRegistry = new DefaultResolverRegistry({
|
|
81
|
-
...gitResolvers,
|
|
82
|
-
...dateResolvers,
|
|
83
|
-
...npmResolvers,
|
|
84
|
-
...workspaceResolvers,
|
|
85
|
-
});
|
|
86
|
-
/**
|
|
87
|
-
* Convenience function to register a resolver on the global registry.
|
|
88
|
-
* @param key The resolver key
|
|
89
|
-
* @param resolver The resolver function
|
|
90
|
-
*/
|
|
91
|
-
export function registerDefaultResolver(key, resolver) {
|
|
92
|
-
globalResolverRegistry.register(key, resolver);
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Convenience function to resolve a key using the global registry.
|
|
96
|
-
* @param key The resolver key
|
|
97
|
-
* @returns The resolved value or undefined
|
|
98
|
-
*/
|
|
99
|
-
export function resolveDefault(key) {
|
|
100
|
-
return globalResolverRegistry.resolve(key);
|
|
101
|
-
}
|
|
102
|
-
export { getGitConfig } from './git';
|
|
103
|
-
export { getNpmWhoami } from './npm';
|
package/esm/resolvers/npm.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
/**
|
|
3
|
-
* Retrieves the currently logged in npm user.
|
|
4
|
-
* @returns The npm username, or undefined if not logged in or error occurs
|
|
5
|
-
*/
|
|
6
|
-
export function getNpmWhoami() {
|
|
7
|
-
try {
|
|
8
|
-
const result = execSync('npm whoami', {
|
|
9
|
-
encoding: 'utf8',
|
|
10
|
-
stdio: ['pipe', 'pipe', 'ignore'] // Suppress stderr
|
|
11
|
-
});
|
|
12
|
-
const trimmed = result.trim();
|
|
13
|
-
return trimmed || undefined; // Treat empty string as undefined
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return undefined;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Built-in npm resolvers.
|
|
21
|
-
*/
|
|
22
|
-
export const npmResolvers = {
|
|
23
|
-
'npm.whoami': () => getNpmWhoami(),
|
|
24
|
-
};
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { findAndRequirePackageJson } from 'find-and-require-package-json';
|
|
2
|
-
/**
|
|
3
|
-
* Find and read the nearest package.json starting from cwd.
|
|
4
|
-
* Returns undefined if not found (instead of throwing).
|
|
5
|
-
*/
|
|
6
|
-
function findPackageJsonFromCwd() {
|
|
7
|
-
try {
|
|
8
|
-
return findAndRequirePackageJson(process.cwd());
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return undefined;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Parse a GitHub URL and extract organization and repo name.
|
|
16
|
-
* Handles various formats:
|
|
17
|
-
* - https://github.com/org/repo
|
|
18
|
-
* - https://github.com/org/repo.git
|
|
19
|
-
* - git@github.com:org/repo.git
|
|
20
|
-
* - git://github.com/org/repo.git
|
|
21
|
-
*/
|
|
22
|
-
function parseGitHubUrl(url) {
|
|
23
|
-
if (!url) {
|
|
24
|
-
return {};
|
|
25
|
-
}
|
|
26
|
-
// Handle git@github.com:org/repo.git format
|
|
27
|
-
const sshMatch = url.match(/git@github\.com:([^/]+)\/([^/.]+)(?:\.git)?/);
|
|
28
|
-
if (sshMatch) {
|
|
29
|
-
return { organization: sshMatch[1], name: sshMatch[2] };
|
|
30
|
-
}
|
|
31
|
-
// Handle https://github.com/org/repo or git://github.com/org/repo formats
|
|
32
|
-
const httpsMatch = url.match(/(?:https?|git):\/\/github\.com\/([^/]+)\/([^/.]+)(?:\.git)?/);
|
|
33
|
-
if (httpsMatch) {
|
|
34
|
-
return { organization: httpsMatch[1], name: httpsMatch[2] };
|
|
35
|
-
}
|
|
36
|
-
return {};
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Get the repository URL from package.json.
|
|
40
|
-
* Handles both string and object formats.
|
|
41
|
-
*/
|
|
42
|
-
function getRepositoryUrl(pkg) {
|
|
43
|
-
if (!pkg.repository) {
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
if (typeof pkg.repository === 'string') {
|
|
47
|
-
return pkg.repository;
|
|
48
|
-
}
|
|
49
|
-
return pkg.repository.url;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Parse author field which can be a string or object.
|
|
53
|
-
* String format: "Name <email> (url)" where email and url are optional
|
|
54
|
-
*/
|
|
55
|
-
function parseAuthor(author) {
|
|
56
|
-
if (!author) {
|
|
57
|
-
return {};
|
|
58
|
-
}
|
|
59
|
-
if (typeof author === 'object') {
|
|
60
|
-
return { name: author.name, email: author.email };
|
|
61
|
-
}
|
|
62
|
-
// Parse string format: "Name <email> (url)"
|
|
63
|
-
const nameMatch = author.match(/^([^<(]+)/);
|
|
64
|
-
const emailMatch = author.match(/<([^>]+)>/);
|
|
65
|
-
return {
|
|
66
|
-
name: nameMatch ? nameMatch[1].trim() : undefined,
|
|
67
|
-
email: emailMatch ? emailMatch[1] : undefined,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Built-in workspace resolvers.
|
|
72
|
-
* These resolve values from the nearest package.json in the current working directory.
|
|
73
|
-
*/
|
|
74
|
-
export const workspaceResolvers = {
|
|
75
|
-
'workspace.name': () => {
|
|
76
|
-
const pkg = findPackageJsonFromCwd();
|
|
77
|
-
if (!pkg)
|
|
78
|
-
return undefined;
|
|
79
|
-
const url = getRepositoryUrl(pkg);
|
|
80
|
-
// Prefer repo slug when repository is set; fall back to package name
|
|
81
|
-
if (url) {
|
|
82
|
-
const parsed = parseGitHubUrl(url);
|
|
83
|
-
if (parsed.name)
|
|
84
|
-
return parsed.name;
|
|
85
|
-
}
|
|
86
|
-
return pkg.name;
|
|
87
|
-
},
|
|
88
|
-
'workspace.repo.name': () => {
|
|
89
|
-
const pkg = findPackageJsonFromCwd();
|
|
90
|
-
if (!pkg)
|
|
91
|
-
return undefined;
|
|
92
|
-
const url = getRepositoryUrl(pkg);
|
|
93
|
-
if (!url)
|
|
94
|
-
return undefined;
|
|
95
|
-
return parseGitHubUrl(url).name;
|
|
96
|
-
},
|
|
97
|
-
'workspace.repo.organization': () => {
|
|
98
|
-
const pkg = findPackageJsonFromCwd();
|
|
99
|
-
if (!pkg)
|
|
100
|
-
return undefined;
|
|
101
|
-
const url = getRepositoryUrl(pkg);
|
|
102
|
-
if (!url)
|
|
103
|
-
return undefined;
|
|
104
|
-
return parseGitHubUrl(url).organization;
|
|
105
|
-
},
|
|
106
|
-
// Alias for repo.organization for template readability
|
|
107
|
-
'workspace.organization.name': () => {
|
|
108
|
-
const pkg = findPackageJsonFromCwd();
|
|
109
|
-
if (!pkg)
|
|
110
|
-
return undefined;
|
|
111
|
-
const url = getRepositoryUrl(pkg);
|
|
112
|
-
if (!url)
|
|
113
|
-
return undefined;
|
|
114
|
-
return parseGitHubUrl(url).organization;
|
|
115
|
-
},
|
|
116
|
-
'workspace.license': () => {
|
|
117
|
-
const pkg = findPackageJsonFromCwd();
|
|
118
|
-
return pkg?.license;
|
|
119
|
-
},
|
|
120
|
-
'workspace.author': () => {
|
|
121
|
-
const pkg = findPackageJsonFromCwd();
|
|
122
|
-
if (!pkg)
|
|
123
|
-
return undefined;
|
|
124
|
-
const parsed = parseAuthor(pkg.author);
|
|
125
|
-
return parsed.name;
|
|
126
|
-
},
|
|
127
|
-
'workspace.author.name': () => {
|
|
128
|
-
const pkg = findPackageJsonFromCwd();
|
|
129
|
-
if (!pkg)
|
|
130
|
-
return undefined;
|
|
131
|
-
const parsed = parseAuthor(pkg.author);
|
|
132
|
-
return parsed.name;
|
|
133
|
-
},
|
|
134
|
-
'workspace.author.email': () => {
|
|
135
|
-
const pkg = findPackageJsonFromCwd();
|
|
136
|
-
if (!pkg)
|
|
137
|
-
return undefined;
|
|
138
|
-
const parsed = parseAuthor(pkg.author);
|
|
139
|
-
return parsed.email;
|
|
140
|
-
},
|
|
141
|
-
};
|
package/esm/utils.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { green, blue } from 'yanse';
|
|
2
|
-
import { findAndRequirePackageJson } from 'find-and-require-package-json';
|
|
3
|
-
// Function to display the version information
|
|
4
|
-
export function displayVersion() {
|
|
5
|
-
const pkg = findAndRequirePackageJson(__dirname);
|
|
6
|
-
console.log(green(`Name: ${pkg.name}`));
|
|
7
|
-
console.log(blue(`Version: ${pkg.version}`));
|
|
8
|
-
}
|
|
9
|
-
export function getVersion() {
|
|
10
|
-
const pkg = findAndRequirePackageJson(__dirname);
|
|
11
|
-
return pkg.version;
|
|
12
|
-
}
|
package/keypress.d.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { Readable } from 'stream';
|
|
2
|
-
type KeyHandler = () => void;
|
|
3
|
-
interface ProcessWrapper {
|
|
4
|
-
exit: (code?: number) => never;
|
|
5
|
-
}
|
|
6
|
-
export declare const KEY_CODES: {
|
|
7
|
-
UP_ARROW: string;
|
|
8
|
-
DOWN_ARROW: string;
|
|
9
|
-
RIGHT_ARROW: string;
|
|
10
|
-
LEFT_ARROW: string;
|
|
11
|
-
ENTER: string;
|
|
12
|
-
SPACE: string;
|
|
13
|
-
CTRL_C: string;
|
|
14
|
-
BACKSPACE: string;
|
|
15
|
-
BACKSPACE_LEGACY: string;
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Handles keyboard input for interactive prompts.
|
|
19
|
-
*
|
|
20
|
-
* **Important**: Only one TerminalKeypress instance should be actively listening
|
|
21
|
-
* on a given input stream at a time. If you need multiple Prompter instances,
|
|
22
|
-
* call `close()` on the first instance before using the second, or reuse a single
|
|
23
|
-
* instance for all prompts.
|
|
24
|
-
*
|
|
25
|
-
* Multiple instances sharing the same input stream (e.g., process.stdin) will
|
|
26
|
-
* each receive all keypresses, which can cause duplicate or unexpected behavior.
|
|
27
|
-
*/
|
|
28
|
-
export declare class TerminalKeypress {
|
|
29
|
-
private listeners;
|
|
30
|
-
private active;
|
|
31
|
-
private noTty;
|
|
32
|
-
private input;
|
|
33
|
-
private proc;
|
|
34
|
-
private dataHandler;
|
|
35
|
-
constructor(noTty?: boolean, input?: Readable, proc?: ProcessWrapper);
|
|
36
|
-
isTTY(): boolean;
|
|
37
|
-
private setupListeners;
|
|
38
|
-
on(key: string, callback: KeyHandler): void;
|
|
39
|
-
off(key: string, callback: KeyHandler): void;
|
|
40
|
-
clearHandlers(): void;
|
|
41
|
-
pause(): void;
|
|
42
|
-
resume(): void;
|
|
43
|
-
destroy(): void;
|
|
44
|
-
}
|
|
45
|
-
export {};
|
package/keypress.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TerminalKeypress = exports.KEY_CODES = void 0;
|
|
4
|
-
const defaultProcessWrapper = {
|
|
5
|
-
exit: (code) => process.exit(code)
|
|
6
|
-
};
|
|
7
|
-
exports.KEY_CODES = {
|
|
8
|
-
UP_ARROW: '\u001b[A',
|
|
9
|
-
DOWN_ARROW: '\u001b[B',
|
|
10
|
-
RIGHT_ARROW: '\u001b[C',
|
|
11
|
-
LEFT_ARROW: '\u001b[D',
|
|
12
|
-
ENTER: '\r',
|
|
13
|
-
SPACE: ' ',
|
|
14
|
-
CTRL_C: '\u0003',
|
|
15
|
-
BACKSPACE: '\x7f', // Commonly used BACKSPACE key in Unix-like systems
|
|
16
|
-
BACKSPACE_LEGACY: '\x08' // For compatibility with some systems
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Handles keyboard input for interactive prompts.
|
|
20
|
-
*
|
|
21
|
-
* **Important**: Only one TerminalKeypress instance should be actively listening
|
|
22
|
-
* on a given input stream at a time. If you need multiple Prompter instances,
|
|
23
|
-
* call `close()` on the first instance before using the second, or reuse a single
|
|
24
|
-
* instance for all prompts.
|
|
25
|
-
*
|
|
26
|
-
* Multiple instances sharing the same input stream (e.g., process.stdin) will
|
|
27
|
-
* each receive all keypresses, which can cause duplicate or unexpected behavior.
|
|
28
|
-
*/
|
|
29
|
-
class TerminalKeypress {
|
|
30
|
-
listeners = {};
|
|
31
|
-
active = true;
|
|
32
|
-
noTty;
|
|
33
|
-
input;
|
|
34
|
-
proc;
|
|
35
|
-
dataHandler = null;
|
|
36
|
-
constructor(noTty = false, input = process.stdin, proc = defaultProcessWrapper) {
|
|
37
|
-
this.noTty = noTty;
|
|
38
|
-
this.input = input;
|
|
39
|
-
this.proc = proc;
|
|
40
|
-
if (this.isTTY()) {
|
|
41
|
-
this.input.resume();
|
|
42
|
-
this.input.setEncoding('utf8');
|
|
43
|
-
}
|
|
44
|
-
this.setupListeners();
|
|
45
|
-
}
|
|
46
|
-
isTTY() {
|
|
47
|
-
return !this.noTty;
|
|
48
|
-
}
|
|
49
|
-
setupListeners() {
|
|
50
|
-
this.dataHandler = (key) => {
|
|
51
|
-
if (!this.active)
|
|
52
|
-
return;
|
|
53
|
-
const handlers = this.listeners[key];
|
|
54
|
-
handlers?.forEach(handler => handler());
|
|
55
|
-
if (key === exports.KEY_CODES.CTRL_C) {
|
|
56
|
-
this.proc.exit(0);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
this.input.on('data', this.dataHandler);
|
|
60
|
-
}
|
|
61
|
-
on(key, callback) {
|
|
62
|
-
if (!this.listeners[key]) {
|
|
63
|
-
this.listeners[key] = [];
|
|
64
|
-
}
|
|
65
|
-
this.listeners[key].push(callback);
|
|
66
|
-
}
|
|
67
|
-
off(key, callback) {
|
|
68
|
-
if (this.listeners[key]) {
|
|
69
|
-
const index = this.listeners[key].indexOf(callback);
|
|
70
|
-
if (index !== -1) {
|
|
71
|
-
this.listeners[key].splice(index, 1);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
clearHandlers() {
|
|
76
|
-
this.listeners = {};
|
|
77
|
-
}
|
|
78
|
-
pause() {
|
|
79
|
-
this.active = false;
|
|
80
|
-
this.clearHandlers();
|
|
81
|
-
}
|
|
82
|
-
resume() {
|
|
83
|
-
this.active = true;
|
|
84
|
-
if (this.isTTY() && typeof this.input.setRawMode === 'function') {
|
|
85
|
-
this.input.setRawMode(true);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
destroy() {
|
|
89
|
-
if (typeof this.input.setRawMode === 'function') {
|
|
90
|
-
this.input.setRawMode(false);
|
|
91
|
-
}
|
|
92
|
-
this.input.pause();
|
|
93
|
-
if (this.dataHandler) {
|
|
94
|
-
this.input.removeListener('data', this.dataHandler);
|
|
95
|
-
this.dataHandler = null;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
exports.TerminalKeypress = TerminalKeypress;
|
package/prompt.d.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { Readable, Writable } from 'stream';
|
|
2
|
-
import { AutocompleteQuestion, CheckboxQuestion, ConfirmQuestion, ListQuestion, NumberQuestion, OptionValue, Question, TextQuestion, Validation } from './question';
|
|
3
|
-
import { DefaultResolverRegistry } from './resolvers';
|
|
4
|
-
export interface ManPageInfo {
|
|
5
|
-
commandName: string;
|
|
6
|
-
questions: Question[];
|
|
7
|
-
author?: string;
|
|
8
|
-
description?: string;
|
|
9
|
-
}
|
|
10
|
-
export interface PromptOptions {
|
|
11
|
-
usageText?: string;
|
|
12
|
-
manPageInfo?: ManPageInfo;
|
|
13
|
-
mutateArgs?: boolean;
|
|
14
|
-
}
|
|
15
|
-
export declare function reorderQuestionsByDeps(questions: Question[]): Question[];
|
|
16
|
-
declare class PromptContext {
|
|
17
|
-
numTries: number;
|
|
18
|
-
needsInput: boolean;
|
|
19
|
-
validation: Validation;
|
|
20
|
-
constructor();
|
|
21
|
-
tryAgain(validation: Partial<Validation>): void;
|
|
22
|
-
nextQuestion(): void;
|
|
23
|
-
process(validation: Validation | boolean): Validation;
|
|
24
|
-
}
|
|
25
|
-
export interface PrompterOptions {
|
|
26
|
-
noTty?: boolean;
|
|
27
|
-
input?: Readable;
|
|
28
|
-
output?: Writable;
|
|
29
|
-
useDefaults?: boolean;
|
|
30
|
-
globalMaxLines?: number;
|
|
31
|
-
mutateArgs?: boolean;
|
|
32
|
-
resolverRegistry?: DefaultResolverRegistry;
|
|
33
|
-
}
|
|
34
|
-
export declare class Prompter {
|
|
35
|
-
private rl;
|
|
36
|
-
private keypress;
|
|
37
|
-
private noTty;
|
|
38
|
-
private output;
|
|
39
|
-
private input;
|
|
40
|
-
private useDefaults;
|
|
41
|
-
private globalMaxLines;
|
|
42
|
-
private mutateArgs;
|
|
43
|
-
private resolverRegistry;
|
|
44
|
-
private handledKeys;
|
|
45
|
-
constructor(options?: PrompterOptions);
|
|
46
|
-
private clearScreen;
|
|
47
|
-
private write;
|
|
48
|
-
private log;
|
|
49
|
-
private getInput;
|
|
50
|
-
private getPrompt;
|
|
51
|
-
private displayPrompt;
|
|
52
|
-
generateManPage(opts: ManPageInfo): string;
|
|
53
|
-
private isValidatableAnswer;
|
|
54
|
-
private validateAnswer;
|
|
55
|
-
private isValid;
|
|
56
|
-
private validateAnswerPattern;
|
|
57
|
-
private isEmptyAnswer;
|
|
58
|
-
private sanitizeAnswer;
|
|
59
|
-
exit(): void;
|
|
60
|
-
prompt<T extends object>(argv: T, questions: Question[], options?: PromptOptions): Promise<T>;
|
|
61
|
-
private handleMissingArgsError;
|
|
62
|
-
private hasMissingRequiredArgs;
|
|
63
|
-
/**
|
|
64
|
-
* Resolves the default value for a question using the resolver system.
|
|
65
|
-
* Priority: defaultFrom > default > undefined
|
|
66
|
-
*/
|
|
67
|
-
private resolveQuestionDefault;
|
|
68
|
-
/**
|
|
69
|
-
* Resolves dynamic defaults for all questions that have defaultFrom specified.
|
|
70
|
-
* Updates the question.default property with the resolved value.
|
|
71
|
-
*/
|
|
72
|
-
private resolveDynamicDefaults;
|
|
73
|
-
/**
|
|
74
|
-
* Resolves setFrom values for all questions that have setFrom specified.
|
|
75
|
-
* Sets the value directly in obj, bypassing the prompt entirely.
|
|
76
|
-
*/
|
|
77
|
-
private resolveSetValues;
|
|
78
|
-
/**
|
|
79
|
-
* Resolves optionsFrom values for all questions that have optionsFrom specified.
|
|
80
|
-
* Updates the question.options property with the resolved array.
|
|
81
|
-
*/
|
|
82
|
-
private resolveOptionsFrom;
|
|
83
|
-
/**
|
|
84
|
-
* Extracts positional arguments from obj._ and assigns them to questions marked with _: true.
|
|
85
|
-
*
|
|
86
|
-
* Rules:
|
|
87
|
-
* 1. Named arguments take precedence - if a question already has a value in obj, skip it
|
|
88
|
-
* 2. Positional questions consume from obj._ left-to-right in declaration order
|
|
89
|
-
* 3. Returns the count of consumed positionals so caller can strip them from obj._
|
|
90
|
-
* 4. Missing positional values leave questions unset (for prompting/validation)
|
|
91
|
-
*
|
|
92
|
-
* This effectively allows "naming positional parameters" - users can pass values
|
|
93
|
-
* without flags and they'll be assigned to the appropriate question names.
|
|
94
|
-
*
|
|
95
|
-
* @returns The number of positional arguments consumed
|
|
96
|
-
*/
|
|
97
|
-
private extractPositionalArgs;
|
|
98
|
-
private applyDefaultValues;
|
|
99
|
-
private applyOverrides;
|
|
100
|
-
private handleOverrides;
|
|
101
|
-
private handleOverridesForCheckboxOptions;
|
|
102
|
-
private handleOverridesWithOptions;
|
|
103
|
-
private handleQuestionType;
|
|
104
|
-
confirm(question: ConfirmQuestion, ctx: PromptContext): Promise<boolean>;
|
|
105
|
-
text(question: TextQuestion, ctx: PromptContext): Promise<string | null>;
|
|
106
|
-
number(question: NumberQuestion, ctx: PromptContext): Promise<number | null>;
|
|
107
|
-
checkbox(question: CheckboxQuestion, ctx: PromptContext): Promise<OptionValue[]>;
|
|
108
|
-
autocomplete(question: AutocompleteQuestion, ctx: PromptContext): Promise<any>;
|
|
109
|
-
list(question: ListQuestion, ctx: PromptContext): Promise<any>;
|
|
110
|
-
private getOptionValue;
|
|
111
|
-
private sanitizeOptions;
|
|
112
|
-
private filterOptions;
|
|
113
|
-
private getMaxLines;
|
|
114
|
-
close(): void;
|
|
115
|
-
}
|
|
116
|
-
export {};
|