create-sparkling-app 2.0.0 → 2.1.0-rc.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 +4 -0
- package/dist/core/project-builder/project-builder.js +52 -49
- package/dist/core/project-builder/template.js +46 -20
- package/dist/create-app/post-create.js +38 -10
- package/dist/create-app/user-prompts.js +109 -180
- package/dist/create-app.js +36 -6
- package/dist/index.js +37 -1
- package/dist/utils/spinner.js +60 -12
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -30,6 +30,10 @@ npx create-sparkling-app@latest my-app --verbose
|
|
|
30
30
|
|
|
31
31
|
Run `npx create-sparkling-app@latest --help` to see all available options.
|
|
32
32
|
|
|
33
|
+
## Local testing
|
|
34
|
+
|
|
35
|
+
When developing inside the Sparkling monorepo, see [LOCAL_TESTING.md](./LOCAL_TESTING.md) for building this CLI, running it from the workspace, and pointing `--template` at `template/sparkling-app-template`.
|
|
36
|
+
|
|
33
37
|
## What's Included
|
|
34
38
|
|
|
35
39
|
The generated project includes:
|
|
@@ -1,4 +1,37 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -7,7 +40,7 @@ exports.ProjectBuilder = void 0;
|
|
|
7
40
|
// Copyright (c) 2025 TikTok Pte. Ltd.
|
|
8
41
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
9
42
|
// LICENSE file in the root directory of this source tree.
|
|
10
|
-
const
|
|
43
|
+
const p = __importStar(require("@clack/prompts"));
|
|
11
44
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
12
45
|
const node_path_1 = __importDefault(require("node:path"));
|
|
13
46
|
const logger_1 = require("../../logger");
|
|
@@ -41,24 +74,14 @@ class ProjectBuilder {
|
|
|
41
74
|
}
|
|
42
75
|
const shouldCheckEmpty = this.config.checkEmpty ?? true;
|
|
43
76
|
if (shouldCheckEmpty && !this.config.override && node_fs_1.default.existsSync(this.config.targetDir) && !(0, common_1.isEmptyDir)(this.config.targetDir)) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
{ name: 'Continue and override files', value: 'yes' },
|
|
53
|
-
{ name: 'Cancel operation', value: 'no' },
|
|
54
|
-
],
|
|
55
|
-
},
|
|
56
|
-
]);
|
|
57
|
-
option = (0, template_1.checkCancel)(answer.choice);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
throw new template_1.UserCancelledError(error.message);
|
|
61
|
-
}
|
|
77
|
+
const option = await p.select({
|
|
78
|
+
message: `"${node_path_1.default.basename(this.config.targetDir)}" is not empty, please choose:`,
|
|
79
|
+
options: [
|
|
80
|
+
{ label: 'Continue and override files', value: 'yes' },
|
|
81
|
+
{ label: 'Cancel operation', value: 'no' },
|
|
82
|
+
],
|
|
83
|
+
});
|
|
84
|
+
(0, template_1.checkCancel)(option);
|
|
62
85
|
if (option === 'no') {
|
|
63
86
|
throw new template_1.UserCancelledError();
|
|
64
87
|
}
|
|
@@ -97,21 +120,11 @@ class ProjectBuilder {
|
|
|
97
120
|
async execute(_context) {
|
|
98
121
|
const shouldCheckEmpty = config.checkEmpty ?? true;
|
|
99
122
|
if (shouldCheckEmpty && !(0, common_1.isEmptyDir)(config.targetDir)) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
name: 'cont',
|
|
106
|
-
message: `Target directory ${config.targetDir} is not empty. Continue?`,
|
|
107
|
-
default: false,
|
|
108
|
-
},
|
|
109
|
-
]);
|
|
110
|
-
shouldContinue = (0, template_1.checkCancel)(answer.cont);
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
throw new template_1.UserCancelledError(error.message);
|
|
114
|
-
}
|
|
123
|
+
const shouldContinue = await p.confirm({
|
|
124
|
+
message: `Target directory ${config.targetDir} is not empty. Continue?`,
|
|
125
|
+
initialValue: false,
|
|
126
|
+
});
|
|
127
|
+
(0, template_1.checkCancel)(shouldContinue);
|
|
115
128
|
if (!shouldContinue) {
|
|
116
129
|
throw new template_1.UserCancelledError();
|
|
117
130
|
}
|
|
@@ -133,21 +146,11 @@ class ProjectBuilder {
|
|
|
133
146
|
description: 'Ensure target directory is empty before scaffolding',
|
|
134
147
|
async execute() {
|
|
135
148
|
if (node_fs_1.default.existsSync(targetDir) && !(0, common_1.isEmptyDir)(targetDir)) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
name: 'cont',
|
|
142
|
-
message: `Target directory ${targetDir} is not empty. Continue?`,
|
|
143
|
-
default: false,
|
|
144
|
-
},
|
|
145
|
-
]);
|
|
146
|
-
shouldContinue = (0, template_1.checkCancel)(answer.cont);
|
|
147
|
-
}
|
|
148
|
-
catch (error) {
|
|
149
|
-
throw new template_1.UserCancelledError(error.message);
|
|
150
|
-
}
|
|
149
|
+
const shouldContinue = await p.confirm({
|
|
150
|
+
message: `Target directory ${targetDir} is not empty. Continue?`,
|
|
151
|
+
initialValue: false,
|
|
152
|
+
});
|
|
153
|
+
(0, template_1.checkCancel)(shouldContinue);
|
|
151
154
|
if (!shouldContinue) {
|
|
152
155
|
throw new template_1.UserCancelledError();
|
|
153
156
|
}
|
|
@@ -1,4 +1,37 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -12,7 +45,7 @@ exports.updatePackageJson = updatePackageJson;
|
|
|
12
45
|
// Copyright (c) 2025 TikTok Pte. Ltd.
|
|
13
46
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
14
47
|
// LICENSE file in the root directory of this source tree.
|
|
15
|
-
const
|
|
48
|
+
const p = __importStar(require("@clack/prompts"));
|
|
16
49
|
const deepmerge_1 = __importDefault(require("deepmerge"));
|
|
17
50
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
18
51
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -26,6 +59,9 @@ class UserCancelledError extends Error {
|
|
|
26
59
|
}
|
|
27
60
|
exports.UserCancelledError = UserCancelledError;
|
|
28
61
|
function checkCancel(value) {
|
|
62
|
+
if (p.isCancel(value)) {
|
|
63
|
+
throw new UserCancelledError();
|
|
64
|
+
}
|
|
29
65
|
return value;
|
|
30
66
|
}
|
|
31
67
|
function formatProjectName(input) {
|
|
@@ -98,29 +134,19 @@ function mergePackageJson(targetPackage, extraPackage) {
|
|
|
98
134
|
}
|
|
99
135
|
async function copyTemplateWithVariables({ checkEmpty = true, from, isMergePackageJson, override = false, packageName, renameFiles = { gitignore: '.gitignore' }, skipFiles = [], to, variables = {}, version, }) {
|
|
100
136
|
if (checkEmpty && !override && node_fs_1.default.existsSync(to) && !(0, common_1.isEmptyDir)(to)) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{ name: 'Continue and override files', value: 'yes' },
|
|
110
|
-
{ name: 'Cancel operation', value: 'no' },
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
]);
|
|
114
|
-
option = checkCancel(answer.choice);
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
throw new UserCancelledError(error.message);
|
|
118
|
-
}
|
|
137
|
+
const option = await p.select({
|
|
138
|
+
message: `"${node_path_1.default.basename(to)}" is not empty, please choose:`,
|
|
139
|
+
options: [
|
|
140
|
+
{ label: 'Continue and override files', value: 'yes' },
|
|
141
|
+
{ label: 'Cancel operation', value: 'no' },
|
|
142
|
+
],
|
|
143
|
+
});
|
|
144
|
+
checkCancel(option);
|
|
119
145
|
if (option === 'no') {
|
|
120
146
|
throw new UserCancelledError();
|
|
121
147
|
}
|
|
122
148
|
}
|
|
123
|
-
const allSkipFiles = new Set(['dist', 'node_modules', ...skipFiles]);
|
|
149
|
+
const allSkipFiles = new Set(['dist', 'node_modules', 'Pods', '.gradle', ...skipFiles]);
|
|
124
150
|
node_fs_1.default.mkdirSync(to, { recursive: true });
|
|
125
151
|
for (const file of node_fs_1.default.readdirSync(from)) {
|
|
126
152
|
if (allSkipFiles.has(file)) {
|
|
@@ -1,4 +1,37 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.installDependencies = installDependencies;
|
|
4
37
|
exports.initializeGitRepo = initializeGitRepo;
|
|
@@ -8,6 +41,7 @@ exports.showCompletionNotes = showCompletionNotes;
|
|
|
8
41
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
9
42
|
// LICENSE file in the root directory of this source tree.
|
|
10
43
|
const node_child_process_1 = require("node:child_process");
|
|
44
|
+
const p = __importStar(require("@clack/prompts"));
|
|
11
45
|
const ui_1 = require("../ui");
|
|
12
46
|
const spinner_1 = require("../utils/spinner");
|
|
13
47
|
const verbose_1 = require("../utils/verbose");
|
|
@@ -48,7 +82,7 @@ async function installDependencies(distFolder, packageManager) {
|
|
|
48
82
|
if ((0, verbose_1.isVerboseEnabled)()) {
|
|
49
83
|
(0, verbose_1.verboseLog)(`Install failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
84
|
}
|
|
51
|
-
|
|
85
|
+
p.log.warn(`Failed to install dependencies. Run '${packageManager} install' manually.`);
|
|
52
86
|
return false;
|
|
53
87
|
}
|
|
54
88
|
}
|
|
@@ -60,7 +94,7 @@ async function initializeGitRepo(distFolder) {
|
|
|
60
94
|
(0, node_child_process_1.execSync)('git --version', { stdio: stdioMode });
|
|
61
95
|
}
|
|
62
96
|
catch {
|
|
63
|
-
|
|
97
|
+
p.log.warn('Git is not installed or not in PATH. Skipping git initialization.');
|
|
64
98
|
return;
|
|
65
99
|
}
|
|
66
100
|
s.start('Initializing git repository...');
|
|
@@ -72,7 +106,7 @@ async function initializeGitRepo(distFolder) {
|
|
|
72
106
|
}
|
|
73
107
|
catch (error) {
|
|
74
108
|
s.stop('Failed to initialize git repository');
|
|
75
|
-
|
|
109
|
+
p.log.warn('Failed to initialize git repository. Run "git init" manually.');
|
|
76
110
|
}
|
|
77
111
|
}
|
|
78
112
|
function detectPackageManager() {
|
|
@@ -120,7 +154,6 @@ function detectPackageManager() {
|
|
|
120
154
|
}
|
|
121
155
|
}
|
|
122
156
|
function showCompletionNotes(targetDir, packageManager, didInstall = false) {
|
|
123
|
-
console.log(ui_1.ui.success(`✔ Project created at ${targetDir}`));
|
|
124
157
|
const formatScriptCommand = (script) => {
|
|
125
158
|
const pm = packageManager ?? 'npm';
|
|
126
159
|
return pm === 'npm' ? `${pm} run ${script}` : `${pm} ${script}`;
|
|
@@ -134,14 +167,9 @@ function showCompletionNotes(targetDir, packageManager, didInstall = false) {
|
|
|
134
167
|
}
|
|
135
168
|
nextSteps.push(formatScriptCommand('run:ios'));
|
|
136
169
|
nextSteps.push(formatScriptCommand('run:android'));
|
|
137
|
-
console.log(ui_1.ui.headline('Next steps'));
|
|
138
|
-
nextSteps.forEach(step => console.log(ui_1.ui.headline(step)));
|
|
139
170
|
const tips = [
|
|
140
171
|
'iOS: ensure Xcode Command Line Tools are installed.',
|
|
141
172
|
'Android: ensure ANDROID_HOME and SDK platforms are set.',
|
|
142
173
|
];
|
|
143
|
-
tips.
|
|
144
|
-
console.log(ui_1.ui.tip(tip));
|
|
145
|
-
});
|
|
146
|
-
console.log(ui_1.ui.success('Successfully created app project!'));
|
|
174
|
+
p.note([...nextSteps, '', ...tips.map(t => ui_1.ui.tip(t))].join('\n'), `✔ Project created at ${targetDir}`);
|
|
147
175
|
}
|
|
@@ -1,7 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
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
|
+
})();
|
|
5
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
36
|
exports.askProjectName = askProjectName;
|
|
7
37
|
exports.askTemplate = askTemplate;
|
|
@@ -16,43 +46,23 @@ exports.confirmRemoveExistingDir = confirmRemoveExistingDir;
|
|
|
16
46
|
// Copyright (c) 2025 TikTok Pte. Ltd.
|
|
17
47
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
18
48
|
// LICENSE file in the root directory of this source tree.
|
|
19
|
-
const
|
|
49
|
+
const p = __importStar(require("@clack/prompts"));
|
|
20
50
|
const template_1 = require("../core/project-builder/template");
|
|
21
|
-
const ui_1 = require("../ui");
|
|
22
51
|
const constants_1 = require("./constants");
|
|
23
52
|
const android_dsl_1 = require("./android-dsl");
|
|
24
53
|
const namespace_1 = require("./namespace");
|
|
25
|
-
function handlePromptError(error) {
|
|
26
|
-
if (error instanceof Error) {
|
|
27
|
-
throw new template_1.UserCancelledError(error.message);
|
|
28
|
-
}
|
|
29
|
-
throw new template_1.UserCancelledError();
|
|
30
|
-
}
|
|
31
54
|
async function askProjectName(flags, defaultName = constants_1.DEFAULT_PROJECT_NAME) {
|
|
32
55
|
if (!flags.yes) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
validate(value) {
|
|
45
|
-
if (!value || value.length === 0)
|
|
46
|
-
return 'Project name is required';
|
|
47
|
-
return true;
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
]);
|
|
51
|
-
return (0, template_1.checkCancel)(projectName);
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
handlePromptError(error);
|
|
55
|
-
}
|
|
56
|
+
const projectName = await p.text({
|
|
57
|
+
message: 'Project name',
|
|
58
|
+
defaultValue: defaultName,
|
|
59
|
+
placeholder: defaultName,
|
|
60
|
+
validate(value) {
|
|
61
|
+
if (!value || value.length === 0)
|
|
62
|
+
return 'Project name is required';
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return (0, template_1.checkCancel)(projectName);
|
|
56
66
|
}
|
|
57
67
|
return defaultName;
|
|
58
68
|
}
|
|
@@ -60,23 +70,14 @@ async function askTemplate(flags, initial) {
|
|
|
60
70
|
if (initial)
|
|
61
71
|
return initial;
|
|
62
72
|
if (!flags.yes) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
{ value: constants_1.CUSTOM_TEMPLATE_OPTION, name: 'Custom template (Local path, Git URL, or npm package)' },
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
]);
|
|
75
|
-
return (0, template_1.checkCancel)(template);
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
handlePromptError(error);
|
|
79
|
-
}
|
|
73
|
+
const template = await p.select({
|
|
74
|
+
message: 'Choose a template',
|
|
75
|
+
options: [
|
|
76
|
+
{ value: constants_1.DEFAULT_TEMPLATE_NAME, label: 'sparkling-default (Official Sparkling starter project)' },
|
|
77
|
+
{ value: constants_1.CUSTOM_TEMPLATE_OPTION, label: 'Custom template (Local path, Git URL, or npm package)' },
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
return (0, template_1.checkCancel)(template);
|
|
80
81
|
}
|
|
81
82
|
return constants_1.DEFAULT_TEMPLATE_NAME;
|
|
82
83
|
}
|
|
@@ -84,87 +85,51 @@ async function askCustomTemplatePath(flags) {
|
|
|
84
85
|
if (flags.yes) {
|
|
85
86
|
throw new Error('Custom template requires interactive input or a direct --template path.');
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (!value || value.length === 0)
|
|
96
|
-
return 'Template path is required';
|
|
97
|
-
return true;
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
]);
|
|
101
|
-
return (0, template_1.checkCancel)(templatePath);
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
handlePromptError(error);
|
|
105
|
-
}
|
|
88
|
+
const templatePath = await p.text({
|
|
89
|
+
message: 'Enter custom template path, GitHub URL, or npm package',
|
|
90
|
+
validate(value) {
|
|
91
|
+
if (!value || value.length === 0)
|
|
92
|
+
return 'Template path is required';
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
return (0, template_1.checkCancel)(templatePath);
|
|
106
96
|
}
|
|
107
97
|
async function askAndroidDsl(flags) {
|
|
108
98
|
if (!flags.yes) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
{ value: 'groovy', name: 'Groovy (.gradle)' },
|
|
118
|
-
],
|
|
119
|
-
},
|
|
120
|
-
]);
|
|
121
|
-
return (0, template_1.checkCancel)(androidDsl) === 'groovy' ? 'groovy' : 'kts';
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
handlePromptError(error);
|
|
125
|
-
}
|
|
99
|
+
const androidDsl = await p.select({
|
|
100
|
+
message: 'Android Gradle build files',
|
|
101
|
+
options: [
|
|
102
|
+
{ value: 'kts', label: 'Kotlin DSL (.gradle.kts)' },
|
|
103
|
+
{ value: 'groovy', label: 'Groovy (.gradle)' },
|
|
104
|
+
],
|
|
105
|
+
});
|
|
106
|
+
return (0, template_1.checkCancel)(androidDsl) === 'groovy' ? 'groovy' : 'kts';
|
|
126
107
|
}
|
|
127
108
|
return android_dsl_1.DEFAULT_ANDROID_DSL;
|
|
128
109
|
}
|
|
129
110
|
async function askDevTools(flags) {
|
|
130
111
|
if (!flags.yes) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
choices: [{ value: 'testing', name: 'Add ReactLynx Testing Library for unit testing' }],
|
|
138
|
-
},
|
|
139
|
-
]);
|
|
140
|
-
return (0, template_1.checkCancel)(devTools);
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
handlePromptError(error);
|
|
144
|
-
}
|
|
112
|
+
const devTools = await p.multiselect({
|
|
113
|
+
message: 'Select development tools',
|
|
114
|
+
required: false,
|
|
115
|
+
options: [{ value: 'testing', label: 'Add ReactLynx Testing Library for unit testing' }],
|
|
116
|
+
});
|
|
117
|
+
return (0, template_1.checkCancel)(devTools);
|
|
145
118
|
}
|
|
146
119
|
return [];
|
|
147
120
|
}
|
|
148
121
|
async function askAdditionalTools(flags) {
|
|
149
122
|
if (!flags.yes) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
],
|
|
161
|
-
},
|
|
162
|
-
]);
|
|
163
|
-
return (0, template_1.checkCancel)(tools);
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
handlePromptError(error);
|
|
167
|
-
}
|
|
123
|
+
const tools = await p.multiselect({
|
|
124
|
+
message: 'Select optional tooling',
|
|
125
|
+
required: false,
|
|
126
|
+
options: [
|
|
127
|
+
{ value: 'eslint', label: 'ESLint (Standard linting configuration)' },
|
|
128
|
+
{ value: 'prettier', label: 'Prettier (Auto-formatting defaults)' },
|
|
129
|
+
{ value: 'biome', label: 'Biome (Biome + Biome formatter)' },
|
|
130
|
+
],
|
|
131
|
+
});
|
|
132
|
+
return (0, template_1.checkCancel)(tools);
|
|
168
133
|
}
|
|
169
134
|
return [];
|
|
170
135
|
}
|
|
@@ -173,25 +138,16 @@ async function askNamespace(defaultNamespace, flags) {
|
|
|
173
138
|
if (provided)
|
|
174
139
|
return provided;
|
|
175
140
|
if (!flags.yes) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return true;
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
]);
|
|
190
|
-
return (0, template_1.checkCancel)(namespace);
|
|
191
|
-
}
|
|
192
|
-
catch (error) {
|
|
193
|
-
handlePromptError(error);
|
|
194
|
-
}
|
|
141
|
+
const namespace = await p.text({
|
|
142
|
+
message: 'Package namespace (Android package / iOS bundle id)',
|
|
143
|
+
defaultValue: defaultNamespace,
|
|
144
|
+
placeholder: defaultNamespace,
|
|
145
|
+
validate(value) {
|
|
146
|
+
if (!(0, namespace_1.isValidNamespace)(value))
|
|
147
|
+
return 'Use reverse-DNS format, e.g. com.example.app';
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
return (0, template_1.checkCancel)(namespace);
|
|
195
151
|
}
|
|
196
152
|
return defaultNamespace;
|
|
197
153
|
}
|
|
@@ -199,20 +155,11 @@ async function confirmInstall(packageManager, flags) {
|
|
|
199
155
|
if (flags.install !== undefined)
|
|
200
156
|
return flags.install !== false;
|
|
201
157
|
if (!flags.yes) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
message: ui_1.ui.prompt(`Install JS dependencies now with ${packageManager}?`),
|
|
208
|
-
default: true,
|
|
209
|
-
},
|
|
210
|
-
]);
|
|
211
|
-
return (0, template_1.checkCancel)(installNow);
|
|
212
|
-
}
|
|
213
|
-
catch (error) {
|
|
214
|
-
handlePromptError(error);
|
|
215
|
-
}
|
|
158
|
+
const installNow = await p.confirm({
|
|
159
|
+
message: `Install JS dependencies now with ${packageManager}?`,
|
|
160
|
+
initialValue: true,
|
|
161
|
+
});
|
|
162
|
+
return (0, template_1.checkCancel)(installNow);
|
|
216
163
|
}
|
|
217
164
|
return true;
|
|
218
165
|
}
|
|
@@ -220,38 +167,20 @@ async function confirmInitGit(flags) {
|
|
|
220
167
|
if (flags.git !== undefined)
|
|
221
168
|
return flags.git !== false;
|
|
222
169
|
if (!flags.yes) {
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
message: ui_1.ui.prompt('Initialize a git repository?'),
|
|
229
|
-
default: true,
|
|
230
|
-
},
|
|
231
|
-
]);
|
|
232
|
-
return (0, template_1.checkCancel)(initGit);
|
|
233
|
-
}
|
|
234
|
-
catch (error) {
|
|
235
|
-
handlePromptError(error);
|
|
236
|
-
}
|
|
170
|
+
const initGit = await p.confirm({
|
|
171
|
+
message: 'Initialize a git repository?',
|
|
172
|
+
initialValue: true,
|
|
173
|
+
});
|
|
174
|
+
return (0, template_1.checkCancel)(initGit);
|
|
237
175
|
}
|
|
238
176
|
return true;
|
|
239
177
|
}
|
|
240
178
|
async function confirmRemoveExistingDir(targetDir, flags) {
|
|
241
179
|
if (flags.yes)
|
|
242
180
|
return true;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
message: ui_1.ui.prompt(`Target directory "${targetDir}" exists and is not empty. Remove existing files?`),
|
|
249
|
-
default: true,
|
|
250
|
-
},
|
|
251
|
-
]);
|
|
252
|
-
return (0, template_1.checkCancel)(removeDir);
|
|
253
|
-
}
|
|
254
|
-
catch (error) {
|
|
255
|
-
handlePromptError(error);
|
|
256
|
-
}
|
|
181
|
+
const removeDir = await p.confirm({
|
|
182
|
+
message: `Target directory "${targetDir}" exists and is not empty. Remove existing files?`,
|
|
183
|
+
initialValue: true,
|
|
184
|
+
});
|
|
185
|
+
return (0, template_1.checkCancel)(removeDir);
|
|
257
186
|
}
|
package/dist/create-app.js
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -8,6 +41,7 @@ exports.createSparklingApp = createSparklingApp;
|
|
|
8
41
|
// Copyright (c) 2025 TikTok Pte. Ltd.
|
|
9
42
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
10
43
|
// LICENSE file in the root directory of this source tree.
|
|
44
|
+
const p = __importStar(require("@clack/prompts"));
|
|
11
45
|
const fs_1 = __importDefault(require("fs"));
|
|
12
46
|
const path_1 = __importDefault(require("path"));
|
|
13
47
|
const action_runner_1 = require("./core/actions/action-runner");
|
|
@@ -64,11 +98,7 @@ async function createSparklingApp(options) {
|
|
|
64
98
|
const versionLabel = version
|
|
65
99
|
? `${version}${isWorkspaceBuild ? "-local" : ""}`
|
|
66
100
|
: "0.0.0";
|
|
67
|
-
|
|
68
|
-
console.log(ui_1.ui.headline("┌──────────────────────────────────────────────────────────────┐"));
|
|
69
|
-
console.log(ui_1.ui.headline("│ Welcome to Sparkling! │"));
|
|
70
|
-
console.log(ui_1.ui.headline("│ Create a Lynx app with various native abilities in minutes. │"));
|
|
71
|
-
console.log(ui_1.ui.headline("└──────────────────────────────────────────────────────────────┘"));
|
|
101
|
+
p.intro(ui_1.ui.headline(`create-sparkling-app v${versionLabel}`));
|
|
72
102
|
const projectName = args.name ?? (await (0, user_prompts_1.askProjectName)(flags));
|
|
73
103
|
const formatted = (0, template_1.formatProjectName)(projectName);
|
|
74
104
|
const { packageName, targetDir } = formatted;
|
|
@@ -232,8 +262,8 @@ async function createSparklingApp(options) {
|
|
|
232
262
|
didInstall = await (0, post_create_1.installDependencies)(distFolder, packageManager);
|
|
233
263
|
}
|
|
234
264
|
if (shouldInitGit) {
|
|
235
|
-
console.log(ui_1.ui.info('Setting up git repository, this may take a moment...'));
|
|
236
265
|
await (0, post_create_1.initializeGitRepo)(distFolder);
|
|
237
266
|
}
|
|
238
267
|
(0, post_create_1.showCompletionNotes)(targetDir, packageManager, didInstall);
|
|
268
|
+
p.outro(ui_1.ui.success('Happy hacking!'));
|
|
239
269
|
}
|
package/dist/index.js
CHANGED
|
@@ -2,12 +2,46 @@
|
|
|
2
2
|
// Copyright (c) 2025 TikTok Pte. Ltd.
|
|
3
3
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
4
4
|
// LICENSE file in the root directory of this source tree.
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
5
38
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
39
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
40
|
};
|
|
8
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
42
|
exports.createSparklingApp = void 0;
|
|
10
43
|
exports.main = main;
|
|
44
|
+
const p = __importStar(require("@clack/prompts"));
|
|
11
45
|
const help_1 = __importDefault(require("./help"));
|
|
12
46
|
const init_1 = __importDefault(require("./init"));
|
|
13
47
|
const template_1 = require("./core/project-builder/template");
|
|
@@ -64,9 +98,11 @@ async function main() {
|
|
|
64
98
|
if (require.main === module || process.env.NODE_ENV !== 'test') {
|
|
65
99
|
main().catch(error => {
|
|
66
100
|
if (error instanceof template_1.UserCancelledError) {
|
|
101
|
+
p.cancel('Operation cancelled.');
|
|
67
102
|
process.exit(0);
|
|
68
103
|
}
|
|
69
|
-
|
|
104
|
+
p.cancel('An error occurred.');
|
|
105
|
+
console.error(error);
|
|
70
106
|
if ((0, verbose_1.isVerboseEnabled)() && error instanceof Error && error.stack) {
|
|
71
107
|
(0, verbose_1.verboseLog)(error.stack);
|
|
72
108
|
}
|
package/dist/utils/spinner.js
CHANGED
|
@@ -1,30 +1,78 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.createSpinner = createSpinner;
|
|
4
37
|
// Copyright (c) 2025 TikTok Pte. Ltd.
|
|
5
38
|
// Licensed under the Apache License Version 2.0 that can be found in the
|
|
6
39
|
// LICENSE file in the root directory of this source tree.
|
|
7
|
-
const
|
|
40
|
+
const p = __importStar(require("@clack/prompts"));
|
|
8
41
|
function createSpinner() {
|
|
9
|
-
|
|
42
|
+
// p.spinner() uses animated cursor output that requires a TTY.
|
|
43
|
+
// Fall back to simple console.log in non-TTY environments (CI, piped output).
|
|
44
|
+
if (!process.stdout.isTTY) {
|
|
45
|
+
let activeMessage = null;
|
|
46
|
+
return {
|
|
47
|
+
message(message) {
|
|
48
|
+
if (message)
|
|
49
|
+
console.log(message);
|
|
50
|
+
},
|
|
51
|
+
start(message) {
|
|
52
|
+
activeMessage = message ?? null;
|
|
53
|
+
if (message)
|
|
54
|
+
console.log(message);
|
|
55
|
+
},
|
|
56
|
+
stop(message, _code) {
|
|
57
|
+
const finalMessage = message ?? activeMessage;
|
|
58
|
+
if (finalMessage)
|
|
59
|
+
console.log(finalMessage);
|
|
60
|
+
activeMessage = null;
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const spin = p.spinner();
|
|
10
65
|
return {
|
|
11
66
|
message(message) {
|
|
12
67
|
if (message) {
|
|
13
|
-
|
|
68
|
+
spin.message(message);
|
|
14
69
|
}
|
|
15
70
|
},
|
|
16
71
|
start(message) {
|
|
17
|
-
|
|
18
|
-
if (message) {
|
|
19
|
-
console.log(ui_1.ui.info(message));
|
|
20
|
-
}
|
|
72
|
+
spin.start(message ?? '');
|
|
21
73
|
},
|
|
22
74
|
stop(message, _code) {
|
|
23
|
-
|
|
24
|
-
if (finalMessage) {
|
|
25
|
-
console.log(ui_1.ui.info(finalMessage));
|
|
26
|
-
}
|
|
27
|
-
activeMessage = null;
|
|
75
|
+
spin.stop(message ?? '');
|
|
28
76
|
},
|
|
29
77
|
};
|
|
30
78
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-sparkling-app",
|
|
3
|
-
"version": "2.0.0",
|
|
3
|
+
"version": "2.1.0-rc.0",
|
|
4
4
|
"homepage": "https://tiktok.github.io/sparkling/",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"description": "CLI tool for creating Sparkling app projects",
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/jest": "^29.5.12",
|
|
24
|
-
"@types/inquirer": "^9.0.8",
|
|
25
24
|
"@types/node": "^22.15.0",
|
|
26
25
|
"jest": "^29.7.0",
|
|
27
26
|
"ts-jest": "^29.1.2",
|
|
@@ -31,7 +30,7 @@
|
|
|
31
30
|
"chalk": "^4.1.2",
|
|
32
31
|
"commander": "^12.1.0",
|
|
33
32
|
"deepmerge": "^4.3.1",
|
|
34
|
-
"
|
|
33
|
+
"@clack/prompts": "^0.10.1"
|
|
35
34
|
},
|
|
36
35
|
"scripts": {
|
|
37
36
|
"test": "jest",
|