@tymber/create 0.0.1-alpha.0 → 0.0.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/LICENSE +22 -0
- package/README.md +11 -0
- package/dist/index.js +756 -0
- package/package.json +23 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
(The MIT License)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026-present Damien ARRACHEQUESNE
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,756 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { styleText } from 'node:util';
|
|
4
|
+
import V, { stdout, stdin } from 'node:process';
|
|
5
|
+
import * as b from 'node:readline';
|
|
6
|
+
import b__default from 'node:readline';
|
|
7
|
+
import { ReadStream } from 'node:tty';
|
|
8
|
+
import 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as fs from 'node:fs/promises';
|
|
11
|
+
|
|
12
|
+
/* MAIN */
|
|
13
|
+
const getCodePointsLength = (() => {
|
|
14
|
+
const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
|
|
15
|
+
return (input) => {
|
|
16
|
+
let surrogatePairsNr = 0;
|
|
17
|
+
SURROGATE_PAIR_RE.lastIndex = 0;
|
|
18
|
+
while (SURROGATE_PAIR_RE.test(input)) {
|
|
19
|
+
surrogatePairsNr += 1;
|
|
20
|
+
}
|
|
21
|
+
return input.length - surrogatePairsNr;
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
const isFullWidth = (x) => {
|
|
25
|
+
return x === 0x3000 || x >= 0xFF01 && x <= 0xFF60 || x >= 0xFFE0 && x <= 0xFFE6;
|
|
26
|
+
};
|
|
27
|
+
const isWideNotCJKTNotEmoji = (x) => {
|
|
28
|
+
return x === 0x231B || x === 0x2329 || x >= 0x2FF0 && x <= 0x2FFF || x >= 0x3001 && x <= 0x303E || x >= 0x3099 && x <= 0x30FF || x >= 0x3105 && x <= 0x312F || x >= 0x3131 && x <= 0x318E || x >= 0x3190 && x <= 0x31E3 || x >= 0x31EF && x <= 0x321E || x >= 0x3220 && x <= 0x3247 || x >= 0x3250 && x <= 0x4DBF || x >= 0xFE10 && x <= 0xFE19 || x >= 0xFE30 && x <= 0xFE52 || x >= 0xFE54 && x <= 0xFE66 || x >= 0xFE68 && x <= 0xFE6B || x >= 0x1F200 && x <= 0x1F202 || x >= 0x1F210 && x <= 0x1F23B || x >= 0x1F240 && x <= 0x1F248 || x >= 0x20000 && x <= 0x2FFFD || x >= 0x30000 && x <= 0x3FFFD;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/* IMPORT */
|
|
32
|
+
/* HELPERS */
|
|
33
|
+
const ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
|
|
34
|
+
const CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
35
|
+
const CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
|
|
36
|
+
const TAB_RE = /\t{1,1000}/y;
|
|
37
|
+
const EMOJI_RE = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/yu;
|
|
38
|
+
const LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
|
|
39
|
+
const MODIFIER_RE = /\p{M}+/gu;
|
|
40
|
+
const NO_TRUNCATION$1 = { limit: Infinity, ellipsis: '' };
|
|
41
|
+
/* MAIN */
|
|
42
|
+
const getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
|
|
43
|
+
/* CONSTANTS */
|
|
44
|
+
const LIMIT = truncationOptions.limit ?? Infinity;
|
|
45
|
+
const ELLIPSIS = truncationOptions.ellipsis ?? '';
|
|
46
|
+
const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION$1, widthOptions).width : 0);
|
|
47
|
+
const ANSI_WIDTH = 0;
|
|
48
|
+
const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
|
|
49
|
+
const TAB_WIDTH = widthOptions.tabWidth ?? 8;
|
|
50
|
+
const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
|
|
51
|
+
const FULL_WIDTH_WIDTH = 2;
|
|
52
|
+
const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
|
|
53
|
+
const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
|
|
54
|
+
const PARSE_BLOCKS = [
|
|
55
|
+
[LATIN_RE, REGULAR_WIDTH],
|
|
56
|
+
[ANSI_RE, ANSI_WIDTH],
|
|
57
|
+
[CONTROL_RE, CONTROL_WIDTH],
|
|
58
|
+
[TAB_RE, TAB_WIDTH],
|
|
59
|
+
[EMOJI_RE, EMOJI_WIDTH],
|
|
60
|
+
[CJKT_WIDE_RE, WIDE_WIDTH],
|
|
61
|
+
];
|
|
62
|
+
/* STATE */
|
|
63
|
+
let indexPrev = 0;
|
|
64
|
+
let index = 0;
|
|
65
|
+
let length = input.length;
|
|
66
|
+
let lengthExtra = 0;
|
|
67
|
+
let truncationEnabled = false;
|
|
68
|
+
let truncationIndex = length;
|
|
69
|
+
let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
|
|
70
|
+
let unmatchedStart = 0;
|
|
71
|
+
let unmatchedEnd = 0;
|
|
72
|
+
let width = 0;
|
|
73
|
+
let widthExtra = 0;
|
|
74
|
+
/* PARSE LOOP */
|
|
75
|
+
outer: while (true) {
|
|
76
|
+
/* UNMATCHED */
|
|
77
|
+
if ((unmatchedEnd > unmatchedStart) || (index >= length && index > indexPrev)) {
|
|
78
|
+
const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
|
|
79
|
+
lengthExtra = 0;
|
|
80
|
+
for (const char of unmatched.replaceAll(MODIFIER_RE, '')) {
|
|
81
|
+
const codePoint = char.codePointAt(0) || 0;
|
|
82
|
+
if (isFullWidth(codePoint)) {
|
|
83
|
+
widthExtra = FULL_WIDTH_WIDTH;
|
|
84
|
+
}
|
|
85
|
+
else if (isWideNotCJKTNotEmoji(codePoint)) {
|
|
86
|
+
widthExtra = WIDE_WIDTH;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
widthExtra = REGULAR_WIDTH;
|
|
90
|
+
}
|
|
91
|
+
if ((width + widthExtra) > truncationLimit) {
|
|
92
|
+
truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
|
|
93
|
+
}
|
|
94
|
+
if ((width + widthExtra) > LIMIT) {
|
|
95
|
+
truncationEnabled = true;
|
|
96
|
+
break outer;
|
|
97
|
+
}
|
|
98
|
+
lengthExtra += char.length;
|
|
99
|
+
width += widthExtra;
|
|
100
|
+
}
|
|
101
|
+
unmatchedStart = unmatchedEnd = 0;
|
|
102
|
+
}
|
|
103
|
+
/* EXITING */
|
|
104
|
+
if (index >= length) {
|
|
105
|
+
break outer;
|
|
106
|
+
}
|
|
107
|
+
/* PARSE BLOCKS */
|
|
108
|
+
for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
|
|
109
|
+
const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
|
|
110
|
+
BLOCK_RE.lastIndex = index;
|
|
111
|
+
if (BLOCK_RE.test(input)) {
|
|
112
|
+
lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
|
|
113
|
+
widthExtra = lengthExtra * BLOCK_WIDTH;
|
|
114
|
+
if ((width + widthExtra) > truncationLimit) {
|
|
115
|
+
truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
|
|
116
|
+
}
|
|
117
|
+
if ((width + widthExtra) > LIMIT) {
|
|
118
|
+
truncationEnabled = true;
|
|
119
|
+
break outer;
|
|
120
|
+
}
|
|
121
|
+
width += widthExtra;
|
|
122
|
+
unmatchedStart = indexPrev;
|
|
123
|
+
unmatchedEnd = index;
|
|
124
|
+
index = indexPrev = BLOCK_RE.lastIndex;
|
|
125
|
+
continue outer;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/* UNMATCHED INDEX */
|
|
129
|
+
index += 1;
|
|
130
|
+
}
|
|
131
|
+
/* RETURN */
|
|
132
|
+
return {
|
|
133
|
+
width: truncationEnabled ? truncationLimit : width,
|
|
134
|
+
index: truncationEnabled ? truncationIndex : length,
|
|
135
|
+
truncated: truncationEnabled,
|
|
136
|
+
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/* IMPORT */
|
|
141
|
+
/* HELPERS */
|
|
142
|
+
const NO_TRUNCATION = {
|
|
143
|
+
limit: Infinity,
|
|
144
|
+
ellipsis: '',
|
|
145
|
+
ellipsisWidth: 0,
|
|
146
|
+
};
|
|
147
|
+
/* MAIN */
|
|
148
|
+
const fastStringWidth = (input, options = {}) => {
|
|
149
|
+
return getStringTruncatedWidth(input, NO_TRUNCATION, options).width;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const ESC = '\x1B';
|
|
153
|
+
const CSI = '\x9B';
|
|
154
|
+
const END_CODE = 39;
|
|
155
|
+
const ANSI_ESCAPE_BELL = '\u0007';
|
|
156
|
+
const ANSI_CSI = '[';
|
|
157
|
+
const ANSI_OSC = ']';
|
|
158
|
+
const ANSI_SGR_TERMINATOR = 'm';
|
|
159
|
+
const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
160
|
+
const GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, 'y');
|
|
161
|
+
const getClosingCode = (openingCode) => {
|
|
162
|
+
if (openingCode >= 30 && openingCode <= 37)
|
|
163
|
+
return 39;
|
|
164
|
+
if (openingCode >= 90 && openingCode <= 97)
|
|
165
|
+
return 39;
|
|
166
|
+
if (openingCode >= 40 && openingCode <= 47)
|
|
167
|
+
return 49;
|
|
168
|
+
if (openingCode >= 100 && openingCode <= 107)
|
|
169
|
+
return 49;
|
|
170
|
+
if (openingCode === 1 || openingCode === 2)
|
|
171
|
+
return 22;
|
|
172
|
+
if (openingCode === 3)
|
|
173
|
+
return 23;
|
|
174
|
+
if (openingCode === 4)
|
|
175
|
+
return 24;
|
|
176
|
+
if (openingCode === 7)
|
|
177
|
+
return 27;
|
|
178
|
+
if (openingCode === 8)
|
|
179
|
+
return 28;
|
|
180
|
+
if (openingCode === 9)
|
|
181
|
+
return 29;
|
|
182
|
+
if (openingCode === 0)
|
|
183
|
+
return 0;
|
|
184
|
+
return undefined;
|
|
185
|
+
};
|
|
186
|
+
const wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
|
|
187
|
+
const wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
|
|
188
|
+
const wrapWord = (rows, word, columns) => {
|
|
189
|
+
const characters = word[Symbol.iterator]();
|
|
190
|
+
let isInsideEscape = false;
|
|
191
|
+
let isInsideLinkEscape = false;
|
|
192
|
+
let lastRow = rows.at(-1);
|
|
193
|
+
let visible = lastRow === undefined ? 0 : fastStringWidth(lastRow);
|
|
194
|
+
let currentCharacter = characters.next();
|
|
195
|
+
let nextCharacter = characters.next();
|
|
196
|
+
let rawCharacterIndex = 0;
|
|
197
|
+
while (!currentCharacter.done) {
|
|
198
|
+
const character = currentCharacter.value;
|
|
199
|
+
const characterLength = fastStringWidth(character);
|
|
200
|
+
if (visible + characterLength <= columns) {
|
|
201
|
+
rows[rows.length - 1] += character;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
rows.push(character);
|
|
205
|
+
visible = 0;
|
|
206
|
+
}
|
|
207
|
+
if (character === ESC || character === CSI) {
|
|
208
|
+
isInsideEscape = true;
|
|
209
|
+
isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
|
|
210
|
+
}
|
|
211
|
+
if (isInsideEscape) {
|
|
212
|
+
if (isInsideLinkEscape) {
|
|
213
|
+
if (character === ANSI_ESCAPE_BELL) {
|
|
214
|
+
isInsideEscape = false;
|
|
215
|
+
isInsideLinkEscape = false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else if (character === ANSI_SGR_TERMINATOR) {
|
|
219
|
+
isInsideEscape = false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
visible += characterLength;
|
|
224
|
+
if (visible === columns && !nextCharacter.done) {
|
|
225
|
+
rows.push('');
|
|
226
|
+
visible = 0;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
currentCharacter = nextCharacter;
|
|
230
|
+
nextCharacter = characters.next();
|
|
231
|
+
rawCharacterIndex += character.length;
|
|
232
|
+
}
|
|
233
|
+
lastRow = rows.at(-1);
|
|
234
|
+
if (!visible && lastRow !== undefined && lastRow.length && rows.length > 1) {
|
|
235
|
+
rows[rows.length - 2] += rows.pop();
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
const stringVisibleTrimSpacesRight = (string) => {
|
|
239
|
+
const words = string.split(' ');
|
|
240
|
+
let last = words.length;
|
|
241
|
+
while (last) {
|
|
242
|
+
if (fastStringWidth(words[last - 1])) {
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
last--;
|
|
246
|
+
}
|
|
247
|
+
if (last === words.length) {
|
|
248
|
+
return string;
|
|
249
|
+
}
|
|
250
|
+
return words.slice(0, last).join(' ') + words.slice(last).join('');
|
|
251
|
+
};
|
|
252
|
+
const exec = (string, columns, options = {}) => {
|
|
253
|
+
if (options.trim !== false && string.trim() === '') {
|
|
254
|
+
return '';
|
|
255
|
+
}
|
|
256
|
+
let returnValue = '';
|
|
257
|
+
let escapeCode;
|
|
258
|
+
let escapeUrl;
|
|
259
|
+
const words = string.split(' ');
|
|
260
|
+
let rows = [''];
|
|
261
|
+
let rowLength = 0;
|
|
262
|
+
for (let index = 0; index < words.length; index++) {
|
|
263
|
+
const word = words[index];
|
|
264
|
+
if (options.trim !== false) {
|
|
265
|
+
const row = rows.at(-1) ?? '';
|
|
266
|
+
const trimmed = row.trimStart();
|
|
267
|
+
if (row.length !== trimmed.length) {
|
|
268
|
+
rows[rows.length - 1] = trimmed;
|
|
269
|
+
rowLength = fastStringWidth(trimmed);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (index !== 0) {
|
|
273
|
+
if (rowLength >= columns &&
|
|
274
|
+
(options.wordWrap === false || options.trim === false)) {
|
|
275
|
+
rows.push('');
|
|
276
|
+
rowLength = 0;
|
|
277
|
+
}
|
|
278
|
+
if (rowLength || options.trim === false) {
|
|
279
|
+
rows[rows.length - 1] += ' ';
|
|
280
|
+
rowLength++;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const wordLength = fastStringWidth(word);
|
|
284
|
+
if (options.hard && wordLength > columns) {
|
|
285
|
+
const remainingColumns = columns - rowLength;
|
|
286
|
+
const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
|
|
287
|
+
const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
|
|
288
|
+
if (breaksStartingNextLine < breaksStartingThisLine) {
|
|
289
|
+
rows.push('');
|
|
290
|
+
}
|
|
291
|
+
wrapWord(rows, word, columns);
|
|
292
|
+
rowLength = fastStringWidth(rows.at(-1) ?? '');
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (rowLength + wordLength > columns && rowLength && wordLength) {
|
|
296
|
+
if (options.wordWrap === false && rowLength < columns) {
|
|
297
|
+
wrapWord(rows, word, columns);
|
|
298
|
+
rowLength = fastStringWidth(rows.at(-1) ?? '');
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
rows.push('');
|
|
302
|
+
rowLength = 0;
|
|
303
|
+
}
|
|
304
|
+
if (rowLength + wordLength > columns && options.wordWrap === false) {
|
|
305
|
+
wrapWord(rows, word, columns);
|
|
306
|
+
rowLength = fastStringWidth(rows.at(-1) ?? '');
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
rows[rows.length - 1] += word;
|
|
310
|
+
rowLength += wordLength;
|
|
311
|
+
}
|
|
312
|
+
if (options.trim !== false) {
|
|
313
|
+
rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
|
|
314
|
+
}
|
|
315
|
+
const preString = rows.join('\n');
|
|
316
|
+
let inSurrogate = false;
|
|
317
|
+
for (let i = 0; i < preString.length; i++) {
|
|
318
|
+
const character = preString[i];
|
|
319
|
+
returnValue += character;
|
|
320
|
+
if (!inSurrogate) {
|
|
321
|
+
inSurrogate = character >= '\ud800' && character <= '\udbff';
|
|
322
|
+
if (inSurrogate) {
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
inSurrogate = false;
|
|
328
|
+
}
|
|
329
|
+
if (character === ESC || character === CSI) {
|
|
330
|
+
GROUP_REGEX.lastIndex = i + 1;
|
|
331
|
+
const groupsResult = GROUP_REGEX.exec(preString);
|
|
332
|
+
const groups = groupsResult?.groups;
|
|
333
|
+
if (groups?.code !== undefined) {
|
|
334
|
+
const code = Number.parseFloat(groups.code);
|
|
335
|
+
escapeCode = code === END_CODE ? undefined : code;
|
|
336
|
+
}
|
|
337
|
+
else if (groups?.uri !== undefined) {
|
|
338
|
+
escapeUrl = groups.uri.length === 0 ? undefined : groups.uri;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
if (preString[i + 1] === '\n') {
|
|
342
|
+
if (escapeUrl) {
|
|
343
|
+
returnValue += wrapAnsiHyperlink('');
|
|
344
|
+
}
|
|
345
|
+
const closingCode = escapeCode ? getClosingCode(escapeCode) : undefined;
|
|
346
|
+
if (escapeCode && closingCode) {
|
|
347
|
+
returnValue += wrapAnsiCode(closingCode);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else if (character === '\n') {
|
|
351
|
+
if (escapeCode && getClosingCode(escapeCode)) {
|
|
352
|
+
returnValue += wrapAnsiCode(escapeCode);
|
|
353
|
+
}
|
|
354
|
+
if (escapeUrl) {
|
|
355
|
+
returnValue += wrapAnsiHyperlink(escapeUrl);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return returnValue;
|
|
360
|
+
};
|
|
361
|
+
const CRLF_OR_LF = /\r?\n/;
|
|
362
|
+
function wrapAnsi(string, columns, options) {
|
|
363
|
+
return String(string)
|
|
364
|
+
.normalize()
|
|
365
|
+
.split(CRLF_OR_LF)
|
|
366
|
+
.map((line) => exec(line, columns, options))
|
|
367
|
+
.join('\n');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
var src;
|
|
371
|
+
var hasRequiredSrc;
|
|
372
|
+
|
|
373
|
+
function requireSrc () {
|
|
374
|
+
if (hasRequiredSrc) return src;
|
|
375
|
+
hasRequiredSrc = 1;
|
|
376
|
+
|
|
377
|
+
const ESC = '\x1B';
|
|
378
|
+
const CSI = `${ESC}[`;
|
|
379
|
+
const beep = '\u0007';
|
|
380
|
+
|
|
381
|
+
const cursor = {
|
|
382
|
+
to(x, y) {
|
|
383
|
+
if (!y) return `${CSI}${x + 1}G`;
|
|
384
|
+
return `${CSI}${y + 1};${x + 1}H`;
|
|
385
|
+
},
|
|
386
|
+
move(x, y) {
|
|
387
|
+
let ret = '';
|
|
388
|
+
|
|
389
|
+
if (x < 0) ret += `${CSI}${-x}D`;
|
|
390
|
+
else if (x > 0) ret += `${CSI}${x}C`;
|
|
391
|
+
|
|
392
|
+
if (y < 0) ret += `${CSI}${-y}A`;
|
|
393
|
+
else if (y > 0) ret += `${CSI}${y}B`;
|
|
394
|
+
|
|
395
|
+
return ret;
|
|
396
|
+
},
|
|
397
|
+
up: (count = 1) => `${CSI}${count}A`,
|
|
398
|
+
down: (count = 1) => `${CSI}${count}B`,
|
|
399
|
+
forward: (count = 1) => `${CSI}${count}C`,
|
|
400
|
+
backward: (count = 1) => `${CSI}${count}D`,
|
|
401
|
+
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
402
|
+
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
403
|
+
left: `${CSI}G`,
|
|
404
|
+
hide: `${CSI}?25l`,
|
|
405
|
+
show: `${CSI}?25h`,
|
|
406
|
+
save: `${ESC}7`,
|
|
407
|
+
restore: `${ESC}8`
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
const scroll = {
|
|
411
|
+
up: (count = 1) => `${CSI}S`.repeat(count),
|
|
412
|
+
down: (count = 1) => `${CSI}T`.repeat(count)
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const erase = {
|
|
416
|
+
screen: `${CSI}2J`,
|
|
417
|
+
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
418
|
+
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
419
|
+
line: `${CSI}2K`,
|
|
420
|
+
lineEnd: `${CSI}K`,
|
|
421
|
+
lineStart: `${CSI}1K`,
|
|
422
|
+
lines(count) {
|
|
423
|
+
let clear = '';
|
|
424
|
+
for (let i = 0; i < count; i++)
|
|
425
|
+
clear += this.line + (i < count - 1 ? cursor.up() : '');
|
|
426
|
+
if (count)
|
|
427
|
+
clear += cursor.left;
|
|
428
|
+
return clear;
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
src = { cursor, scroll, erase, beep };
|
|
433
|
+
return src;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
var srcExports = requireSrc();
|
|
437
|
+
|
|
438
|
+
function f(r,t,s){if(!s.some(o=>!o.disabled))return r;const e=r+t,i=Math.max(s.length-1,0),n=e<0?i:e>i?0:e;return s[n].disabled?f(n,t<0?-1:1,s):n}const G=["up","down","left","right","space","enter","cancel"],h={actions:new Set(G),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"},withGuide:true};function C(r,t){if(typeof r=="string")return h.aliases.get(r)===t;for(const s of r)if(s!==void 0&&C(s,t))return true;return false}function z$1(r,t){if(r===t)return;const s=r.split(`
|
|
439
|
+
`),e=t.split(`
|
|
440
|
+
`),i=Math.max(s.length,e.length),n=[];for(let o=0;o<i;o++)s[o]!==e[o]&&n.push(o);return {lines:n,numLinesBefore:s.length,numLinesAfter:e.length,numLines:i}}const Y$1=globalThis.process.platform.startsWith("win"),k=Symbol("clack:cancel");function q(r){return r===k}function w$1(r,t){const s=r;s.isTTY&&s.setRawMode(t);}function R$1({input:r=stdin,output:t=stdout,overwrite:s=true,hideCursor:e=true}={}){const i=b.createInterface({input:r,output:t,prompt:"",tabSize:1});b.emitKeypressEvents(r,i),r instanceof ReadStream&&r.isTTY&&r.setRawMode(true);const n=(o,{name:u,sequence:a})=>{const l=String(o);if(C([l,u,a],"cancel")){e&&t.write(srcExports.cursor.show),process.exit(0);return}if(!s)return;const c=u==="return"?0:-1,y=u==="return"?-1:0;b.moveCursor(t,c,y,()=>{b.clearLine(t,1,()=>{r.once("keypress",n);});});};return e&&t.write(srcExports.cursor.hide),r.once("keypress",n),()=>{r.off("keypress",n),e&&t.write(srcExports.cursor.show),r instanceof ReadStream&&r.isTTY&&!Y$1&&r.setRawMode(false),i.terminal=false,i.close();}}const A=r=>"columns"in r&&typeof r.columns=="number"?r.columns:80,L=r=>"rows"in r&&typeof r.rows=="number"?r.rows:20;function W(r,t,s,e=s,i=s,n){const o=A(r??stdout);return wrapAnsi(t,o-s.length,{hard:true,trim:false}).split(`
|
|
441
|
+
`).map((u,a,l)=>{const c=u;return a===0?`${e}${c}`:a===l.length-1?`${i}${c}`:`${s}${c}`}).join(`
|
|
442
|
+
`)}let m=class{input;output;_abortSignal;rl;opts;_render;_track=false;_prevFrame="";_subscribers=new Map;_cursor=0;state="initial";error="";value;userInput="";constructor(t,s=true){const{input:e=stdin,output:i=stdout,render:n,signal:o,...u}=t;this.opts=u,this.onKeypress=this.onKeypress.bind(this),this.close=this.close.bind(this),this.render=this.render.bind(this),this._render=n.bind(this),this._track=s,this._abortSignal=o,this.input=e,this.output=i;}unsubscribe(){this._subscribers.clear();}setSubscriber(t,s){const e=this._subscribers.get(t)??[];e.push(s),this._subscribers.set(t,e);}on(t,s){this.setSubscriber(t,{cb:s});}once(t,s){this.setSubscriber(t,{cb:s,once:true});}emit(t,...s){const e=this._subscribers.get(t)??[],i=[];for(const n of e)n.cb(...s),n.once&&i.push(()=>e.splice(e.indexOf(n),1));for(const n of i)n();}prompt(){return new Promise(t=>{if(this._abortSignal){if(this._abortSignal.aborted)return this.state="cancel",this.close(),t(k);this._abortSignal.addEventListener("abort",()=>{this.state="cancel",this.close();},{once:true});}this.rl=b__default.createInterface({input:this.input,tabSize:2,prompt:"",escapeCodeTimeout:50,terminal:true}),this.rl.prompt(),this.opts.initialUserInput!==void 0&&this._setUserInput(this.opts.initialUserInput,true),this.input.on("keypress",this.onKeypress),w$1(this.input,true),this.output.on("resize",this.render),this.render(),this.once("submit",()=>{this.output.write(srcExports.cursor.show),this.output.off("resize",this.render),w$1(this.input,false),t(this.value);}),this.once("cancel",()=>{this.output.write(srcExports.cursor.show),this.output.off("resize",this.render),w$1(this.input,false),t(k);});})}_isActionKey(t,s){return t===" "}_shouldSubmit(t,s){return true}_setValue(t){this.value=t,this.emit("value",this.value);}_setUserInput(t,s){this.userInput=t??"",this.emit("userInput",this.userInput),s&&this._track&&this.rl&&(this.rl.write(this.userInput),this._cursor=this.rl.cursor);}_clearUserInput(){this.rl?.write(null,{ctrl:true,name:"u"}),this._setUserInput("");}onKeypress(t,s){if(this._track&&s.name!=="return"&&(s.name&&this._isActionKey(t,s)&&this.rl?.write(null,{ctrl:true,name:"h"}),this._cursor=this.rl?.cursor??0,this._setUserInput(this.rl?.line)),this.state==="error"&&(this.state="active"),s?.name&&(!this._track&&h.aliases.has(s.name)&&this.emit("cursor",h.aliases.get(s.name)),h.actions.has(s.name)&&this.emit("cursor",s.name)),t&&(t.toLowerCase()==="y"||t.toLowerCase()==="n")&&this.emit("confirm",t.toLowerCase()==="y"),this.emit("key",t?.toLowerCase(),s),s?.name==="return"&&this._shouldSubmit(t,s)){if(this.opts.validate){const e=this.opts.validate(this.value);e&&(this.error=e instanceof Error?e.message:e,this.state="error",this.rl?.write(this.userInput));}this.state!=="error"&&(this.state="submit");}C([t,s?.name,s?.sequence],"cancel")&&(this.state="cancel"),(this.state==="submit"||this.state==="cancel")&&this.emit("finalize"),this.render(),(this.state==="submit"||this.state==="cancel")&&this.close();}close(){this.input.unpipe(),this.input.removeListener("keypress",this.onKeypress),this.output.write(`
|
|
443
|
+
`),w$1(this.input,false),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe();}restoreCursor(){const t=wrapAnsi(this._prevFrame,process.stdout.columns,{hard:true,trim:false}).split(`
|
|
444
|
+
`).length-1;this.output.write(srcExports.cursor.move(-999,t*-1));}render(){const t=wrapAnsi(this._render(this)??"",process.stdout.columns,{hard:true,trim:false});if(t!==this._prevFrame){if(this.state==="initial")this.output.write(srcExports.cursor.hide);else {const s=z$1(this._prevFrame,t),e=L(this.output);if(this.restoreCursor(),s){const i=Math.max(0,s.numLinesAfter-e),n=Math.max(0,s.numLinesBefore-e);let o=s.lines.find(u=>u>=i);if(o===void 0){this._prevFrame=t;return}if(s.lines.length===1){this.output.write(srcExports.cursor.move(0,o-n)),this.output.write(srcExports.erase.lines(1));const u=t.split(`
|
|
445
|
+
`);this.output.write(u[o]),this._prevFrame=t,this.output.write(srcExports.cursor.move(0,u.length-o-1));return}else if(s.lines.length>1){if(i<n)o=i;else {const a=o-n;a>0&&this.output.write(srcExports.cursor.move(0,a));}this.output.write(srcExports.erase.down());const u=t.split(`
|
|
446
|
+
`).slice(o);this.output.write(u.join(`
|
|
447
|
+
`)),this._prevFrame=t;return}}this.output.write(srcExports.erase.down());}this.output.write(t),this.state==="initial"&&(this.state="active"),this._prevFrame=t;}}};let nt=class extends m{options;cursor=0;get _value(){return this.options[this.cursor].value}get _enabledOptions(){return this.options.filter(t=>t.disabled!==true)}toggleAll(){const t=this._enabledOptions,s=this.value!==void 0&&this.value.length===t.length;this.value=s?[]:t.map(e=>e.value);}toggleInvert(){const t=this.value;if(!t)return;const s=this._enabledOptions.filter(e=>!t.includes(e.value));this.value=s.map(e=>e.value);}toggleValue(){this.value===void 0&&(this.value=[]);const t=this.value.includes(this._value);this.value=t?this.value.filter(s=>s!==this._value):[...this.value,this._value];}constructor(t){super(t,false),this.options=t.options,this.value=[...t.initialValues??[]];const s=Math.max(this.options.findIndex(({value:e})=>e===t.cursorAt),0);this.cursor=this.options[s].disabled?f(s,1,this.options):s,this.on("key",e=>{e==="a"&&this.toggleAll(),e==="i"&&this.toggleInvert();}),this.on("cursor",e=>{switch(e){case "left":case "up":this.cursor=f(this.cursor,-1,this.options);break;case "down":case "right":this.cursor=f(this.cursor,1,this.options);break;case "space":this.toggleValue();break}});}};let ut$1 = class ut extends m{options;cursor=0;get _selectedValue(){return this.options[this.cursor]}changeValue(){this.value=this._selectedValue.value;}constructor(t){super(t,false),this.options=t.options;const s=this.options.findIndex(({value:i})=>i===t.initialValue),e=s===-1?0:s;this.cursor=this.options[e].disabled?f(e,1,this.options):e,this.changeValue(),this.on("cursor",i=>{switch(i){case "left":case "up":this.cursor=f(this.cursor,-1,this.options);break;case "down":case "right":this.cursor=f(this.cursor,1,this.options);break}this.changeValue();});}};let ht$1 = class ht extends m{get userInputWithCursor(){if(this.state==="submit")return this.userInput;const t=this.userInput;if(this.cursor>=t.length)return `${this.userInput}\u2588`;const s=t.slice(0,this.cursor),[e,...i]=t.slice(this.cursor);return `${s}${styleText("inverse",e)}${i.join("")}`}get cursor(){return this._cursor}constructor(t){super({...t,initialUserInput:t.initialUserInput??t.initialValue}),this.on("userInput",s=>{this._setValue(s);}),this.on("finalize",()=>{this.value||(this.value=t.defaultValue),this.value===void 0&&(this.value="");});}};
|
|
448
|
+
|
|
449
|
+
function ee(){return V.platform!=="win32"?V.env.TERM!=="linux":!!V.env.CI||!!V.env.WT_SESSION||!!V.env.TERMINUS_SUBLIME||V.env.ConEmuTask==="{cmd::Cmder}"||V.env.TERM_PROGRAM==="Terminus-Sublime"||V.env.TERM_PROGRAM==="vscode"||V.env.TERM==="xterm-256color"||V.env.TERM==="alacritty"||V.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}const tt=ee(),ot=()=>process.env.CI==="true",w=(t,i)=>tt?t:i,Tt=w("\u25C6","*"),at=w("\u25A0","x"),ut=w("\u25B2","x"),H=w("\u25C7","o"),lt=w("\u250C","T"),$=w("\u2502","|"),x=w("\u2514","\u2014"),z=w("\u25CF",">"),U=w("\u25CB"," "),et=w("\u25FB","[\u2022]"),K=w("\u25FC","[+]"),Y=w("\u25FB","[ ]"),st=w("\u2500","-"),ct=w("\u256E","+"),Gt=w("\u251C","+"),$t=w("\u256F","+"),ht=w("\u25CF","\u2022"),pt=w("\u25C6","*"),mt=w("\u25B2","!"),gt=w("\u25A0","x"),P=t=>{switch(t){case "initial":case "active":return styleText("cyan",Tt);case "cancel":return styleText("red",at);case "error":return styleText("yellow",ut);case "submit":return styleText("green",H)}},yt=t=>{switch(t){case "initial":case "active":return styleText("cyan",$);case "cancel":return styleText("red",$);case "error":return styleText("yellow",$);case "submit":return styleText("green",$)}},Ot=(t,i,s,r,u,n=false)=>{let a=i,c=0;if(n)for(let o=r-1;o>=s&&(a-=t[o].length,c++,!(a<=u));o--);else for(let o=s;o<r&&(a-=t[o].length,c++,!(a<=u));o++);return {lineCount:a,removals:c}},F=({cursor:t,options:i,style:s,output:r=process.stdout,maxItems:u=Number.POSITIVE_INFINITY,columnPadding:n=0,rowPadding:a=4})=>{const c=A(r)-n,o=L(r),l=styleText("dim","..."),d=Math.max(o-a,0),g=Math.max(Math.min(u,d),5);let p=0;t>=g-3&&(p=Math.max(Math.min(t-g+3,i.length-g),0));let f=g<i.length&&p>0,h=g<i.length&&p+g<i.length;const I=Math.min(p+g,i.length),m=[];let y=0;f&&y++,h&&y++;const v=p+(f?1:0),C=I-(h?1:0);for(let b=v;b<C;b++){const G=wrapAnsi(s(i[b],b===t),c,{hard:true,trim:false}).split(`
|
|
450
|
+
`);m.push(G),y+=G.length;}if(y>d){let b=0,G=0,M=y;const N=t-v;let O=d;const j=()=>Ot(m,M,0,N,O),k=()=>Ot(m,M,N+1,m.length,O,true);f?({lineCount:M,removals:b}=j(),M>O&&(h||(O-=1),{lineCount:M,removals:G}=k())):(h||(O-=1),{lineCount:M,removals:G}=k(),M>O&&(O-=1,{lineCount:M,removals:b}=j())),b>0&&(f=true,m.splice(0,b)),G>0&&(h=true,m.splice(m.length-G,G));}const S=[];f&&S.push(l);for(const b of m)for(const G of b)S.push(G);return h&&S.push(l),S};const he=async(t,i)=>{const s={},r=Object.keys(t);for(const u of r){const n=t[u],a=await n({results:s})?.catch(c=>{throw c});if(typeof i?.onCancel=="function"&&q(a)){s[u]="canceled",i.onCancel({results:s});continue}s[u]=a;}return s},R={message:(t=[],{symbol:i=styleText("gray",$),secondarySymbol:s=styleText("gray",$),output:r=process.stdout,spacing:u=1,withGuide:n}={})=>{const a=[],c=n??h.withGuide,o=c?s:"",l=c?`${i} `:"",d=c?`${s} `:"";for(let p=0;p<u;p++)a.push(o);const g=Array.isArray(t)?t:t.split(`
|
|
451
|
+
`);if(g.length>0){const[p,...f]=g;p.length>0?a.push(`${l}${p}`):a.push(c?i:"");for(const h of f)h.length>0?a.push(`${d}${h}`):a.push(c?s:"");}r.write(`${a.join(`
|
|
452
|
+
`)}
|
|
453
|
+
`);},info:(t,i)=>{R.message(t,{...i,symbol:styleText("blue",ht)});},success:(t,i)=>{R.message(t,{...i,symbol:styleText("green",pt)});},step:(t,i)=>{R.message(t,{...i,symbol:styleText("green",H)});},warn:(t,i)=>{R.message(t,{...i,symbol:styleText("yellow",mt)});},warning:(t,i)=>{R.warn(t,i);},error:(t,i)=>{R.message(t,{...i,symbol:styleText("red",gt)});}},me=(t="",i)=>{const s=process.stdout,r=`${styleText("gray",x)} `;s.write(`${r}${styleText("red",t)}
|
|
454
|
+
|
|
455
|
+
`);},ge=(t="",i)=>{const s=process.stdout,r=`${styleText("gray",lt)} `;s.write(`${r}${t}
|
|
456
|
+
`);},ye=(t="",i)=>{const s=process.stdout,r=`${styleText("gray",$)}
|
|
457
|
+
${styleText("gray",x)} `;s.write(`${r}${t}
|
|
458
|
+
|
|
459
|
+
`);},Q=(t,i)=>t.split(`
|
|
460
|
+
`).map(s=>i(s)).join(`
|
|
461
|
+
`),ve=t=>{const i=(r,u)=>{const n=r.label??String(r.value);return u==="disabled"?`${styleText("gray",Y)} ${Q(n,a=>styleText(["strikethrough","gray"],a))}${r.hint?` ${styleText("dim",`(${r.hint??"disabled"})`)}`:""}`:u==="active"?`${styleText("cyan",et)} ${n}${r.hint?` ${styleText("dim",`(${r.hint})`)}`:""}`:u==="selected"?`${styleText("green",K)} ${Q(n,a=>styleText("dim",a))}${r.hint?` ${styleText("dim",`(${r.hint})`)}`:""}`:u==="cancelled"?`${Q(n,a=>styleText(["strikethrough","dim"],a))}`:u==="active-selected"?`${styleText("green",K)} ${n}${r.hint?` ${styleText("dim",`(${r.hint})`)}`:""}`:u==="submitted"?`${Q(n,a=>styleText("dim",a))}`:`${styleText("dim",Y)} ${Q(n,a=>styleText("dim",a))}`},s=t.required??true;return new nt({options:t.options,signal:t.signal,input:t.input,output:t.output,initialValues:t.initialValues,required:s,cursorAt:t.cursorAt,validate(r){if(s&&(r===void 0||r.length===0))return `Please select at least one option.
|
|
462
|
+
${styleText("reset",styleText("dim",`Press ${styleText(["gray","bgWhite","inverse"]," space ")} to select, ${styleText("gray",styleText("bgWhite",styleText("inverse"," enter ")))} to submit`))}`},render(){const r=t.withGuide??h.withGuide,u=W(t.output,t.message,r?`${yt(this.state)} `:"",`${P(this.state)} `),n=`${r?`${styleText("gray",$)}
|
|
463
|
+
`:""}${u}
|
|
464
|
+
`,a=this.value??[],c=(o,l)=>{if(o.disabled)return i(o,"disabled");const d=a.includes(o.value);return l&&d?i(o,"active-selected"):d?i(o,"selected"):i(o,l?"active":"inactive")};switch(this.state){case "submit":{const o=this.options.filter(({value:d})=>a.includes(d)).map(d=>i(d,"submitted")).join(styleText("dim",", "))||styleText("dim","none"),l=W(t.output,o,r?`${styleText("gray",$)} `:"");return `${n}${l}`}case "cancel":{const o=this.options.filter(({value:d})=>a.includes(d)).map(d=>i(d,"cancelled")).join(styleText("dim",", "));if(o.trim()==="")return `${n}${styleText("gray",$)}`;const l=W(t.output,o,r?`${styleText("gray",$)} `:"");return `${n}${l}${r?`
|
|
465
|
+
${styleText("gray",$)}`:""}`}case "error":{const o=r?`${styleText("yellow",$)} `:"",l=this.error.split(`
|
|
466
|
+
`).map((p,f)=>f===0?`${r?`${styleText("yellow",x)} `:""}${styleText("yellow",p)}`:` ${p}`).join(`
|
|
467
|
+
`),d=n.split(`
|
|
468
|
+
`).length,g=l.split(`
|
|
469
|
+
`).length+1;return `${n}${o}${F({output:t.output,options:this.options,cursor:this.cursor,maxItems:t.maxItems,columnPadding:o.length,rowPadding:d+g,style:c}).join(`
|
|
470
|
+
${o}`)}
|
|
471
|
+
${l}
|
|
472
|
+
`}default:{const o=r?`${styleText("cyan",$)} `:"",l=n.split(`
|
|
473
|
+
`).length,d=r?2:1;return `${n}${o}${F({output:t.output,options:this.options,cursor:this.cursor,maxItems:t.maxItems,columnPadding:o.length,rowPadding:l+d,style:c}).join(`
|
|
474
|
+
${o}`)}
|
|
475
|
+
${r?styleText("cyan",x):""}
|
|
476
|
+
`}}}}).prompt()},we=t=>styleText("dim",t),be=(t,i,s)=>{const r={hard:true,trim:false},u=wrapAnsi(t,i,r).split(`
|
|
477
|
+
`),n=u.reduce((o,l)=>Math.max(fastStringWidth(l),o),0),a=u.map(s).reduce((o,l)=>Math.max(fastStringWidth(l),o),0),c=i-(a-n);return wrapAnsi(t,c,r)},Se=(t="",i="",s)=>{const r=V.stdout,n=we,a=["",...be(t,A(r)-6,n).split(`
|
|
478
|
+
`).map(n),""],c=fastStringWidth(i),o=Math.max(a.reduce((p,f)=>{const h=fastStringWidth(f);return h>p?h:p},0),c)+2,l=a.map(p=>`${styleText("gray",$)} ${p}${" ".repeat(o-fastStringWidth(p))}${styleText("gray",$)}`).join(`
|
|
479
|
+
`),d=`${styleText("gray",$)}
|
|
480
|
+
`,g=Gt;r.write(`${d}${styleText("green",H)} ${styleText("reset",i)} ${styleText("gray",st.repeat(Math.max(o-c-1,1))+ct)}
|
|
481
|
+
${l}
|
|
482
|
+
${styleText("gray",g+st.repeat(o+2)+$t)}
|
|
483
|
+
`);},Te=t=>styleText("magenta",t),ft=({indicator:t="dots",onCancel:i,output:s=process.stdout,cancelMessage:r,errorMessage:u,frames:n=tt?["\u25D2","\u25D0","\u25D3","\u25D1"]:["\u2022","o","O","0"],delay:a=tt?80:120,signal:c,...o}={})=>{const l=ot();let d,g,p=false,f=false,h$1="",I,m=performance.now();const y=A(s),v=o?.styleFrame??Te,C=_=>{const A=_>1?u??h.messages.error:r??h.messages.cancel;f=_===1,p&&(W(A,_),f&&typeof i=="function"&&i());},S=()=>C(2),b=()=>C(1),G=()=>{process.on("uncaughtExceptionMonitor",S),process.on("unhandledRejection",S),process.on("SIGINT",b),process.on("SIGTERM",b),process.on("exit",C),c&&c.addEventListener("abort",b);},M=()=>{process.removeListener("uncaughtExceptionMonitor",S),process.removeListener("unhandledRejection",S),process.removeListener("SIGINT",b),process.removeListener("SIGTERM",b),process.removeListener("exit",C),c&&c.removeEventListener("abort",b);},N=()=>{if(I===void 0)return;l&&s.write(`
|
|
484
|
+
`);const _=wrapAnsi(I,y,{hard:true,trim:false}).split(`
|
|
485
|
+
`);_.length>1&&s.write(srcExports.cursor.up(_.length-1)),s.write(srcExports.cursor.to(0)),s.write(srcExports.erase.down());},O=_=>_.replace(/\.+$/,""),j=_=>{const A=(performance.now()-_)/1e3,L=Math.floor(A/60),D=Math.floor(A%60);return L>0?`[${L}m ${D}s]`:`[${D}s]`},k=o.withGuide??h.withGuide,rt=(_="")=>{p=true,d=R$1({output:s}),h$1=O(_),m=performance.now(),k&&s.write(`${styleText("gray",$)}
|
|
486
|
+
`);let A=0,L=0;G(),g=setInterval(()=>{if(l&&h$1===I)return;N(),I=h$1;const D=v(n[A]);let Z;if(l)Z=`${D} ${h$1}...`;else if(t==="timer")Z=`${D} ${h$1} ${j(m)}`;else {const kt=".".repeat(Math.floor(L)).slice(0,3);Z=`${D} ${h$1}${kt}`;}const Bt=wrapAnsi(Z,y,{hard:true,trim:false});s.write(Bt),A=A+1<n.length?A+1:0,L=L<4?L+.125:0;},a);},W=(_="",A=0,L=false)=>{if(!p)return;p=false,clearInterval(g),N();const D=A===0?styleText("green",H):A===1?styleText("red",at):styleText("red",ut);h$1=_??h$1,L||(t==="timer"?s.write(`${D} ${h$1} ${j(m)}
|
|
487
|
+
`):s.write(`${D} ${h$1}
|
|
488
|
+
`)),M(),d();};return {start:rt,stop:(_="")=>W(_,0),message:(_="")=>{h$1=O(_??h$1);},cancel:(_="")=>W(_,1),error:(_="")=>W(_,2),clear:()=>W("",0,true),get isCancelled(){return f}}};const it=(t,i)=>t.includes(`
|
|
489
|
+
`)?t.split(`
|
|
490
|
+
`).map(s=>i(s)).join(`
|
|
491
|
+
`):i(t),xe=t=>{const i=(s,r)=>{const u=s.label??String(s.value);switch(r){case "disabled":return `${styleText("gray",U)} ${it(u,n=>styleText("gray",n))}${s.hint?` ${styleText("dim",`(${s.hint??"disabled"})`)}`:""}`;case "selected":return `${it(u,n=>styleText("dim",n))}`;case "active":return `${styleText("green",z)} ${u}${s.hint?` ${styleText("dim",`(${s.hint})`)}`:""}`;case "cancelled":return `${it(u,n=>styleText(["strikethrough","dim"],n))}`;default:return `${styleText("dim",U)} ${it(u,n=>styleText("dim",n))}`}};return new ut$1({options:t.options,signal:t.signal,input:t.input,output:t.output,initialValue:t.initialValue,render(){const s=t.withGuide??h.withGuide,r=`${P(this.state)} `,u=`${yt(this.state)} `,n=W(t.output,t.message,u,r),a=`${s?`${styleText("gray",$)}
|
|
492
|
+
`:""}${n}
|
|
493
|
+
`;switch(this.state){case "submit":{const c=s?`${styleText("gray",$)} `:"",o=W(t.output,i(this.options[this.cursor],"selected"),c);return `${a}${o}`}case "cancel":{const c=s?`${styleText("gray",$)} `:"",o=W(t.output,i(this.options[this.cursor],"cancelled"),c);return `${a}${o}${s?`
|
|
494
|
+
${styleText("gray",$)}`:""}`}default:{const c=s?`${styleText("cyan",$)} `:"",o=s?styleText("cyan",x):"",l=a.split(`
|
|
495
|
+
`).length,d=s?2:1;return `${a}${c}${F({output:t.output,cursor:this.cursor,options:this.options,maxItems:t.maxItems,columnPadding:c.length,rowPadding:l+d,style:(g,p)=>i(g,g.disabled?"disabled":p?"active":"inactive")}).join(`
|
|
496
|
+
${c}`)}
|
|
497
|
+
${o}
|
|
498
|
+
`}}}}).prompt()};`${styleText("gray",$)} `;const Pe=t=>new ht$1({validate:t.validate,placeholder:t.placeholder,defaultValue:t.defaultValue,initialValue:t.initialValue,output:t.output,signal:t.signal,input:t.input,render(){const i=t?.withGuide??h.withGuide,s=`${`${i?`${styleText("gray",$)}
|
|
499
|
+
`:""}${P(this.state)} `}${t.message}
|
|
500
|
+
`,r=t.placeholder?styleText("inverse",t.placeholder[0])+styleText("dim",t.placeholder.slice(1)):styleText(["inverse","hidden"],"_"),u=this.userInput?this.userInputWithCursor:r,n=this.value??"";switch(this.state){case "error":{const a=this.error?` ${styleText("yellow",this.error)}`:"",c=i?`${styleText("yellow",$)} `:"",o=i?styleText("yellow",x):"";return `${s.trim()}
|
|
501
|
+
${c}${u}
|
|
502
|
+
${o}${a}
|
|
503
|
+
`}case "submit":{const a=n?` ${styleText("dim",n)}`:"",c=i?styleText("gray",$):"";return `${s}${c}${a}`}case "cancel":{const a=n?` ${styleText(["strikethrough","dim"],n)}`:"",c=i?styleText("gray",$):"";return `${s}${c}${a}${n.trim()?`
|
|
504
|
+
${c}`:""}`}default:{const a=i?`${styleText("cyan",$)} `:"",c=i?styleText("cyan",x):"";return `${s}${a}${u}
|
|
505
|
+
${c}
|
|
506
|
+
`}}}}).prompt();
|
|
507
|
+
|
|
508
|
+
// from https://github.com/jashkenas/underscore/blob/master/modules/template.js
|
|
509
|
+
const escapeMap = {
|
|
510
|
+
"&": "&",
|
|
511
|
+
"<": "<",
|
|
512
|
+
">": ">",
|
|
513
|
+
'"': """,
|
|
514
|
+
};
|
|
515
|
+
const ESCAPE_REGEX = /[&<>"]/g;
|
|
516
|
+
const _ = {
|
|
517
|
+
escape(s) {
|
|
518
|
+
return s.replace(ESCAPE_REGEX, (match) => escapeMap[match]);
|
|
519
|
+
},
|
|
520
|
+
};
|
|
521
|
+
// When customizing `_.templateSettings`, if you don't want to define an
|
|
522
|
+
// interpolation, evaluation or escaping regex, we need one that is
|
|
523
|
+
// guaranteed not to match.
|
|
524
|
+
var noMatch = /(.)^/;
|
|
525
|
+
// Certain characters need to be escaped so that they can be put into a
|
|
526
|
+
// string literal.
|
|
527
|
+
var escapes = {
|
|
528
|
+
"'": "'",
|
|
529
|
+
"\\": "\\",
|
|
530
|
+
"\r": "r",
|
|
531
|
+
"\n": "n",
|
|
532
|
+
"\u2028": "u2028",
|
|
533
|
+
"\u2029": "u2029",
|
|
534
|
+
};
|
|
535
|
+
var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
|
|
536
|
+
function escapeChar(match) {
|
|
537
|
+
return "\\" + escapes[match];
|
|
538
|
+
}
|
|
539
|
+
// In order to prevent third-party code injection through
|
|
540
|
+
// `_.templateSettings.variable`, we test it against the following regular
|
|
541
|
+
// expression. It is intentionally a bit more liberal than just matching valid
|
|
542
|
+
// identifiers, but still prevents possible loopholes through defaults or
|
|
543
|
+
// destructuring assignment.
|
|
544
|
+
var bareIdentifier = /^\s*(\w|\$)+\s*$/;
|
|
545
|
+
// JavaScript micro-templating, similar to John Resig's implementation.
|
|
546
|
+
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
|
547
|
+
// and correctly escapes quotes within interpolated code.
|
|
548
|
+
// NB: `oldSettings` only exists for backwards compatibility.
|
|
549
|
+
function compileTemplate(text) {
|
|
550
|
+
const settings = {
|
|
551
|
+
evaluate: /<%([\s\S]+?)%>/g,
|
|
552
|
+
interpolate: /<%=([\s\S]+?)%>/g,
|
|
553
|
+
escape: /<%-([\s\S]+?)%>/g,
|
|
554
|
+
};
|
|
555
|
+
// remove spaces before and newlines after delimiters
|
|
556
|
+
text = text.replace(/%>\r?\n/g, "%>").replace(/[ \t]+<%/g, "<%");
|
|
557
|
+
// Combine delimiters into one regular expression via alternation.
|
|
558
|
+
var matcher = RegExp([
|
|
559
|
+
(settings.escape || noMatch).source,
|
|
560
|
+
(settings.interpolate || noMatch).source,
|
|
561
|
+
(settings.evaluate || noMatch).source,
|
|
562
|
+
].join("|") + "|$", "g");
|
|
563
|
+
// Compile the template source, escaping string literals appropriately.
|
|
564
|
+
var index = 0;
|
|
565
|
+
var source = "__p+='";
|
|
566
|
+
text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
|
|
567
|
+
source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
|
|
568
|
+
index = offset + match.length;
|
|
569
|
+
if (escape) {
|
|
570
|
+
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
|
571
|
+
}
|
|
572
|
+
else if (interpolate) {
|
|
573
|
+
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
|
574
|
+
}
|
|
575
|
+
else if (evaluate) {
|
|
576
|
+
source += "';\n" + evaluate + "\n__p+='";
|
|
577
|
+
}
|
|
578
|
+
// Adobe VMs need the match returned to produce the correct offset.
|
|
579
|
+
return match;
|
|
580
|
+
});
|
|
581
|
+
source += "';\n";
|
|
582
|
+
// @ts-expect-error unknown property
|
|
583
|
+
var argument = settings.variable;
|
|
584
|
+
if (argument) {
|
|
585
|
+
// Insure against third-party code injection. (CVE-2021-23358)
|
|
586
|
+
if (!bareIdentifier.test(argument))
|
|
587
|
+
throw new Error("variable is not a bare identifier: " + argument);
|
|
588
|
+
}
|
|
589
|
+
else {
|
|
590
|
+
// If a variable is not specified, place data values in local scope.
|
|
591
|
+
source = "with(obj||{}){\n" + source + "}\n";
|
|
592
|
+
argument = "obj";
|
|
593
|
+
}
|
|
594
|
+
source =
|
|
595
|
+
"var __t,__p='',__j=Array.prototype.join," +
|
|
596
|
+
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
|
597
|
+
source +
|
|
598
|
+
"return __p;\n";
|
|
599
|
+
var render;
|
|
600
|
+
try {
|
|
601
|
+
render = new Function(argument, "_", source);
|
|
602
|
+
}
|
|
603
|
+
catch (e) {
|
|
604
|
+
// @ts-expect-error unknown property
|
|
605
|
+
e.source = source;
|
|
606
|
+
throw e;
|
|
607
|
+
}
|
|
608
|
+
var template = function (data) {
|
|
609
|
+
// @ts-expect-error unknown this
|
|
610
|
+
return render.call(this, data, _);
|
|
611
|
+
};
|
|
612
|
+
// Provide the compiled source as a convenience for precompilation.
|
|
613
|
+
// @ts-expect-error unknown property
|
|
614
|
+
template.source = "function(" + argument + "){\n" + source + "}";
|
|
615
|
+
return template;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
var nodeTsconfigTemplate = "{\n \"$schema\": \"https://json.schemastore.org/tsconfig\",\n \"extends\": \"@tsconfig/node24/tsconfig.json\",\n \"compilerOptions\": {\n \"types\": [\"node\"],\n \"verbatimModuleSyntax\": true\n },\n \"include\": [\n \"src/**/*.ts\",\n \"test/**/*.ts\"\n ]\n}\n";
|
|
619
|
+
|
|
620
|
+
var bunTsconfigTemplate = "{\n \"compilerOptions\": {\n // Environment setup & latest features\n \"lib\": [\"ESNext\"],\n \"target\": \"ESNext\",\n \"module\": \"Preserve\",\n \"moduleDetection\": \"force\",\n \"jsx\": \"react-jsx\",\n \"allowJs\": true,\n \"types\": [\"bun\"],\n\n // Bundler mode\n \"moduleResolution\": \"bundler\",\n \"allowImportingTsExtensions\": true,\n \"verbatimModuleSyntax\": true,\n \"noEmit\": true,\n\n // Best practices\n \"strict\": true,\n \"skipLibCheck\": true,\n \"noFallthroughCasesInSwitch\": true,\n \"noUncheckedIndexedAccess\": true,\n \"noImplicitOverride\": true,\n\n // Some stricter flags (disabled by default)\n \"noUnusedLocals\": false,\n \"noUnusedParameters\": false,\n \"noPropertyAccessFromIndexSignature\": false\n },\n \"include\": [\n \"src/**/*.ts\",\n \"test/**/*.ts\"\n ]\n}\n";
|
|
621
|
+
|
|
622
|
+
var moduleTemplate = "import { type Module } from \"@tymber/core\";\nimport { HelloWorld } from \"./endpoints/HelloWorld.js\";\n\nexport const MainModule: Module = {\n name: \"main\",\n version: \"0.1.0\",\n\n async init(app) {\n app.endpoint(\"GET\", \"/hello\", HelloWorld);\n },\n};\n";
|
|
623
|
+
|
|
624
|
+
var nodeEntrypointTemplate = "import { App, toNodeHandler } from \"@tymber/core\";\n<% if (db === \"postgres\") { %>\nimport { PostgresDB } from \"@tymber/postgres\";\nimport * as pg from \"pg\";\n<% } %>\n<% if (db === \"sqlite\") { %>\nimport { open } from \"sqlite\";\nimport sqlite3 from \"sqlite3\";\nimport { SQLiteDB } from \"@tymber/sqlite\";\n<% } %>\n<% if (modules.includes(\"admin\")) { %>\nimport { AdminModule } from \"@tymber/admin\";\n<% } %>\n<% if (modules.includes(\"config\")) { %>\nimport { ConfigModule } from \"@tymber/config\";\n<% } %>\n<% if (modules.includes(\"openapi\")) { %>\nimport { OpenApiModule } from \"@tymber/openapi\";\n<% } %>\n<% if (modules.includes(\"user\")) { %>\nimport { UserModule } from \"@tymber/user\";\n<% } %>\nimport { MainModule } from \"./module.js\";\nimport { createServer } from \"node:http\";\n\nasync function main() {\n <% if (db === \"postgres\") { %>\n const pgPool = new pg.Pool({\n user: \"postgres\",\n password: \"changeit\",\n });\n\n const db = new PostgresDB(pgPool);\n <% } %>\n <% if (db === \"sqlite\") { %>\n const dbFile = await open({\n filename: \"/tmp/<%= projectName %>.db\",\n driver: sqlite3.Database,\n });\n\n const db = new SQLiteDB(dbFile);\n <% } %>\n\n const app = await App.create({\n components: [db],\n modules: [\n <% if (modules.includes(\"admin\")) { %>\n AdminModule,\n <% } %>\n <% if (modules.includes(\"config\")) { %>\n ConfigModule,\n <% } %>\n <% if (modules.includes(\"openapi\")) { %>\n OpenApiModule,\n <% } %>\n <% if (modules.includes(\"user\")) { %>\n UserModule,\n <% } %>\n MainModule\n ],\n });\n\n const httpServer = createServer(toNodeHandler(app.fetch));\n\n httpServer.listen(8080, () => {\n console.log(\"Server listening on http://localhost:8080\");\n });\n}\n\nmain().catch(console.error);\n";
|
|
625
|
+
|
|
626
|
+
var bunEntrypointTemplate = "import { App } from \"@tymber/core\";\n<% if (db === \"postgres\") { %>\nimport { PostgresDB } from \"@tymber/postgres\";\nimport * as pg from \"pg\";\n<% } %>\n<% if (db === \"sqlite\") { %>\nimport { open } from \"sqlite\";\nimport sqlite3 from \"sqlite3\";\nimport { SQLiteDB } from \"@tymber/sqlite\";\n<% } %>\n<% if (modules.includes(\"admin\")) { %>\nimport { AdminModule } from \"@tymber/admin\";\n<% } %>\n<% if (modules.includes(\"config\")) { %>\nimport { ConfigModule } from \"@tymber/config\";\n<% } %>\n<% if (modules.includes(\"openapi\")) { %>\nimport { OpenApiModule } from \"@tymber/openapi\";\n<% } %>\n<% if (modules.includes(\"user\")) { %>\nimport { UserModule } from \"@tymber/user\";\n<% } %>\nimport { MainModule } from \"./module.js\";\n\n<% if (db === \"postgres\") { %>\nconst pgPool = new pg.Pool({\n user: \"postgres\",\n password: \"changeit\",\n});\n\nconst db = new PostgresDB(pgPool);\n<% } %>\n<% if (db === \"sqlite\") { %>\nconst dbFile = await open({\n filename: \"/tmp/<%= projectName %>.db\",\n driver: sqlite3.Database,\n});\n\nconst db = new SQLiteDB(dbFile);\n<% } %>\n\nconst app = await App.create({\n components: [db],\n modules: [\n <% if (modules.includes(\"admin\")) { %>\n AdminModule,\n <% } %>\n <% if (modules.includes(\"config\")) { %>\n ConfigModule,\n <% } %>\n <% if (modules.includes(\"openapi\")) { %>\n OpenApiModule,\n <% } %>\n <% if (modules.includes(\"user\")) { %>\n UserModule,\n <% } %>\n MainModule\n ],\n});\n\nexport default {\n port: 8080,\n fetch: app.fetch,\n};\n";
|
|
627
|
+
|
|
628
|
+
var helloWorldTemplate = "import { Endpoint, type HttpContext } from \"@tymber/core\";\n\nexport class HelloWorld extends Endpoint {\n async handle(ctx: HttpContext) {\n return Response.json({ message: \"Hello World\" });\n }\n}\n";
|
|
629
|
+
|
|
630
|
+
var setupTestTemplate = "import { createTestDB } from \"@tymber/<%= db %>\";\n<% if (modules.includes(\"admin\")) { %>\nimport {\n type BaseTestContext,\n type AdminUserId,\n createTestApp,\n} from \"@tymber/core\";\nimport { AdminModule, initTestDB } from \"@tymber/admin\";\n<% } else { %>\nimport { type BaseTestContext, createTestApp } from \"@tymber/core\";\n<% } %>\n<% if (modules.includes(\"config\")) { %>\nimport { ConfigModule } from \"@tymber/config\";\n<% } %>\n<% if (modules.includes(\"openapi\")) { %>\nimport { OpenApiModule } from \"@tymber/openapi\";\n<% } %>\n<% if (modules.includes(\"user\")) { %>\nimport { UserModule } from \"@tymber/user\";\n<% } %>\nimport { MainModule } from \"../src/module.js\";\n\nexport interface TestContext extends BaseTestContext {\n <% if (modules.includes(\"admin\")) { %>\n adminSessionId: string;\n adminUserId: AdminUserId;\n <% } %>\n}\n\nexport async function setup(): Promise<TestContext> {\n const ctx = await createTestApp(() => createTestDB(), [\n <% if (modules.includes(\"admin\")) { %>\n AdminModule,\n <% } %>\n <% if (modules.includes(\"config\")) { %>\n ConfigModule,\n <% } %>\n <% if (modules.includes(\"openapi\")) { %>\n OpenApiModule,\n <% } %>\n <% if (modules.includes(\"user\")) { %>\n UserModule,\n <% } %>\n MainModule\n ]);\n <% if (modules.includes(\"admin\")) { %>\n const { adminSessionId, adminUserId } = await initTestDB(ctx.db);\n <% } %>\n <% if (modules.includes(\"config\")) { %>\n process.env.CONFIG_SECRET_KEYS = \"S3cr3T\";\n <% } %>\n\n return {\n ...ctx,\n <% if (modules.includes(\"admin\")) { %>\n adminSessionId,\n adminUserId,\n <% } %>\n };\n}\n";
|
|
631
|
+
|
|
632
|
+
var helloWorldTestTemplate = "<% if (isBunPackageManager) { %>\nimport { describe, it, beforeAll, afterAll } from \"bun:test\";\n<% } else { %>\nimport { describe, it, before, after } from \"node:test\";\n<% } %>\nimport * as assert from \"node:assert\";\nimport { setup, type TestContext } from \"../setup.js\";\n\ndescribe(\"HelloWorld\", () => {\n let ctx: TestContext;\n\n before<% if (isBunPackageManager) { %>All<% } %>(async () => {\n ctx = await setup();\n });\n\n after<% if (isBunPackageManager) { %>All<% } %>(() => ctx.close());\n\n it(\"should work\", async () => {\n const res = await fetch(`${ctx.baseUrl}/hello`);\n\n assert.equal(res.status, 200);\n });\n});\n";
|
|
633
|
+
|
|
634
|
+
const packageManager = (() => {
|
|
635
|
+
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
636
|
+
if (userAgent.startsWith("bun/"))
|
|
637
|
+
return "bun";
|
|
638
|
+
if (userAgent.startsWith("pnpm/"))
|
|
639
|
+
return "pnpm";
|
|
640
|
+
if (userAgent.startsWith("yarn/"))
|
|
641
|
+
return "yarn";
|
|
642
|
+
return "npm";
|
|
643
|
+
})();
|
|
644
|
+
const isBunPackageManager = packageManager === "bun";
|
|
645
|
+
async function main() {
|
|
646
|
+
ge("Welcome to Tymber project generator!");
|
|
647
|
+
const { projectName, db, modules } = await he({
|
|
648
|
+
projectName: () => Pe({
|
|
649
|
+
message: "Project name",
|
|
650
|
+
placeholder: "tymber-app",
|
|
651
|
+
initialValue: "tymber-app",
|
|
652
|
+
}),
|
|
653
|
+
db: () => xe({
|
|
654
|
+
message: "Database to use",
|
|
655
|
+
options: [
|
|
656
|
+
{ value: "postgres", label: "PostgreSQL" },
|
|
657
|
+
{ value: "sqlite", label: "SQLite" },
|
|
658
|
+
],
|
|
659
|
+
}),
|
|
660
|
+
modules: () => ve({
|
|
661
|
+
message: "Modules to include",
|
|
662
|
+
options: [
|
|
663
|
+
{ value: "admin", label: "Admin dashboard" },
|
|
664
|
+
{ value: "config", label: "Configuration management" },
|
|
665
|
+
{ value: "openapi", label: "OpenAPI console" },
|
|
666
|
+
{ value: "user", label: "User Management" },
|
|
667
|
+
],
|
|
668
|
+
required: false,
|
|
669
|
+
}),
|
|
670
|
+
}, {
|
|
671
|
+
onCancel: () => {
|
|
672
|
+
me("Operation cancelled.");
|
|
673
|
+
process.exit(0);
|
|
674
|
+
},
|
|
675
|
+
});
|
|
676
|
+
const projectDir = path.resolve(projectName);
|
|
677
|
+
await fs.mkdir(projectDir, { recursive: true });
|
|
678
|
+
const s = ft();
|
|
679
|
+
s.start(`Creating project in ${projectDir}...`);
|
|
680
|
+
const templateData = {
|
|
681
|
+
projectName,
|
|
682
|
+
isBunPackageManager,
|
|
683
|
+
db,
|
|
684
|
+
modules,
|
|
685
|
+
};
|
|
686
|
+
const dependencies = {
|
|
687
|
+
"@tymber/core": "latest",
|
|
688
|
+
[`@tymber/${db}`]: "latest",
|
|
689
|
+
};
|
|
690
|
+
for (const module of modules) {
|
|
691
|
+
dependencies[`@tymber/${module}`] = "latest";
|
|
692
|
+
}
|
|
693
|
+
const packageJsonContent = {
|
|
694
|
+
name: projectName,
|
|
695
|
+
version: "0.0.0",
|
|
696
|
+
type: "module",
|
|
697
|
+
scripts: isBunPackageManager
|
|
698
|
+
? {
|
|
699
|
+
start: "bun src/entrypoint.ts",
|
|
700
|
+
test: "bun test",
|
|
701
|
+
}
|
|
702
|
+
: {
|
|
703
|
+
start: "tsx src/entrypoint.ts",
|
|
704
|
+
test: "tsx --test test/**/*.test.ts",
|
|
705
|
+
},
|
|
706
|
+
dependencies,
|
|
707
|
+
devDependencies: isBunPackageManager
|
|
708
|
+
? {
|
|
709
|
+
"@types/bun": "latest",
|
|
710
|
+
typescript: "latest",
|
|
711
|
+
}
|
|
712
|
+
: {
|
|
713
|
+
"@tsconfig/node24": "latest",
|
|
714
|
+
"@types/node": "latest",
|
|
715
|
+
tsx: "latest",
|
|
716
|
+
typescript: "latest",
|
|
717
|
+
},
|
|
718
|
+
};
|
|
719
|
+
// package.json
|
|
720
|
+
await fs.writeFile(path.join(projectDir, "package.json"), JSON.stringify(packageJsonContent, null, 2));
|
|
721
|
+
// tsconfig.json
|
|
722
|
+
await fs.writeFile(path.join(projectDir, "tsconfig.json"), compileTemplate(isBunPackageManager ? bunTsconfigTemplate : nodeTsconfigTemplate)(templateData));
|
|
723
|
+
// src directory
|
|
724
|
+
const srcDir = path.join(projectDir, "src");
|
|
725
|
+
await fs.mkdir(srcDir, { recursive: true });
|
|
726
|
+
// src/entrypoint.ts
|
|
727
|
+
await fs.writeFile(path.join(srcDir, "entrypoint.ts"), compileTemplate(isBunPackageManager ? bunEntrypointTemplate : nodeEntrypointTemplate)(templateData));
|
|
728
|
+
// src/module.ts
|
|
729
|
+
await fs.writeFile(path.join(srcDir, "module.ts"), compileTemplate(moduleTemplate)(templateData));
|
|
730
|
+
// src/endpoints/HelloWorld.ts
|
|
731
|
+
const endpointsDir = path.join(srcDir, "endpoints");
|
|
732
|
+
await fs.mkdir(endpointsDir, { recursive: true });
|
|
733
|
+
await fs.writeFile(path.join(endpointsDir, "HelloWorld.ts"), compileTemplate(helloWorldTemplate)(templateData));
|
|
734
|
+
// tests
|
|
735
|
+
const testDir = path.join(projectDir, "test");
|
|
736
|
+
await fs.mkdir(path.join(testDir, "endpoints"), { recursive: true });
|
|
737
|
+
await fs.writeFile(path.join(testDir, "setup.ts"), compileTemplate(setupTestTemplate)(templateData));
|
|
738
|
+
await fs.writeFile(path.join(testDir, "endpoints", "HelloWorld.test.ts"), compileTemplate(helloWorldTestTemplate)(templateData));
|
|
739
|
+
// assets
|
|
740
|
+
const assetSubDirs = ["migrations", "static", "templates", "i18n"];
|
|
741
|
+
for (const subDir of assetSubDirs) {
|
|
742
|
+
const dirPath = path.join(projectDir, "assets", subDir);
|
|
743
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
744
|
+
await fs.writeFile(path.join(dirPath, ".gitkeep"), "");
|
|
745
|
+
}
|
|
746
|
+
s.stop("Project created successfully!");
|
|
747
|
+
Se(`Next steps:
|
|
748
|
+
cd ${projectName}
|
|
749
|
+
${packageManager} install
|
|
750
|
+
${packageManager} start`, "Done!");
|
|
751
|
+
ye("Happy coding!");
|
|
752
|
+
}
|
|
753
|
+
main().catch((err) => {
|
|
754
|
+
R.error(`Error creating project: ${err.message}`);
|
|
755
|
+
process.exit(1);
|
|
756
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tymber/create",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Scaffold a new Tymber project",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"author": "Damien ARRACHEQUESNE"
|
|
6
|
+
"author": "Damien ARRACHEQUESNE",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/tymber-framework/tymber.git"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"bin": {
|
|
13
|
+
"create-tymber": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"compile": "rollup -c",
|
|
17
|
+
"format:check": "prettier -c src/",
|
|
18
|
+
"format:fix": "prettier -w src/"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"tymber",
|
|
25
|
+
"typescript",
|
|
26
|
+
"framework"
|
|
27
|
+
]
|
|
7
28
|
}
|