zuro-cli 0.0.2-beta.15 → 0.0.2-beta.16
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/dist/index.js +31 -159
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -159
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1332,27 +1332,15 @@ var UPLOAD_PRESETS = {
|
|
|
1332
1332
|
mimeTypes: ["video/mp4", "video/quicktime", "video/webm"],
|
|
1333
1333
|
maxFileSize: 100 * 1024 * 1024,
|
|
1334
1334
|
maxFiles: 1
|
|
1335
|
-
},
|
|
1336
|
-
mixed: {
|
|
1337
|
-
mimeTypes: [
|
|
1338
|
-
"image/jpeg",
|
|
1339
|
-
"image/png",
|
|
1340
|
-
"image/webp",
|
|
1341
|
-
"application/pdf",
|
|
1342
|
-
"text/plain",
|
|
1343
|
-
"video/mp4"
|
|
1344
|
-
],
|
|
1345
|
-
maxFileSize: 25 * 1024 * 1024,
|
|
1346
|
-
maxFiles: 5
|
|
1347
1335
|
}
|
|
1348
1336
|
};
|
|
1349
1337
|
function getUploadEnvSchemaFields(provider) {
|
|
1350
1338
|
const shared = [
|
|
1351
1339
|
{ name: "UPLOAD_PROVIDER", schema: `z.enum(["s3", "r2", "cloudinary"])` },
|
|
1352
1340
|
{ name: "UPLOAD_MODE", schema: `z.enum(["proxy", "direct", "large"])` },
|
|
1353
|
-
{ name: "UPLOAD_AUTH_MODE", schema: `z.enum(["required", "
|
|
1341
|
+
{ name: "UPLOAD_AUTH_MODE", schema: `z.enum(["required", "none"])` },
|
|
1354
1342
|
{ name: "UPLOAD_FILE_ACCESS", schema: `z.enum(["private", "public"])` },
|
|
1355
|
-
{ name: "UPLOAD_FILE_PRESET", schema: `z.enum(["image", "document", "video"
|
|
1343
|
+
{ name: "UPLOAD_FILE_PRESET", schema: `z.enum(["image", "document", "video"])` },
|
|
1356
1344
|
{ name: "UPLOAD_KEY_PREFIX", schema: "z.string().min(1)" },
|
|
1357
1345
|
{ name: "UPLOAD_ALLOWED_MIME", schema: "z.string().min(1)" },
|
|
1358
1346
|
{ name: "UPLOAD_MAX_FILE_SIZE", schema: "z.coerce.number().positive()" },
|
|
@@ -1387,103 +1375,24 @@ async function isAuthInstalled(projectRoot, srcDir) {
|
|
|
1387
1375
|
function hasDrizzleDatabase(config) {
|
|
1388
1376
|
return config?.database?.orm === "drizzle";
|
|
1389
1377
|
}
|
|
1390
|
-
|
|
1391
|
-
console.log(chalk6.dim(" Tip: Leave fields blank to use placeholders and configure later.\n"));
|
|
1378
|
+
function getProviderEnvDefaults(provider) {
|
|
1392
1379
|
if (provider === "cloudinary") {
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
},
|
|
1400
|
-
{
|
|
1401
|
-
type: "text",
|
|
1402
|
-
name: "apiKey",
|
|
1403
|
-
message: "Cloudinary API key",
|
|
1404
|
-
initial: ""
|
|
1405
|
-
},
|
|
1406
|
-
{
|
|
1407
|
-
type: "password",
|
|
1408
|
-
name: "apiSecret",
|
|
1409
|
-
message: "Cloudinary API secret"
|
|
1410
|
-
},
|
|
1411
|
-
{
|
|
1412
|
-
type: "text",
|
|
1413
|
-
name: "folder",
|
|
1414
|
-
message: "Cloudinary folder",
|
|
1415
|
-
initial: "uploads"
|
|
1416
|
-
},
|
|
1417
|
-
{
|
|
1418
|
-
type: "text",
|
|
1419
|
-
name: "uploadPreset",
|
|
1420
|
-
message: "Cloudinary upload preset (optional)",
|
|
1421
|
-
initial: ""
|
|
1422
|
-
}
|
|
1423
|
-
]);
|
|
1424
|
-
if (response2.cloudName === void 0) {
|
|
1425
|
-
console.log(chalk6.yellow("Operation cancelled."));
|
|
1426
|
-
return null;
|
|
1427
|
-
}
|
|
1428
|
-
const values2 = {
|
|
1429
|
-
CLOUDINARY_CLOUD_NAME: response2.cloudName?.trim() || "your-cloud-name",
|
|
1430
|
-
CLOUDINARY_API_KEY: response2.apiKey?.trim() || "your-api-key",
|
|
1431
|
-
CLOUDINARY_API_SECRET: response2.apiSecret?.trim() || "your-api-secret",
|
|
1432
|
-
CLOUDINARY_FOLDER: response2.folder?.trim() || "uploads",
|
|
1433
|
-
CLOUDINARY_UPLOAD_PRESET: response2.uploadPreset?.trim() || ""
|
|
1380
|
+
return {
|
|
1381
|
+
CLOUDINARY_CLOUD_NAME: "your-cloud-name",
|
|
1382
|
+
CLOUDINARY_API_KEY: "your-api-key",
|
|
1383
|
+
CLOUDINARY_API_SECRET: "your-api-secret",
|
|
1384
|
+
CLOUDINARY_FOLDER: "uploads",
|
|
1385
|
+
CLOUDINARY_UPLOAD_PRESET: ""
|
|
1434
1386
|
};
|
|
1435
|
-
return values2;
|
|
1436
1387
|
}
|
|
1437
|
-
|
|
1438
|
-
{
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
{
|
|
1445
|
-
type: "text",
|
|
1446
|
-
name: "region",
|
|
1447
|
-
message: `${provider.toUpperCase()} region`,
|
|
1448
|
-
initial: provider === "r2" ? "auto" : "us-east-1"
|
|
1449
|
-
},
|
|
1450
|
-
{
|
|
1451
|
-
type: "text",
|
|
1452
|
-
name: "endpoint",
|
|
1453
|
-
message: provider === "r2" ? "R2 S3 endpoint" : "Custom S3 endpoint (optional)",
|
|
1454
|
-
initial: provider === "r2" ? "https://<account-id>.r2.cloudflarestorage.com" : ""
|
|
1455
|
-
},
|
|
1456
|
-
{
|
|
1457
|
-
type: "text",
|
|
1458
|
-
name: "accessKeyId",
|
|
1459
|
-
message: "Access key ID",
|
|
1460
|
-
initial: ""
|
|
1461
|
-
},
|
|
1462
|
-
{
|
|
1463
|
-
type: "password",
|
|
1464
|
-
name: "secretAccessKey",
|
|
1465
|
-
message: "Secret access key"
|
|
1466
|
-
},
|
|
1467
|
-
{
|
|
1468
|
-
type: "text",
|
|
1469
|
-
name: "publicBaseUrl",
|
|
1470
|
-
message: "Public base URL (optional)",
|
|
1471
|
-
initial: ""
|
|
1472
|
-
}
|
|
1473
|
-
]);
|
|
1474
|
-
if (response.bucket === void 0) {
|
|
1475
|
-
console.log(chalk6.yellow("Operation cancelled."));
|
|
1476
|
-
return null;
|
|
1477
|
-
}
|
|
1478
|
-
const values = {
|
|
1479
|
-
UPLOAD_BUCKET: response.bucket?.trim() || `your-${provider}-bucket`,
|
|
1480
|
-
UPLOAD_REGION: response.region?.trim() || (provider === "r2" ? "auto" : "us-east-1"),
|
|
1481
|
-
UPLOAD_ENDPOINT: response.endpoint?.trim() || (provider === "r2" ? "https://<account-id>.r2.cloudflarestorage.com" : ""),
|
|
1482
|
-
UPLOAD_ACCESS_KEY_ID: response.accessKeyId?.trim() || "your-access-key-id",
|
|
1483
|
-
UPLOAD_SECRET_ACCESS_KEY: response.secretAccessKey?.trim() || "your-secret-access-key",
|
|
1484
|
-
UPLOAD_PUBLIC_BASE_URL: response.publicBaseUrl?.trim() || ""
|
|
1388
|
+
return {
|
|
1389
|
+
UPLOAD_BUCKET: `your-${provider}-bucket`,
|
|
1390
|
+
UPLOAD_REGION: provider === "r2" ? "auto" : "us-east-1",
|
|
1391
|
+
UPLOAD_ENDPOINT: provider === "r2" ? "https://<account-id>.r2.cloudflarestorage.com" : "",
|
|
1392
|
+
UPLOAD_ACCESS_KEY_ID: "your-access-key-id",
|
|
1393
|
+
UPLOAD_SECRET_ACCESS_KEY: "your-secret-access-key",
|
|
1394
|
+
UPLOAD_PUBLIC_BASE_URL: ""
|
|
1485
1395
|
};
|
|
1486
|
-
return values;
|
|
1487
1396
|
}
|
|
1488
1397
|
function buildSharedEnvVars(provider, mode, authMode, access, preset, maxFileSize, maxFiles) {
|
|
1489
1398
|
return {
|
|
@@ -1534,10 +1443,9 @@ async function promptUploadsConfig(projectRoot, srcDir) {
|
|
|
1534
1443
|
message: "Who can upload?",
|
|
1535
1444
|
choices: [
|
|
1536
1445
|
{ title: "Authenticated only", value: "required" },
|
|
1537
|
-
{ title: "Optional auth", value: "optional" },
|
|
1538
1446
|
{ title: "Public", value: "none" }
|
|
1539
1447
|
],
|
|
1540
|
-
initial: authInstalled ? 0 :
|
|
1448
|
+
initial: authInstalled ? 0 : 1
|
|
1541
1449
|
},
|
|
1542
1450
|
{
|
|
1543
1451
|
type: "select",
|
|
@@ -1556,16 +1464,9 @@ async function promptUploadsConfig(projectRoot, srcDir) {
|
|
|
1556
1464
|
choices: [
|
|
1557
1465
|
{ title: "Image", value: "image" },
|
|
1558
1466
|
{ title: "Document", value: "document" },
|
|
1559
|
-
{ title: "Video", value: "video" }
|
|
1560
|
-
{ title: "Mixed", value: "mixed" }
|
|
1467
|
+
{ title: "Video", value: "video" }
|
|
1561
1468
|
],
|
|
1562
1469
|
initial: 0
|
|
1563
|
-
},
|
|
1564
|
-
{
|
|
1565
|
-
type: "confirm",
|
|
1566
|
-
name: "useDefaults",
|
|
1567
|
-
message: "Use recommended upload limits for this preset?",
|
|
1568
|
-
initial: true
|
|
1569
1470
|
}
|
|
1570
1471
|
]);
|
|
1571
1472
|
if (initial.provider === void 0) {
|
|
@@ -1582,7 +1483,7 @@ async function promptUploadsConfig(projectRoot, srcDir) {
|
|
|
1582
1483
|
console.log(chalk6.yellow("Use S3 or R2 for large uploads, or pick Proxy/Direct for Cloudinary.\n"));
|
|
1583
1484
|
return null;
|
|
1584
1485
|
}
|
|
1585
|
-
if (provider === "cloudinary" &&
|
|
1486
|
+
if (provider === "cloudinary" && preset === "document") {
|
|
1586
1487
|
const warning = await prompts4({
|
|
1587
1488
|
type: "confirm",
|
|
1588
1489
|
name: "continue",
|
|
@@ -1595,50 +1496,19 @@ async function promptUploadsConfig(projectRoot, srcDir) {
|
|
|
1595
1496
|
}
|
|
1596
1497
|
}
|
|
1597
1498
|
const presetDefaults = UPLOAD_PRESETS[preset];
|
|
1598
|
-
let maxFileSize = presetDefaults.maxFileSize;
|
|
1599
|
-
let maxFiles = presetDefaults.maxFiles;
|
|
1600
|
-
if (!initial.useDefaults) {
|
|
1601
|
-
const custom = await prompts4([
|
|
1602
|
-
{
|
|
1603
|
-
type: "number",
|
|
1604
|
-
name: "maxFileSizeMb",
|
|
1605
|
-
message: "Max file size (MB)",
|
|
1606
|
-
initial: Math.max(1, Math.round(presetDefaults.maxFileSize / (1024 * 1024))),
|
|
1607
|
-
min: 1
|
|
1608
|
-
},
|
|
1609
|
-
{
|
|
1610
|
-
type: "number",
|
|
1611
|
-
name: "maxFiles",
|
|
1612
|
-
message: "Max files per request",
|
|
1613
|
-
initial: presetDefaults.maxFiles,
|
|
1614
|
-
min: 1,
|
|
1615
|
-
max: 20
|
|
1616
|
-
}
|
|
1617
|
-
]);
|
|
1618
|
-
if (custom.maxFileSizeMb === void 0) {
|
|
1619
|
-
console.log(chalk6.yellow("Operation cancelled."));
|
|
1620
|
-
return null;
|
|
1621
|
-
}
|
|
1622
|
-
maxFileSize = Number(custom.maxFileSizeMb) * 1024 * 1024;
|
|
1623
|
-
maxFiles = Number(custom.maxFiles);
|
|
1624
|
-
}
|
|
1625
1499
|
let useDatabaseMetadata = false;
|
|
1626
1500
|
let shouldInstallDatabase = false;
|
|
1627
1501
|
const metadataPrompt = await prompts4({
|
|
1628
|
-
type: "
|
|
1502
|
+
type: "confirm",
|
|
1629
1503
|
name: "metadata",
|
|
1630
|
-
message: "
|
|
1631
|
-
|
|
1632
|
-
{ title: drizzleInstalled ? "Database" : "Install database + track uploads", value: "db" },
|
|
1633
|
-
{ title: "No metadata", value: "none" }
|
|
1634
|
-
],
|
|
1635
|
-
initial: 0
|
|
1504
|
+
message: drizzleInstalled ? "Store upload metadata in your database?" : "Install database and store upload metadata?",
|
|
1505
|
+
initial: true
|
|
1636
1506
|
});
|
|
1637
1507
|
if (metadataPrompt.metadata === void 0) {
|
|
1638
1508
|
console.log(chalk6.yellow("Operation cancelled."));
|
|
1639
1509
|
return null;
|
|
1640
1510
|
}
|
|
1641
|
-
if (metadataPrompt.metadata ===
|
|
1511
|
+
if (metadataPrompt.metadata === true) {
|
|
1642
1512
|
useDatabaseMetadata = true;
|
|
1643
1513
|
if (!projectConfig?.database) {
|
|
1644
1514
|
shouldInstallDatabase = true;
|
|
@@ -1674,10 +1544,6 @@ async function promptUploadsConfig(projectRoot, srcDir) {
|
|
|
1674
1544
|
}
|
|
1675
1545
|
shouldInstallAuth = true;
|
|
1676
1546
|
}
|
|
1677
|
-
const providerEnv = await promptCredentials(provider);
|
|
1678
|
-
if (!providerEnv) {
|
|
1679
|
-
return null;
|
|
1680
|
-
}
|
|
1681
1547
|
return {
|
|
1682
1548
|
provider,
|
|
1683
1549
|
mode,
|
|
@@ -1688,8 +1554,8 @@ async function promptUploadsConfig(projectRoot, srcDir) {
|
|
|
1688
1554
|
shouldInstallAuth,
|
|
1689
1555
|
shouldInstallDatabase,
|
|
1690
1556
|
envVars: {
|
|
1691
|
-
...buildSharedEnvVars(provider, mode, authMode, access, preset, maxFileSize, maxFiles),
|
|
1692
|
-
...
|
|
1557
|
+
...buildSharedEnvVars(provider, mode, authMode, access, preset, presetDefaults.maxFileSize, presetDefaults.maxFiles),
|
|
1558
|
+
...getProviderEnvDefaults(provider)
|
|
1693
1559
|
}
|
|
1694
1560
|
};
|
|
1695
1561
|
}
|
|
@@ -1925,6 +1791,7 @@ ${moduleDocsEndMarker}`);
|
|
|
1925
1791
|
function printUploadHints(result) {
|
|
1926
1792
|
console.log(chalk6.yellow("\u2139 Upload routes are mounted at: /api/uploads"));
|
|
1927
1793
|
console.log(chalk6.yellow(`\u2139 Provider: ${result.provider} \xB7 Mode: ${result.mode} \xB7 Access: ${result.access}`));
|
|
1794
|
+
console.log(chalk6.yellow("\u2139 Fill the generated upload env vars in .env before testing uploads."));
|
|
1928
1795
|
if (result.mode === "proxy") {
|
|
1929
1796
|
console.log(chalk6.yellow("\u2139 Reuse uploadSingle()/uploadArray() from src/lib/uploads/proxy.ts in your own form + file routes."));
|
|
1930
1797
|
}
|
|
@@ -2047,6 +1914,11 @@ var add = async (moduleName, options = {}) => {
|
|
|
2047
1914
|
currentStep = "module dependency resolution";
|
|
2048
1915
|
await resolveDependencies(moduleDeps, projectRoot);
|
|
2049
1916
|
if (resolvedModuleName === "uploads" && uploadConfig) {
|
|
1917
|
+
const errorHandlerInstalled = fs10.existsSync(path11.join(projectRoot, srcDir, "lib", "errors.ts"));
|
|
1918
|
+
if (!errorHandlerInstalled) {
|
|
1919
|
+
console.log(chalk7.blue("\n\u2139 Uploads needs the error-handler module. Installing error-handler..."));
|
|
1920
|
+
await add("error-handler");
|
|
1921
|
+
}
|
|
2050
1922
|
if (uploadConfig.shouldInstallDatabase) {
|
|
2051
1923
|
console.log(chalk7.blue("\n\u2139 Upload metadata needs a Drizzle database. Installing database module..."));
|
|
2052
1924
|
await add("database");
|