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 CHANGED
@@ -1793,27 +1793,15 @@ var UPLOAD_PRESETS = {
1793
1793
  mimeTypes: ["video/mp4", "video/quicktime", "video/webm"],
1794
1794
  maxFileSize: 100 * 1024 * 1024,
1795
1795
  maxFiles: 1
1796
- },
1797
- mixed: {
1798
- mimeTypes: [
1799
- "image/jpeg",
1800
- "image/png",
1801
- "image/webp",
1802
- "application/pdf",
1803
- "text/plain",
1804
- "video/mp4"
1805
- ],
1806
- maxFileSize: 25 * 1024 * 1024,
1807
- maxFiles: 5
1808
1796
  }
1809
1797
  };
1810
1798
  function getUploadEnvSchemaFields(provider) {
1811
1799
  const shared = [
1812
1800
  { name: "UPLOAD_PROVIDER", schema: `z.enum(["s3", "r2", "cloudinary"])` },
1813
1801
  { name: "UPLOAD_MODE", schema: `z.enum(["proxy", "direct", "large"])` },
1814
- { name: "UPLOAD_AUTH_MODE", schema: `z.enum(["required", "optional", "none"])` },
1802
+ { name: "UPLOAD_AUTH_MODE", schema: `z.enum(["required", "none"])` },
1815
1803
  { name: "UPLOAD_FILE_ACCESS", schema: `z.enum(["private", "public"])` },
1816
- { name: "UPLOAD_FILE_PRESET", schema: `z.enum(["image", "document", "video", "mixed"])` },
1804
+ { name: "UPLOAD_FILE_PRESET", schema: `z.enum(["image", "document", "video"])` },
1817
1805
  { name: "UPLOAD_KEY_PREFIX", schema: "z.string().min(1)" },
1818
1806
  { name: "UPLOAD_ALLOWED_MIME", schema: "z.string().min(1)" },
1819
1807
  { name: "UPLOAD_MAX_FILE_SIZE", schema: "z.coerce.number().positive()" },
@@ -1848,103 +1836,24 @@ async function isAuthInstalled(projectRoot, srcDir) {
1848
1836
  function hasDrizzleDatabase(config) {
1849
1837
  return config?.database?.orm === "drizzle";
1850
1838
  }
1851
- async function promptCredentials(provider) {
1852
- console.log(import_chalk7.default.dim(" Tip: Leave fields blank to use placeholders and configure later.\n"));
1839
+ function getProviderEnvDefaults(provider) {
1853
1840
  if (provider === "cloudinary") {
1854
- const response2 = await (0, import_prompts5.default)([
1855
- {
1856
- type: "text",
1857
- name: "cloudName",
1858
- message: "Cloudinary cloud name",
1859
- initial: ""
1860
- },
1861
- {
1862
- type: "text",
1863
- name: "apiKey",
1864
- message: "Cloudinary API key",
1865
- initial: ""
1866
- },
1867
- {
1868
- type: "password",
1869
- name: "apiSecret",
1870
- message: "Cloudinary API secret"
1871
- },
1872
- {
1873
- type: "text",
1874
- name: "folder",
1875
- message: "Cloudinary folder",
1876
- initial: "uploads"
1877
- },
1878
- {
1879
- type: "text",
1880
- name: "uploadPreset",
1881
- message: "Cloudinary upload preset (optional)",
1882
- initial: ""
1883
- }
1884
- ]);
1885
- if (response2.cloudName === void 0) {
1886
- console.log(import_chalk7.default.yellow("Operation cancelled."));
1887
- return null;
1888
- }
1889
- const values2 = {
1890
- CLOUDINARY_CLOUD_NAME: response2.cloudName?.trim() || "your-cloud-name",
1891
- CLOUDINARY_API_KEY: response2.apiKey?.trim() || "your-api-key",
1892
- CLOUDINARY_API_SECRET: response2.apiSecret?.trim() || "your-api-secret",
1893
- CLOUDINARY_FOLDER: response2.folder?.trim() || "uploads",
1894
- CLOUDINARY_UPLOAD_PRESET: response2.uploadPreset?.trim() || ""
1841
+ return {
1842
+ CLOUDINARY_CLOUD_NAME: "your-cloud-name",
1843
+ CLOUDINARY_API_KEY: "your-api-key",
1844
+ CLOUDINARY_API_SECRET: "your-api-secret",
1845
+ CLOUDINARY_FOLDER: "uploads",
1846
+ CLOUDINARY_UPLOAD_PRESET: ""
1895
1847
  };
1896
- return values2;
1897
1848
  }
1898
- const response = await (0, import_prompts5.default)([
1899
- {
1900
- type: "text",
1901
- name: "bucket",
1902
- message: `${provider.toUpperCase()} bucket name`,
1903
- initial: ""
1904
- },
1905
- {
1906
- type: "text",
1907
- name: "region",
1908
- message: `${provider.toUpperCase()} region`,
1909
- initial: provider === "r2" ? "auto" : "us-east-1"
1910
- },
1911
- {
1912
- type: "text",
1913
- name: "endpoint",
1914
- message: provider === "r2" ? "R2 S3 endpoint" : "Custom S3 endpoint (optional)",
1915
- initial: provider === "r2" ? "https://<account-id>.r2.cloudflarestorage.com" : ""
1916
- },
1917
- {
1918
- type: "text",
1919
- name: "accessKeyId",
1920
- message: "Access key ID",
1921
- initial: ""
1922
- },
1923
- {
1924
- type: "password",
1925
- name: "secretAccessKey",
1926
- message: "Secret access key"
1927
- },
1928
- {
1929
- type: "text",
1930
- name: "publicBaseUrl",
1931
- message: "Public base URL (optional)",
1932
- initial: ""
1933
- }
1934
- ]);
1935
- if (response.bucket === void 0) {
1936
- console.log(import_chalk7.default.yellow("Operation cancelled."));
1937
- return null;
1938
- }
1939
- const values = {
1940
- UPLOAD_BUCKET: response.bucket?.trim() || `your-${provider}-bucket`,
1941
- UPLOAD_REGION: response.region?.trim() || (provider === "r2" ? "auto" : "us-east-1"),
1942
- UPLOAD_ENDPOINT: response.endpoint?.trim() || (provider === "r2" ? "https://<account-id>.r2.cloudflarestorage.com" : ""),
1943
- UPLOAD_ACCESS_KEY_ID: response.accessKeyId?.trim() || "your-access-key-id",
1944
- UPLOAD_SECRET_ACCESS_KEY: response.secretAccessKey?.trim() || "your-secret-access-key",
1945
- UPLOAD_PUBLIC_BASE_URL: response.publicBaseUrl?.trim() || ""
1849
+ return {
1850
+ UPLOAD_BUCKET: `your-${provider}-bucket`,
1851
+ UPLOAD_REGION: provider === "r2" ? "auto" : "us-east-1",
1852
+ UPLOAD_ENDPOINT: provider === "r2" ? "https://<account-id>.r2.cloudflarestorage.com" : "",
1853
+ UPLOAD_ACCESS_KEY_ID: "your-access-key-id",
1854
+ UPLOAD_SECRET_ACCESS_KEY: "your-secret-access-key",
1855
+ UPLOAD_PUBLIC_BASE_URL: ""
1946
1856
  };
1947
- return values;
1948
1857
  }
1949
1858
  function buildSharedEnvVars(provider, mode, authMode, access, preset, maxFileSize, maxFiles) {
1950
1859
  return {
@@ -1995,10 +1904,9 @@ async function promptUploadsConfig(projectRoot, srcDir) {
1995
1904
  message: "Who can upload?",
1996
1905
  choices: [
1997
1906
  { title: "Authenticated only", value: "required" },
1998
- { title: "Optional auth", value: "optional" },
1999
1907
  { title: "Public", value: "none" }
2000
1908
  ],
2001
- initial: authInstalled ? 0 : 2
1909
+ initial: authInstalled ? 0 : 1
2002
1910
  },
2003
1911
  {
2004
1912
  type: "select",
@@ -2017,16 +1925,9 @@ async function promptUploadsConfig(projectRoot, srcDir) {
2017
1925
  choices: [
2018
1926
  { title: "Image", value: "image" },
2019
1927
  { title: "Document", value: "document" },
2020
- { title: "Video", value: "video" },
2021
- { title: "Mixed", value: "mixed" }
1928
+ { title: "Video", value: "video" }
2022
1929
  ],
2023
1930
  initial: 0
2024
- },
2025
- {
2026
- type: "confirm",
2027
- name: "useDefaults",
2028
- message: "Use recommended upload limits for this preset?",
2029
- initial: true
2030
1931
  }
2031
1932
  ]);
2032
1933
  if (initial.provider === void 0) {
@@ -2043,7 +1944,7 @@ async function promptUploadsConfig(projectRoot, srcDir) {
2043
1944
  console.log(import_chalk7.default.yellow("Use S3 or R2 for large uploads, or pick Proxy/Direct for Cloudinary.\n"));
2044
1945
  return null;
2045
1946
  }
2046
- if (provider === "cloudinary" && (preset === "document" || preset === "mixed")) {
1947
+ if (provider === "cloudinary" && preset === "document") {
2047
1948
  const warning = await (0, import_prompts5.default)({
2048
1949
  type: "confirm",
2049
1950
  name: "continue",
@@ -2056,50 +1957,19 @@ async function promptUploadsConfig(projectRoot, srcDir) {
2056
1957
  }
2057
1958
  }
2058
1959
  const presetDefaults = UPLOAD_PRESETS[preset];
2059
- let maxFileSize = presetDefaults.maxFileSize;
2060
- let maxFiles = presetDefaults.maxFiles;
2061
- if (!initial.useDefaults) {
2062
- const custom = await (0, import_prompts5.default)([
2063
- {
2064
- type: "number",
2065
- name: "maxFileSizeMb",
2066
- message: "Max file size (MB)",
2067
- initial: Math.max(1, Math.round(presetDefaults.maxFileSize / (1024 * 1024))),
2068
- min: 1
2069
- },
2070
- {
2071
- type: "number",
2072
- name: "maxFiles",
2073
- message: "Max files per request",
2074
- initial: presetDefaults.maxFiles,
2075
- min: 1,
2076
- max: 20
2077
- }
2078
- ]);
2079
- if (custom.maxFileSizeMb === void 0) {
2080
- console.log(import_chalk7.default.yellow("Operation cancelled."));
2081
- return null;
2082
- }
2083
- maxFileSize = Number(custom.maxFileSizeMb) * 1024 * 1024;
2084
- maxFiles = Number(custom.maxFiles);
2085
- }
2086
1960
  let useDatabaseMetadata = false;
2087
1961
  let shouldInstallDatabase = false;
2088
1962
  const metadataPrompt = await (0, import_prompts5.default)({
2089
- type: "select",
1963
+ type: "confirm",
2090
1964
  name: "metadata",
2091
- message: "Upload metadata storage?",
2092
- choices: [
2093
- { title: drizzleInstalled ? "Database" : "Install database + track uploads", value: "db" },
2094
- { title: "No metadata", value: "none" }
2095
- ],
2096
- initial: 0
1965
+ message: drizzleInstalled ? "Store upload metadata in your database?" : "Install database and store upload metadata?",
1966
+ initial: true
2097
1967
  });
2098
1968
  if (metadataPrompt.metadata === void 0) {
2099
1969
  console.log(import_chalk7.default.yellow("Operation cancelled."));
2100
1970
  return null;
2101
1971
  }
2102
- if (metadataPrompt.metadata === "db") {
1972
+ if (metadataPrompt.metadata === true) {
2103
1973
  useDatabaseMetadata = true;
2104
1974
  if (!projectConfig?.database) {
2105
1975
  shouldInstallDatabase = true;
@@ -2135,10 +2005,6 @@ async function promptUploadsConfig(projectRoot, srcDir) {
2135
2005
  }
2136
2006
  shouldInstallAuth = true;
2137
2007
  }
2138
- const providerEnv = await promptCredentials(provider);
2139
- if (!providerEnv) {
2140
- return null;
2141
- }
2142
2008
  return {
2143
2009
  provider,
2144
2010
  mode,
@@ -2149,8 +2015,8 @@ async function promptUploadsConfig(projectRoot, srcDir) {
2149
2015
  shouldInstallAuth,
2150
2016
  shouldInstallDatabase,
2151
2017
  envVars: {
2152
- ...buildSharedEnvVars(provider, mode, authMode, access, preset, maxFileSize, maxFiles),
2153
- ...providerEnv
2018
+ ...buildSharedEnvVars(provider, mode, authMode, access, preset, presetDefaults.maxFileSize, presetDefaults.maxFiles),
2019
+ ...getProviderEnvDefaults(provider)
2154
2020
  }
2155
2021
  };
2156
2022
  }
@@ -2386,6 +2252,7 @@ ${moduleDocsEndMarker}`);
2386
2252
  function printUploadHints(result) {
2387
2253
  console.log(import_chalk7.default.yellow("\u2139 Upload routes are mounted at: /api/uploads"));
2388
2254
  console.log(import_chalk7.default.yellow(`\u2139 Provider: ${result.provider} \xB7 Mode: ${result.mode} \xB7 Access: ${result.access}`));
2255
+ console.log(import_chalk7.default.yellow("\u2139 Fill the generated upload env vars in .env before testing uploads."));
2389
2256
  if (result.mode === "proxy") {
2390
2257
  console.log(import_chalk7.default.yellow("\u2139 Reuse uploadSingle()/uploadArray() from src/lib/uploads/proxy.ts in your own form + file routes."));
2391
2258
  }
@@ -2508,6 +2375,11 @@ var add = async (moduleName, options = {}) => {
2508
2375
  currentStep = "module dependency resolution";
2509
2376
  await resolveDependencies(moduleDeps, projectRoot);
2510
2377
  if (resolvedModuleName === "uploads" && uploadConfig) {
2378
+ const errorHandlerInstalled = import_fs_extra12.default.existsSync(import_path13.default.join(projectRoot, srcDir, "lib", "errors.ts"));
2379
+ if (!errorHandlerInstalled) {
2380
+ console.log(import_chalk8.default.blue("\n\u2139 Uploads needs the error-handler module. Installing error-handler..."));
2381
+ await add("error-handler");
2382
+ }
2511
2383
  if (uploadConfig.shouldInstallDatabase) {
2512
2384
  console.log(import_chalk8.default.blue("\n\u2139 Upload metadata needs a Drizzle database. Installing database module..."));
2513
2385
  await add("database");