create-three-blocks-starter 0.0.11 → 0.0.13
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/bin/index.js +116 -2
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -1042,7 +1042,7 @@ const promptTemplateSelection = async ( manifest ) => {
|
|
|
1042
1042
|
selected = ( selected - 1 + templates.length ) % templates.length;
|
|
1043
1043
|
render();
|
|
1044
1044
|
|
|
1045
|
-
} else if ( ch === 'B' || ch === 'j' ) {
|
|
1045
|
+
} else if ( ch === 'B' || ch === 'j' || ch === '\t' ) {
|
|
1046
1046
|
|
|
1047
1047
|
clearLines();
|
|
1048
1048
|
selected = ( selected + 1 ) % templates.length;
|
|
@@ -1167,6 +1167,8 @@ async function main() {
|
|
|
1167
1167
|
logInfo( bold( cyan( 'Available Templates' ) ) );
|
|
1168
1168
|
console.log( '' );
|
|
1169
1169
|
console.log( ` ${bold( 'starter' ).padEnd( 20 )} Base Three.js WebGPU template with PBF demo ${dim( '(default)' )}` );
|
|
1170
|
+
console.log( ` ${bold( 'minimal' ).padEnd( 20 )} Clean rotating cube + grid starting point` );
|
|
1171
|
+
console.log( ` ${bold( 'scroll' ).padEnd( 20 )} Smooth scroll website with magnet sections + keyboard` );
|
|
1170
1172
|
console.log( ` ${bold( 'game' ).padEnd( 20 )} Physics-driven scene with @three-blocks/pro` );
|
|
1171
1173
|
console.log( '' );
|
|
1172
1174
|
logInfo( dim( 'Usage: npx create-three-blocks-starter my-app --template game' ) );
|
|
@@ -1175,19 +1177,124 @@ async function main() {
|
|
|
1175
1177
|
|
|
1176
1178
|
}
|
|
1177
1179
|
|
|
1180
|
+
// Early template selection (hardcoded, runs before package download)
|
|
1181
|
+
const promptEarlyTemplateSelection = async () => {
|
|
1182
|
+
|
|
1183
|
+
const templates = [
|
|
1184
|
+
{ name: 'starter', label: 'Starter (default)', description: 'Base Three.js WebGPU template with PBF demo' },
|
|
1185
|
+
{ name: 'minimal', label: 'Minimal', description: 'Clean rotating cube + grid starting point' },
|
|
1186
|
+
{ name: 'scroll', label: 'Scroll Website', description: 'Smooth scroll website with magnet sections' },
|
|
1187
|
+
{ name: 'game', label: 'Game (Physics)', description: 'Physics-driven scene with @three-blocks/pro' }
|
|
1188
|
+
];
|
|
1189
|
+
|
|
1190
|
+
console.log( '' );
|
|
1191
|
+
logInfo( dim( 'Select a template:' ) );
|
|
1192
|
+
console.log( '' );
|
|
1193
|
+
|
|
1194
|
+
return await new Promise( ( resolve ) => {
|
|
1195
|
+
|
|
1196
|
+
const stdin = process.stdin;
|
|
1197
|
+
const stdout = process.stdout;
|
|
1198
|
+
let selected = 0; // starter is default (index 0)
|
|
1199
|
+
|
|
1200
|
+
const cleanup = () => {
|
|
1201
|
+
|
|
1202
|
+
stdin.removeListener( 'data', onData );
|
|
1203
|
+
if ( stdin.isTTY ) stdin.setRawMode( false );
|
|
1204
|
+
stdin.pause();
|
|
1205
|
+
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1208
|
+
const render = () => {
|
|
1209
|
+
|
|
1210
|
+
for ( let i = 0; i < templates.length; i ++ ) {
|
|
1211
|
+
|
|
1212
|
+
const t = templates[ i ];
|
|
1213
|
+
const prefix = i === selected ? cyan( '› ' ) : ' ';
|
|
1214
|
+
const label = i === selected ? bold( t.label ) : dim( t.label );
|
|
1215
|
+
const desc = dim( ` - ${t.description}` );
|
|
1216
|
+
stdout.write( `${prefix}${label}${desc}\n` );
|
|
1217
|
+
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
const clearLines = () => {
|
|
1223
|
+
|
|
1224
|
+
for ( let i = 0; i < templates.length; i ++ ) {
|
|
1225
|
+
|
|
1226
|
+
readline.moveCursor( stdout, 0, - 1 );
|
|
1227
|
+
readline.clearLine( stdout, 0 );
|
|
1228
|
+
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
};
|
|
1232
|
+
|
|
1233
|
+
const onData = ( chunk ) => {
|
|
1234
|
+
|
|
1235
|
+
const str = String( chunk );
|
|
1236
|
+
for ( const ch of str ) {
|
|
1237
|
+
|
|
1238
|
+
if ( ch === '\u0003' ) {
|
|
1239
|
+
|
|
1240
|
+
cleanup();
|
|
1241
|
+
process.exit( 1 );
|
|
1242
|
+
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
if ( ch === '\r' || ch === '\n' ) {
|
|
1246
|
+
|
|
1247
|
+
cleanup();
|
|
1248
|
+
console.log( '' );
|
|
1249
|
+
return resolve( templates[ selected ].name );
|
|
1250
|
+
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
if ( ch === '\u001b' ) continue;
|
|
1254
|
+
if ( ch === '[' ) continue;
|
|
1255
|
+
if ( ch === 'A' || ch === 'k' ) {
|
|
1256
|
+
|
|
1257
|
+
clearLines();
|
|
1258
|
+
selected = ( selected - 1 + templates.length ) % templates.length;
|
|
1259
|
+
render();
|
|
1260
|
+
|
|
1261
|
+
} else if ( ch === 'B' || ch === 'j' || ch === '\t' ) {
|
|
1262
|
+
|
|
1263
|
+
clearLines();
|
|
1264
|
+
selected = ( selected + 1 ) % templates.length;
|
|
1265
|
+
render();
|
|
1266
|
+
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
};
|
|
1272
|
+
|
|
1273
|
+
render();
|
|
1274
|
+
stdin.setEncoding( 'utf8' );
|
|
1275
|
+
if ( stdin.isTTY ) stdin.setRawMode( true );
|
|
1276
|
+
stdin.resume();
|
|
1277
|
+
stdin.on( 'data', onData );
|
|
1278
|
+
|
|
1279
|
+
} );
|
|
1280
|
+
|
|
1281
|
+
};
|
|
1282
|
+
|
|
1178
1283
|
if ( ! appName ) {
|
|
1179
1284
|
|
|
1180
1285
|
die(
|
|
1181
1286
|
`Usage:\n` +
|
|
1182
1287
|
` npx create-three-blocks-starter <directory> [options]\n\n` +
|
|
1183
1288
|
`Options:\n` +
|
|
1184
|
-
` --template, -t <name> Use a specific template (starter, game)\n` +
|
|
1289
|
+
` --template, -t <name> Use a specific template (starter, minimal, scroll, game)\n` +
|
|
1185
1290
|
` --list-templates List available templates\n` +
|
|
1186
1291
|
` --channel, -c <channel> Release channel (stable|beta|alpha)\n` +
|
|
1187
1292
|
` --starter-path <path> Use local starter path (for development)\n` +
|
|
1188
1293
|
` --debug, -d Enable verbose logging\n\n` +
|
|
1189
1294
|
`Examples:\n` +
|
|
1190
1295
|
` npx create-three-blocks-starter my-app\n` +
|
|
1296
|
+
` npx create-three-blocks-starter my-app --template minimal\n` +
|
|
1297
|
+
` npx create-three-blocks-starter my-app --template scroll\n` +
|
|
1191
1298
|
` npx create-three-blocks-starter my-app --template game`
|
|
1192
1299
|
);
|
|
1193
1300
|
|
|
@@ -1196,6 +1303,13 @@ async function main() {
|
|
|
1196
1303
|
const targetDir = path.resolve( process.cwd(), appName );
|
|
1197
1304
|
await ensureEmptyDir( targetDir );
|
|
1198
1305
|
|
|
1306
|
+
// Early interactive template selection (before auth, if no --template specified)
|
|
1307
|
+
if ( ! template && process.stdin.isTTY ) {
|
|
1308
|
+
|
|
1309
|
+
template = await promptEarlyTemplateSelection();
|
|
1310
|
+
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1199
1313
|
// Early exit for local development with --starter-path (skip auth entirely)
|
|
1200
1314
|
if ( starterPath ) {
|
|
1201
1315
|
|