appwrite-cli 18.0.0 → 18.1.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/dist/index.cjs CHANGED
@@ -35485,7 +35485,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
35485
35485
  }
35486
35486
  return positiveOption || option2;
35487
35487
  };
35488
- const getErrorMessage = (option2) => {
35488
+ const getErrorMessage2 = (option2) => {
35489
35489
  const bestOption = findBestOptionFromValue(option2);
35490
35490
  const optionKey = bestOption.attributeName();
35491
35491
  const source = this.getOptionValueSource(optionKey);
@@ -35494,7 +35494,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
35494
35494
  }
35495
35495
  return `option '${bestOption.flags}'`;
35496
35496
  };
35497
- const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
35497
+ const message = `error: ${getErrorMessage2(option)} cannot be used with ${getErrorMessage2(conflictingOption)}`;
35498
35498
  this.error(message, { code: "commander.conflictingOption" });
35499
35499
  }
35500
35500
  /**
@@ -64957,6 +64957,7 @@ module.exports = __toCommonJS(index_exports);
64957
64957
  var import_fs7 = __toESM(require("fs"), 1);
64958
64958
  var import_path6 = __toESM(require("path"), 1);
64959
64959
  var import_node_readline = __toESM(require("node:readline"), 1);
64960
+ var import_node_util = require("node:util");
64960
64961
  var import_dotenv = __toESM(require_main(), 1);
64961
64962
  var import_chalk9 = __toESM(require_source(), 1);
64962
64963
  var import_inquirer3 = __toESM(require_inquirer(), 1);
@@ -65007,7 +65008,7 @@ var id_default = ID;
65007
65008
  // lib/constants.ts
65008
65009
  var SDK_TITLE = "Appwrite";
65009
65010
  var SDK_TITLE_LOWER = "appwrite";
65010
- var SDK_VERSION = "18.0.0";
65011
+ var SDK_VERSION = "18.1.0";
65011
65012
  var SDK_LOGO = "\n _ _ _ ___ __ _____\n /_\\ _ __ _ ____ ___ __(_) |_ ___ / __\\ / / \\_ \\\n //_\\\\| '_ \\| '_ \\ \\ /\\ / / '__| | __/ _ \\ / / / / / /\\/\n / _ \\ |_) | |_) \\ V V /| | | | || __/ / /___/ /___/\\/ /_\n \\_/ \\_/ .__/| .__/ \\_/\\_/ |_| |_|\\__\\___| \\____/\\____/\\____/\n |_| |_|\n\n";
65012
65013
  var EXECUTABLE_NAME = "appwrite";
65013
65014
  var UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
@@ -79283,6 +79284,8 @@ var getSafeDirectoryName = (value, fallback) => {
79283
79284
  var siteRequiresBuildCommand = (site) => {
79284
79285
  return !(site.framework === "other" && site.adapter === "static");
79285
79286
  };
79287
+ var WINDOWS_EXECUTABLE_NAME = `${EXECUTABLE_NAME.toLowerCase()}.exe`;
79288
+ var HOMEBREW_FORMULA_NAME = EXECUTABLE_NAME.toLowerCase();
79286
79289
  var isCloudHostname = (hostname3) => hostname3 === "cloud.appwrite.io" || hostname3.endsWith(".cloud.appwrite.io");
79287
79290
  var getConsoleBaseUrl = (endpoint) => {
79288
79291
  try {
@@ -103666,7 +103669,7 @@ var package_default = {
103666
103669
  type: "module",
103667
103670
  homepage: "https://appwrite.io/support",
103668
103671
  description: "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API",
103669
- version: "18.0.0",
103672
+ version: "18.1.0",
103670
103673
  license: "BSD-3-Clause",
103671
103674
  main: "dist/index.cjs",
103672
103675
  module: "dist/index.js",
@@ -103698,9 +103701,9 @@ var package_default = {
103698
103701
  "build:types": "tsc -p tsconfig.json --emitDeclarationOnly",
103699
103702
  "build:runtime": "npm run build:lib:runtime && npm run build:cli",
103700
103703
  "build:lib:runtime": "npm run build:lib:esm && npm run build:lib:cjs",
103701
- "build:lib:esm": "esbuild index.ts --bundle --platform=node --target=node18 --format=esm --loader:.hbs=text --outfile=dist/index.js",
103702
- "build:lib:cjs": "esbuild index.ts --bundle --platform=node --target=node18 --format=cjs --loader:.hbs=text --outfile=dist/index.cjs",
103703
- "build:cli": "esbuild cli.ts --bundle --platform=node --target=node18 --format=cjs --loader:.hbs=text --external:fsevents --outfile=dist/cli.cjs",
103704
+ "build:lib:esm": "esbuild index.ts --bundle --platform=node --target=node18 --format=esm --loader:.hbs=text --external:terminal-image --outfile=dist/index.js",
103705
+ "build:lib:cjs": "esbuild index.ts --bundle --platform=node --target=node18 --format=cjs --loader:.hbs=text --external:terminal-image --outfile=dist/index.cjs",
103706
+ "build:cli": "esbuild cli.ts --bundle --platform=node --target=node18 --format=cjs --loader:.hbs=text --external:fsevents --external:terminal-image --outfile=dist/cli.cjs",
103704
103707
  lint: "eslint .",
103705
103708
  format: 'prettier --write "**/*.{js,ts,json,md}"',
103706
103709
  generate: "tsx scripts/generate-commands.ts",
@@ -103711,7 +103714,7 @@ var package_default = {
103711
103714
  "mac-x64": "bun build cli.ts --compile --sourcemap=inline --target=bun-darwin-x64 --outfile build/appwrite-cli-darwin-x64",
103712
103715
  "mac-arm64": "bun build cli.ts --compile --sourcemap=inline --target=bun-darwin-arm64 --outfile build/appwrite-cli-darwin-arm64",
103713
103716
  "windows-x64": "bun build cli.ts --compile --sourcemap=inline --target=bun-windows-x64 --outfile build/appwrite-cli-win-x64.exe",
103714
- "windows-arm64": "esbuild cli.ts --bundle --loader:.hbs=text --platform=node --target=node18 --format=esm --external:fsevents --outfile=dist/bundle-win-arm64.mjs && pkg dist/bundle-win-arm64.mjs -t node18-win-arm64 -o build/appwrite-cli-win-arm64.exe"
103717
+ "windows-arm64": "esbuild cli.ts --bundle --loader:.hbs=text --platform=node --target=node18 --format=esm --external:fsevents --external:terminal-image --outfile=dist/bundle-win-arm64.mjs && pkg dist/bundle-win-arm64.mjs -t node18-win-arm64 -o build/appwrite-cli-win-arm64.exe"
103715
103718
  },
103716
103719
  dependencies: {
103717
103720
  "@appwrite.io/console": "~9.1.0",
@@ -103730,9 +103733,13 @@ var package_default = {
103730
103733
  "string-width": "^7.2.0",
103731
103734
  tail: "^2.2.6",
103732
103735
  tar: "^7.4.3",
103736
+ "terminal-image": "^3.1.1",
103733
103737
  undici: "^6.24.0",
103734
103738
  zod: "^4.3.5"
103735
103739
  },
103740
+ overrides: {
103741
+ phin: "3.7.1"
103742
+ },
103736
103743
  devDependencies: {
103737
103744
  "@typescript-eslint/eslint-plugin": "^8.0.0",
103738
103745
  "@typescript-eslint/parser": "^8.0.0",
@@ -105042,9 +105049,9 @@ var import_chalk5 = __toESM(require_source(), 1);
105042
105049
 
105043
105050
  // lib/sdks.ts
105044
105051
  var import_os4 = __toESM(require("os"), 1);
105045
- var sdkForConsole = async (requiresAuth = true) => {
105052
+ var sdkForConsole = async (requiresAuth = true, endpointOverride) => {
105046
105053
  const client = new Client();
105047
- const endpoint = globalConfig2.getEndpoint() || DEFAULT_ENDPOINT;
105054
+ const endpoint = endpointOverride || globalConfig2.getEndpoint() || DEFAULT_ENDPOINT;
105048
105055
  const cookie = globalConfig2.getCookie();
105049
105056
  const selfSigned = globalConfig2.getSelfSigned();
105050
105057
  if (requiresAuth && cookie === "") {
@@ -106837,8 +106844,18 @@ var DEPLOYMENT_TIMEOUT_MS = 10 * 60 * 1e3;
106837
106844
  var DEPLOYMENT_TIMEOUT_MINUTES = Math.round(
106838
106845
  DEPLOYMENT_TIMEOUT_MS / (60 * 1e3)
106839
106846
  );
106847
+ var SITE_SCREENSHOT_FINALIZATION_TIMEOUT_MS = 30 * 1e3;
106848
+ var SITE_SCREENSHOT_BUCKET_ID = "screenshots";
106849
+ var SITE_SCREENSHOT_PREVIEW_WIDTH = 480;
106850
+ var SITE_SCREENSHOT_PREVIEW_HEIGHT = 270;
106851
+ var SITE_TERMINAL_PREVIEW_TARGET_WIDTH = 72;
106852
+ var SITE_TERMINAL_PREVIEW_MAX_WIDTH = 80;
106853
+ var SITE_TERMINAL_PREVIEW_MAX_HEIGHT = 22;
106854
+ var SITE_TERMINAL_PREVIEW_MIN_HEIGHT = 8;
106840
106855
  var WAITING_JOKE_THRESHOLD_MS = 30 * 1e3;
106841
106856
  var WAITING_JOKE_URL = "https://xkcd.com/303/";
106857
+ var ANSI_RESET = "\x1B[0m";
106858
+ var terminalImageModulePromise;
106842
106859
  function getDeploymentProgressText(status, waitingSince) {
106843
106860
  if (status === "waiting" && waitingSince !== null && Date.now() - waitingSince >= WAITING_JOKE_THRESHOLD_MS) {
106844
106861
  return `Still waiting... ${WAITING_JOKE_URL}`;
@@ -106848,6 +106865,184 @@ function getDeploymentProgressText(status, waitingSince) {
106848
106865
  function getDeploymentTimeoutErrorMessage() {
106849
106866
  return `Deployment got stuck for more than ${DEPLOYMENT_TIMEOUT_MINUTES} minutes`;
106850
106867
  }
106868
+ async function getTerminalImage() {
106869
+ terminalImageModulePromise ??= import("terminal-image").then(
106870
+ (module2) => module2.default
106871
+ );
106872
+ return terminalImageModulePromise;
106873
+ }
106874
+ function getErrorMessage(error49) {
106875
+ if (error49 instanceof Error && error49.message.trim().length > 0) {
106876
+ return error49.message.trim();
106877
+ }
106878
+ if (Array.isArray(error49)) {
106879
+ const messages = error49.map((entry) => getErrorMessage(entry)).filter((entry) => entry !== "Unknown error");
106880
+ if (messages.length > 0) {
106881
+ return messages.join("; ");
106882
+ }
106883
+ }
106884
+ if (typeof error49 === "string" && error49.trim().length > 0) {
106885
+ return error49.trim();
106886
+ }
106887
+ if (error49 && typeof error49 === "object") {
106888
+ const objectMessage = Reflect.get(error49, "message");
106889
+ if (typeof objectMessage === "string" && objectMessage.trim().length > 0) {
106890
+ return objectMessage.trim();
106891
+ }
106892
+ try {
106893
+ return JSON.stringify(error49);
106894
+ } catch (_serializationError) {
106895
+ }
106896
+ }
106897
+ return "Unknown error";
106898
+ }
106899
+ function getSiteDeploymentScreenshots(deployment) {
106900
+ const screenshotLight = typeof deployment["screenshotLight"] === "string" && deployment["screenshotLight"].trim().length > 0 ? deployment["screenshotLight"] : void 0;
106901
+ const screenshotDark = typeof deployment["screenshotDark"] === "string" && deployment["screenshotDark"].trim().length > 0 ? deployment["screenshotDark"] : void 0;
106902
+ return {
106903
+ screenshotLight,
106904
+ screenshotDark
106905
+ };
106906
+ }
106907
+ function hasSiteDeploymentScreenshots(deployment) {
106908
+ const { screenshotLight, screenshotDark } = getSiteDeploymentScreenshots(deployment);
106909
+ return Boolean(screenshotLight || screenshotDark);
106910
+ }
106911
+ function shouldRenderSiteTerminalPreview() {
106912
+ return Boolean(process.stdout.isTTY) && !cliConfig.json && !cliConfig.raw;
106913
+ }
106914
+ function getSiteTerminalPreviewWidth() {
106915
+ const columns = process.stdout.columns ?? 80;
106916
+ return Math.max(
106917
+ 16,
106918
+ Math.min(
106919
+ columns - 4,
106920
+ SITE_TERMINAL_PREVIEW_TARGET_WIDTH,
106921
+ SITE_TERMINAL_PREVIEW_MAX_WIDTH
106922
+ )
106923
+ );
106924
+ }
106925
+ function getSiteTerminalPreviewHeight() {
106926
+ const rows = process.stdout.rows ?? 24;
106927
+ return Math.max(
106928
+ SITE_TERMINAL_PREVIEW_MIN_HEIGHT,
106929
+ Math.min(rows - 10, SITE_TERMINAL_PREVIEW_MAX_HEIGHT)
106930
+ );
106931
+ }
106932
+ async function renderImageBufferToTerminalPreview(buffer) {
106933
+ const terminalImage = await getTerminalImage();
106934
+ const originalTermProgram = process.env.TERM_PROGRAM;
106935
+ const originalTermProgramVersion = process.env.TERM_PROGRAM_VERSION;
106936
+ const originalKonsoleVersion = process.env.KONSOLE_VERSION;
106937
+ const originalKittyWindowId = process.env.KITTY_WINDOW_ID;
106938
+ delete process.env.TERM_PROGRAM;
106939
+ delete process.env.TERM_PROGRAM_VERSION;
106940
+ delete process.env.KONSOLE_VERSION;
106941
+ delete process.env.KITTY_WINDOW_ID;
106942
+ try {
106943
+ return await terminalImage.buffer(buffer, {
106944
+ width: getSiteTerminalPreviewWidth(),
106945
+ height: getSiteTerminalPreviewHeight(),
106946
+ preserveAspectRatio: true
106947
+ });
106948
+ } finally {
106949
+ if (originalTermProgram === void 0) {
106950
+ delete process.env.TERM_PROGRAM;
106951
+ } else {
106952
+ process.env.TERM_PROGRAM = originalTermProgram;
106953
+ }
106954
+ if (originalTermProgramVersion === void 0) {
106955
+ delete process.env.TERM_PROGRAM_VERSION;
106956
+ } else {
106957
+ process.env.TERM_PROGRAM_VERSION = originalTermProgramVersion;
106958
+ }
106959
+ if (originalKonsoleVersion === void 0) {
106960
+ delete process.env.KONSOLE_VERSION;
106961
+ } else {
106962
+ process.env.KONSOLE_VERSION = originalKonsoleVersion;
106963
+ }
106964
+ if (originalKittyWindowId === void 0) {
106965
+ delete process.env.KITTY_WINDOW_ID;
106966
+ } else {
106967
+ process.env.KITTY_WINDOW_ID = originalKittyWindowId;
106968
+ }
106969
+ }
106970
+ }
106971
+ async function fetchSiteScreenshotPreview(params) {
106972
+ const previewUrl = params.renderer.storageService.getFilePreview({
106973
+ bucketId: SITE_SCREENSHOT_BUCKET_ID,
106974
+ fileId: params.fileId,
106975
+ width: SITE_SCREENSHOT_PREVIEW_WIDTH,
106976
+ height: SITE_SCREENSHOT_PREVIEW_HEIGHT,
106977
+ output: ImageFormat.Png
106978
+ });
106979
+ const imageData = await params.renderer.consoleClient.call(
106980
+ "get",
106981
+ new URL(previewUrl),
106982
+ {},
106983
+ {},
106984
+ "arrayBuffer"
106985
+ );
106986
+ if (!(imageData instanceof ArrayBuffer)) {
106987
+ throw new Error("Failed to download the site screenshot preview.");
106988
+ }
106989
+ return renderImageBufferToTerminalPreview(Buffer.from(imageData));
106990
+ }
106991
+ function frameTerminalPreview(preview) {
106992
+ const lines = preview.split("\n").map((line) => line.replace(/\s+$/, ""));
106993
+ while (lines.length > 0 && (0, import_node_util.stripVTControlCharacters)(lines[0]).trim().length === 0) {
106994
+ lines.shift();
106995
+ }
106996
+ while (lines.length > 0 && (0, import_node_util.stripVTControlCharacters)(lines[lines.length - 1]).trim().length === 0) {
106997
+ lines.pop();
106998
+ }
106999
+ if (lines.length === 0) {
107000
+ return "";
107001
+ }
107002
+ const contentWidth = Math.max(
107003
+ ...lines.map((line) => (0, import_node_util.stripVTControlCharacters)(line).length)
107004
+ );
107005
+ const border = `+-${"-".repeat(contentWidth)}-+`;
107006
+ return [
107007
+ border,
107008
+ ...lines.map((line) => {
107009
+ const visibleWidth = (0, import_node_util.stripVTControlCharacters)(line).length;
107010
+ return `| ${line}${ANSI_RESET}${" ".repeat(contentWidth - visibleWidth)} |`;
107011
+ }),
107012
+ border
107013
+ ].join("\n");
107014
+ }
107015
+ async function renderSiteTerminalPreview(params) {
107016
+ const warnings = /* @__PURE__ */ new Set();
107017
+ const candidates = [
107018
+ { fileId: params.screenshotDark, label: "dark" },
107019
+ { fileId: params.screenshotLight, label: "light" }
107020
+ ];
107021
+ for (const candidate of candidates) {
107022
+ const { fileId, label } = candidate;
107023
+ if (!fileId) {
107024
+ continue;
107025
+ }
107026
+ try {
107027
+ const preview = await fetchSiteScreenshotPreview({
107028
+ renderer: params.renderer,
107029
+ fileId
107030
+ });
107031
+ return {
107032
+ preview: frameTerminalPreview(preview),
107033
+ warnings: []
107034
+ };
107035
+ } catch (previewError) {
107036
+ warnings.add(
107037
+ `${label === "dark" ? "Dark mode" : "Light mode"} screenshot: ${getErrorMessage(previewError)}`
107038
+ );
107039
+ }
107040
+ }
107041
+ return {
107042
+ preview: void 0,
107043
+ warnings: [...warnings]
107044
+ };
107045
+ }
106851
107046
  function withDeploymentLogsHint(message, deploymentLogsController) {
106852
107047
  const hint2 = deploymentLogsController.getToggleHint();
106853
107048
  return hint2.length > 0 ? `${message} \u2022 ${hint2}` : message;
@@ -107724,7 +107919,7 @@ var Push = class {
107724
107919
  deploymentLogsController
107725
107920
  )
107726
107921
  });
107727
- const timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
107922
+ let timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
107728
107923
  while (true) {
107729
107924
  if (Date.now() > timeoutDeadline) {
107730
107925
  deploymentLogPrinter.complete();
@@ -108111,6 +108306,8 @@ var Push = class {
108111
108306
  deploymentId
108112
108307
  );
108113
108308
  let waitingSince = null;
108309
+ let readyWithoutScreenshotsSince = null;
108310
+ let activationApplied = false;
108114
108311
  const deploymentLogPrinter = createDeploymentLogPrinter({
108115
108312
  label: `site:${site.name}`,
108116
108313
  showPrefix: sites.length > 1,
@@ -108150,7 +108347,7 @@ var Push = class {
108150
108347
  deploymentLogsController
108151
108348
  )
108152
108349
  });
108153
- const timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
108350
+ let timeoutDeadline = Date.now() + DEPLOYMENT_TIMEOUT_MS;
108154
108351
  while (true) {
108155
108352
  if (Date.now() > timeoutDeadline) {
108156
108353
  deploymentLogPrinter.complete();
@@ -108184,7 +108381,9 @@ var Push = class {
108184
108381
  waitingSince = null;
108185
108382
  }
108186
108383
  if (status === "ready") {
108187
- if (activate) {
108384
+ const { screenshotLight, screenshotDark } = getSiteDeploymentScreenshots(response);
108385
+ const screenshotsReady = hasSiteDeploymentScreenshots(response);
108386
+ if (activate && !activationApplied) {
108188
108387
  currentDeploymentEnd = "Setting active deployment...";
108189
108388
  updaterRow.update({
108190
108389
  status: "Activating",
@@ -108200,6 +108399,28 @@ var Push = class {
108200
108399
  siteId: site["$id"],
108201
108400
  deploymentId
108202
108401
  });
108402
+ activationApplied = true;
108403
+ }
108404
+ if (!screenshotsReady) {
108405
+ readyWithoutScreenshotsSince ??= Date.now();
108406
+ timeoutDeadline = Math.max(
108407
+ timeoutDeadline,
108408
+ readyWithoutScreenshotsSince + SITE_SCREENSHOT_FINALIZATION_TIMEOUT_MS
108409
+ );
108410
+ if (Date.now() - readyWithoutScreenshotsSince < SITE_SCREENSHOT_FINALIZATION_TIMEOUT_MS) {
108411
+ currentDeploymentEnd = "Finalizing deployment preview...";
108412
+ updaterRow.update({
108413
+ status: "Finalizing",
108414
+ end: withDeploymentLogsHint(
108415
+ currentDeploymentEnd,
108416
+ deploymentLogsController
108417
+ )
108418
+ });
108419
+ await new Promise(
108420
+ (resolve3) => setTimeout(resolve3, POLL_DEBOUNCE2)
108421
+ );
108422
+ continue;
108423
+ }
108203
108424
  }
108204
108425
  successfullyDeployed++;
108205
108426
  let url2 = "";
@@ -108226,7 +108447,14 @@ var Push = class {
108226
108447
  status: activate ? "Deployed" : "Built",
108227
108448
  end: ""
108228
108449
  });
108229
- deploymentLogs.push({ url: url2, consoleUrl });
108450
+ deploymentLogs.push({
108451
+ name: site.name,
108452
+ url: url2,
108453
+ consoleUrl,
108454
+ screenshotLight,
108455
+ screenshotDark,
108456
+ screenshotsPending: !screenshotsReady
108457
+ });
108230
108458
  break;
108231
108459
  } else if (status === "failed") {
108232
108460
  deploymentLogPrinter.complete();
@@ -108281,16 +108509,76 @@ var Push = class {
108281
108509
  Spinner.stop();
108282
108510
  }
108283
108511
  if (deploymentLogs.length > 0) {
108512
+ let sitePreviewRenderer = null;
108513
+ let sitePreviewSetupWarning = null;
108514
+ const emittedPreviewWarnings = /* @__PURE__ */ new Set();
108515
+ if (shouldRenderSiteTerminalPreview() && deploymentLogs.some(
108516
+ (deploymentLog) => deploymentLog.screenshotLight || deploymentLog.screenshotDark
108517
+ )) {
108518
+ try {
108519
+ const consoleClient = await sdkForConsole(
108520
+ true,
108521
+ localConfig.getEndpoint() || globalConfig2.getEndpoint()
108522
+ );
108523
+ sitePreviewRenderer = {
108524
+ consoleClient,
108525
+ storageService: await getStorageService(consoleClient)
108526
+ };
108527
+ } catch (previewSetupError) {
108528
+ sitePreviewSetupWarning = getErrorMessage(previewSetupError);
108529
+ }
108530
+ }
108284
108531
  process.stdout.write("\n");
108285
- deploymentLogs.forEach((dl, index) => {
108532
+ for (const [index, dl] of deploymentLogs.entries()) {
108286
108533
  if (index > 0) {
108287
108534
  process.stdout.write("\n");
108288
108535
  }
108536
+ if (deploymentLogs.length > 1) {
108537
+ process.stdout.write(`${import_chalk9.default.cyan.bold(`Site: ${dl.name}`)}
108538
+ `);
108539
+ }
108540
+ if (dl.screenshotsPending) {
108541
+ hint(
108542
+ "Deployment is ready, but screenshot generation is still finalizing. Open the deployment page to view it once it is available."
108543
+ );
108544
+ }
108545
+ if (sitePreviewRenderer && (dl.screenshotLight || dl.screenshotDark)) {
108546
+ const preview = await renderSiteTerminalPreview({
108547
+ renderer: sitePreviewRenderer,
108548
+ screenshotLight: dl.screenshotLight,
108549
+ screenshotDark: dl.screenshotDark
108550
+ });
108551
+ if (preview.preview) {
108552
+ process.stdout.write(
108553
+ `
108554
+ ${import_chalk9.default.cyan.bold("Screenshot preview")}
108555
+
108556
+ `
108557
+ );
108558
+ process.stdout.write(`${preview.preview}
108559
+
108560
+ `);
108561
+ }
108562
+ for (const previewWarning of preview.warnings) {
108563
+ const warningMessage = `Screenshot preview unavailable: ${previewWarning}`;
108564
+ if (emittedPreviewWarnings.has(warningMessage)) {
108565
+ continue;
108566
+ }
108567
+ emittedPreviewWarnings.add(warningMessage);
108568
+ hint(warningMessage);
108569
+ }
108570
+ } else if (sitePreviewSetupWarning && (dl.screenshotLight || dl.screenshotDark)) {
108571
+ const warningMessage = `Screenshot preview unavailable: ${sitePreviewSetupWarning}`;
108572
+ if (!emittedPreviewWarnings.has(warningMessage)) {
108573
+ emittedPreviewWarnings.add(warningMessage);
108574
+ hint(warningMessage);
108575
+ }
108576
+ }
108289
108577
  if (dl.url) {
108290
108578
  this.log(`Preview link: ${import_chalk9.default.cyan(dl.url)}`);
108291
108579
  }
108292
108580
  this.log(`Deployment page: ${import_chalk9.default.cyan(dl.consoleUrl)}`);
108293
- });
108581
+ }
108294
108582
  process.stdout.write("\n");
108295
108583
  }
108296
108584
  return {
@@ -110541,7 +110829,7 @@ var BaseDatabasesGenerator = class {
110541
110829
  };
110542
110830
 
110543
110831
  // lib/commands/generators/typescript/templates/types.ts.hbs
110544
- var types_ts_default = "import { type Models } from '{{appwriteDep}}';\n\n{{{ENUMS}}}{{{TYPES}}}\ndeclare const __roleStringBrand: unique symbol;\nexport type RoleString = string & { readonly [__roleStringBrand]: never };\n\nexport type RoleBuilder = {\n any: () => RoleString;\n user: (userId: string, status?: string) => RoleString;\n users: (status?: string) => RoleString;\n guests: () => RoleString;\n team: (teamId: string, role?: string) => RoleString;\n member: (memberId: string) => RoleString;\n label: (label: string) => RoleString;\n}\n\nexport type PermissionBuilder = {\n read: (role: RoleString) => string;\n write: (role: RoleString) => string;\n create: (role: RoleString) => string;\n update: (role: RoleString) => string;\n delete: (role: RoleString) => string;\n}\n\nexport type PermissionCallback = (permission: PermissionBuilder, role: RoleBuilder) => string[];\n\nexport type QueryValue = string | number | boolean;\n\nexport type ExtractQueryValue<T> = T extends (infer U)[]\n ? U extends QueryValue ? U : never\n : T extends QueryValue | null ? NonNullable<T> : never;\n\nexport type QueryableKeys<T> = {\n [K in keyof T]: ExtractQueryValue<T[K]> extends never ? never : K;\n}[keyof T];\n\nexport type QueryBuilder<T> = {\n equal: <K extends QueryableKeys<T>>(field: K, value: ExtractQueryValue<T[K]>) => string;\n notEqual: <K extends QueryableKeys<T>>(field: K, value: ExtractQueryValue<T[K]>) => string;\n lessThan: <K extends QueryableKeys<T>>(field: K, value: ExtractQueryValue<T[K]>) => string;\n lessThanEqual: <K extends QueryableKeys<T>>(field: K, value: ExtractQueryValue<T[K]>) => string;\n greaterThan: <K extends QueryableKeys<T>>(field: K, value: ExtractQueryValue<T[K]>) => string;\n greaterThanEqual: <K extends QueryableKeys<T>>(field: K, value: ExtractQueryValue<T[K]>) => string;\n contains: <K extends QueryableKeys<T>>(field: K, value: ExtractQueryValue<T[K]>) => string;\n search: <K extends QueryableKeys<T>>(field: K, value: string) => string;\n isNull: <K extends QueryableKeys<T>>(field: K) => string;\n isNotNull: <K extends QueryableKeys<T>>(field: K) => string;\n startsWith: <K extends QueryableKeys<T>>(field: K, value: string) => string;\n endsWith: <K extends QueryableKeys<T>>(field: K, value: string) => string;\n between: <K extends QueryableKeys<T>>(field: K, start: ExtractQueryValue<T[K]>, end: ExtractQueryValue<T[K]>) => string;\n select: <K extends keyof T>(fields: K[]) => string;\n orderAsc: <K extends keyof T>(field: K) => string;\n orderDesc: <K extends keyof T>(field: K) => string;\n limit: (value: number) => string;\n offset: (value: number) => string;\n cursorAfter: (documentId: string) => string;\n cursorBefore: (documentId: string) => string;\n or: (...queries: string[]) => string;\n and: (...queries: string[]) => string;\n}\n\nexport type DatabaseId = {{{databaseIdType}}};\n\n{{{DATABASE_TABLES_TYPE}}}\n";
110832
+ var types_ts_default = "import { type Models } from '{{appwriteDep}}';\n\n{{{ENUMS}}}{{{TYPES}}}\ndeclare const __roleStringBrand: unique symbol;\nexport type RoleString = string & { readonly [__roleStringBrand]: never };\n\nexport type RoleBuilder = {\n any: () => RoleString;\n user: (userId: string, status?: string) => RoleString;\n users: (status?: string) => RoleString;\n guests: () => RoleString;\n team: (teamId: string, role?: string) => RoleString;\n member: (memberId: string) => RoleString;\n label: (label: string) => RoleString;\n}\n\nexport type PermissionBuilder = {\n read: (role: RoleString) => string;\n write: (role: RoleString) => string;\n create: (role: RoleString) => string;\n update: (role: RoleString) => string;\n delete: (role: RoleString) => string;\n}\n\nexport type PermissionCallback = (permission: PermissionBuilder, role: RoleBuilder) => string[];\n\nexport type QueryValue = string | number | boolean;\n\nexport type ExtractQueryValue<T> = T extends (infer U)[]\n ? U extends QueryValue ? U : never\n : T extends QueryValue | null ? NonNullable<T> : never;\n\nexport type QueryableKeys<T> = {\n [K in keyof T]: ExtractQueryValue<T[K]> extends never ? never : K;\n}[keyof T];\n\nexport type QueryableFieldValue<T, K> = K extends keyof T\n ? ExtractQueryValue<T[K]>\n : never;\n\nexport type QueryBuilder<T> = {\n equal: <K extends QueryableKeys<T>>(field: K, value: QueryableFieldValue<T, K>) => string;\n notEqual: <K extends QueryableKeys<T>>(field: K, value: QueryableFieldValue<T, K>) => string;\n lessThan: <K extends QueryableKeys<T>>(field: K, value: QueryableFieldValue<T, K>) => string;\n lessThanEqual: <K extends QueryableKeys<T>>(field: K, value: QueryableFieldValue<T, K>) => string;\n greaterThan: <K extends QueryableKeys<T>>(field: K, value: QueryableFieldValue<T, K>) => string;\n greaterThanEqual: <K extends QueryableKeys<T>>(field: K, value: QueryableFieldValue<T, K>) => string;\n contains: <K extends QueryableKeys<T>>(field: K, value: QueryableFieldValue<T, K>) => string;\n search: <K extends QueryableKeys<T>>(field: K, value: string) => string;\n isNull: <K extends QueryableKeys<T>>(field: K) => string;\n isNotNull: <K extends QueryableKeys<T>>(field: K) => string;\n startsWith: <K extends QueryableKeys<T>>(field: K, value: string) => string;\n endsWith: <K extends QueryableKeys<T>>(field: K, value: string) => string;\n between: <K extends QueryableKeys<T>>(field: K, start: QueryableFieldValue<T, K>, end: QueryableFieldValue<T, K>) => string;\n select: <K extends keyof T>(fields: K[]) => string;\n orderAsc: <K extends keyof T>(field: K) => string;\n orderDesc: <K extends keyof T>(field: K) => string;\n limit: (value: number) => string;\n offset: (value: number) => string;\n cursorAfter: (documentId: string) => string;\n cursorBefore: (documentId: string) => string;\n or: (...queries: string[]) => string;\n and: (...queries: string[]) => string;\n}\n\nexport type DatabaseId = {{{databaseIdType}}};\n\n{{{DATABASE_TABLES_TYPE}}}\n";
110545
110833
 
110546
110834
  // lib/commands/generators/typescript/templates/databases.ts.hbs
110547
110835
  var databases_ts_default = 'import { Client, TablesDB, ID, Query, type Models, Permission, Role } from \'{{appwriteDep}}\';\nimport type { DatabaseHandle, DatabaseId, DatabaseTableMap, DatabaseTables, QueryBuilder, QueryValue, PermissionBuilder, RoleBuilder, RoleString } from \'./types{{importExt}}\';\n{{#if supportsServerSide}}\nimport { PROJECT_ID, ENDPOINT, API_KEY } from \'./constants{{importExt}}\';\n{{else}}\nimport { PROJECT_ID, ENDPOINT } from \'./constants{{importExt}}\';\n{{/if}}\n\nconst createQueryBuilder = <T>(): QueryBuilder<T> => ({\n equal: (field, value) => Query.equal(String(field), value as QueryValue),\n notEqual: (field, value) => Query.notEqual(String(field), value as QueryValue),\n lessThan: (field, value) => Query.lessThan(String(field), value as QueryValue),\n lessThanEqual: (field, value) => Query.lessThanEqual(String(field), value as QueryValue),\n greaterThan: (field, value) => Query.greaterThan(String(field), value as QueryValue),\n greaterThanEqual: (field, value) => Query.greaterThanEqual(String(field), value as QueryValue),\n contains: (field, value) => Query.contains(String(field), value as string | QueryValue[]),\n search: (field, value) => Query.search(String(field), value),\n isNull: (field) => Query.isNull(String(field)),\n isNotNull: (field) => Query.isNotNull(String(field)),\n startsWith: (field, value) => Query.startsWith(String(field), value),\n endsWith: (field, value) => Query.endsWith(String(field), value),\n between: (field, start, end) => Query.between(String(field), start as string | number, end as string | number),\n select: (fields) => Query.select(fields.map(String)),\n orderAsc: (field) => Query.orderAsc(String(field)),\n orderDesc: (field) => Query.orderDesc(String(field)),\n limit: (value) => Query.limit(value),\n offset: (value) => Query.offset(value),\n cursorAfter: (documentId) => Query.cursorAfter(documentId),\n cursorBefore: (documentId) => Query.cursorBefore(documentId),\n or: (...queries) => Query.or(queries),\n and: (...queries) => Query.and(queries),\n});\n\n{{{TABLE_ID_MAP}}}\n\n{{{TABLES_WITH_RELATIONSHIPS}}}\n\nconst roleBuilder: RoleBuilder = {\n any: () => Role.any() as RoleString,\n user: (userId, status?) => Role.user(userId, status) as RoleString,\n users: (status?) => Role.users(status) as RoleString,\n guests: () => Role.guests() as RoleString,\n team: (teamId, role?) => Role.team(teamId, role) as RoleString,\n member: (memberId) => Role.member(memberId) as RoleString,\n label: (label) => Role.label(label) as RoleString,\n};\n\nconst permissionBuilder: PermissionBuilder = {\n read: (role) => Permission.read(role),\n write: (role) => Permission.write(role),\n create: (role) => Permission.create(role),\n update: (role) => Permission.update(role),\n delete: (role) => Permission.delete(role),\n};\n\nconst resolvePermissions = (callback?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]): string[] | undefined =>\n callback?.(permissionBuilder, roleBuilder);\n\nfunction createTableApi<T extends Models.Row>(\n tablesDB: TablesDB,\n databaseId: string,\n tableId: string,\n) {\n return {\n create: (data: Omit<T, keyof Models.Row>, options?: { rowId?: string; permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; transactionId?: string }) =>\n tablesDB.createRow<T>({\n databaseId,\n tableId,\n rowId: options?.rowId ?? ID.unique(),\n data: data as T extends Models.DefaultRow ? Partial<Models.Row> & Record<string, unknown> : Partial<Models.Row> & Omit<T, keyof Models.Row>,\n permissions: resolvePermissions(options?.permissions),\n transactionId: options?.transactionId,\n }),\n get: (id: string) =>\n tablesDB.getRow<T>({\n databaseId,\n tableId,\n rowId: id,\n }),\n update: (id: string, data: Partial<Omit<T, keyof Models.Row>>, options?: { permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; transactionId?: string }) =>\n tablesDB.updateRow<T>({\n databaseId,\n tableId,\n rowId: id,\n data: data as T extends Models.DefaultRow ? Partial<Models.Row> & Record<string, unknown> : Partial<Models.Row> & Partial<Omit<T, keyof Models.Row>>,\n ...(options?.permissions ? { permissions: resolvePermissions(options.permissions) } : {}),\n transactionId: options?.transactionId,\n }),\n delete: async (id: string, options?: { transactionId?: string }) => {\n await tablesDB.deleteRow({\n databaseId,\n tableId,\n rowId: id,\n transactionId: options?.transactionId,\n });\n },\n list: (options?: { queries?: (q: QueryBuilder<T>) => string[] }) =>\n tablesDB.listRows<T>({\n databaseId,\n tableId,\n queries: options?.queries?.(createQueryBuilder<T>()),\n }),{{{BULK_METHODS}}}\n };\n}\n\n{{{BULK_CHECK}}}\nconst hasOwn = (obj: unknown, key: string): boolean =>\n obj != null && Object.prototype.hasOwnProperty.call(obj, key);\n\nfunction createDatabaseHandle<D extends DatabaseId>(\n tablesDB: TablesDB,\n databaseId: D,\n): DatabaseHandle<D> {\n const tableApiCache = new Map<string, unknown>();\n const dbMap = tableIdMap[databaseId];\n\n return {\n use: <T extends keyof DatabaseTableMap[D] & string>(tableId: T): DatabaseTableMap[D][T] => {\n if (!hasOwn(dbMap, tableId)) {\n throw new Error(`Unknown table "${tableId}" in database "${databaseId}"`);\n }\n\n if (!tableApiCache.has(tableId)) {\n const resolvedTableId = dbMap[tableId];\n const api = createTableApi(tablesDB, databaseId, resolvedTableId);\n {{{BULK_REMOVAL}}}\n tableApiCache.set(tableId, api);\n }\n return tableApiCache.get(tableId) as DatabaseTableMap[D][T];\n },\n{{#if supportsServerSide}}\n create: (tableId: string, name: string, options?: { permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; rowSecurity?: boolean; enabled?: boolean; columns?: object[]; indexes?: object[] }) =>\n tablesDB.createTable({\n databaseId,\n tableId,\n name,\n permissions: resolvePermissions(options?.permissions),\n rowSecurity: options?.rowSecurity,\n enabled: options?.enabled,\n columns: options?.columns,\n indexes: options?.indexes,\n }),\n update: (tableId: string, options?: { name?: string; permissions?: (permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]; rowSecurity?: boolean; enabled?: boolean }) => {\n if (!hasOwn(dbMap, tableId)) {\n throw new Error(`Unknown table "${tableId}" in database "${databaseId}"`);\n }\n const resolvedTableId = dbMap[tableId];\n return tablesDB.updateTable({\n databaseId,\n tableId: resolvedTableId,\n name: options?.name,\n permissions: resolvePermissions(options?.permissions),\n rowSecurity: options?.rowSecurity,\n enabled: options?.enabled,\n });\n },\n delete: async (tableId: string) => {\n if (!hasOwn(dbMap, tableId)) {\n throw new Error(`Unknown table "${tableId}" in database "${databaseId}"`);\n }\n const resolvedTableId = dbMap[tableId];\n await tablesDB.deleteTable({\n databaseId,\n tableId: resolvedTableId,\n });\n },\n{{/if}}\n };\n}\n\nfunction createDatabasesApi(tablesDB: TablesDB): DatabaseTables {\n const dbCache = new Map<DatabaseId, ReturnType<typeof createDatabaseHandle>>();\n\n return {\n use: (databaseId: DatabaseId) => {\n if (!hasOwn(tableIdMap, databaseId)) {\n throw new Error(`Unknown database "${databaseId}"`);\n }\n\n if (!dbCache.has(databaseId)) {\n dbCache.set(databaseId, createDatabaseHandle(tablesDB, databaseId));\n }\n return dbCache.get(databaseId);\n },\n{{#if supportsServerSide}}\n create: (databaseId: string, name: string, options?: { enabled?: boolean }) =>\n tablesDB.create({\n databaseId,\n name,\n enabled: options?.enabled,\n }),\n update: (databaseId: DatabaseId, options?: { name?: string; enabled?: boolean }) => {\n return tablesDB.update({\n databaseId,\n name: options?.name ?? databaseId,\n enabled: options?.enabled,\n });\n },\n delete: async (databaseId: DatabaseId) => {\n await tablesDB.delete({\n databaseId,\n });\n },\n{{/if}}\n } as DatabaseTables;\n}\n\n// Initialize client\nconst client = new Client()\n .setEndpoint(ENDPOINT)\n .setProject(PROJECT_ID){{#if supportsServerSide}}\n .setKey(API_KEY){{/if}};\n\nconst tablesDB = new TablesDB(client);\n\nexport const databases: DatabaseTables = createDatabasesApi(tablesDB);\n';
@@ -110558,7 +110846,7 @@ var databasesTemplate = import_handlebars.default.compile(String(databases_ts_de
110558
110846
  var indexTemplate = import_handlebars.default.compile(String(index_ts_default));
110559
110847
  var constantsTemplate = import_handlebars.default.compile(String(constants_ts_default));
110560
110848
  var PERMISSION_CALLBACK_INLINE = `(permission: { read: (role: RoleString) => string; write: (role: RoleString) => string; create: (role: RoleString) => string; update: (role: RoleString) => string; delete: (role: RoleString) => string }, role: { any: () => RoleString; user: (userId: string, status?: string) => RoleString; users: (status?: string) => RoleString; guests: () => RoleString; team: (teamId: string, role?: string) => RoleString; member: (memberId: string) => RoleString; label: (label: string) => RoleString }) => string[]`;
110561
- var getQueryCallbackInline = (typeName) => `(q: { equal: <K extends QueryableKeys<${typeName}>>(field: K, value: ExtractQueryValue<${typeName}[K]>) => string; notEqual: <K extends QueryableKeys<${typeName}>>(field: K, value: ExtractQueryValue<${typeName}[K]>) => string; lessThan: <K extends QueryableKeys<${typeName}>>(field: K, value: ExtractQueryValue<${typeName}[K]>) => string; lessThanEqual: <K extends QueryableKeys<${typeName}>>(field: K, value: ExtractQueryValue<${typeName}[K]>) => string; greaterThan: <K extends QueryableKeys<${typeName}>>(field: K, value: ExtractQueryValue<${typeName}[K]>) => string; greaterThanEqual: <K extends QueryableKeys<${typeName}>>(field: K, value: ExtractQueryValue<${typeName}[K]>) => string; contains: <K extends QueryableKeys<${typeName}>>(field: K, value: ExtractQueryValue<${typeName}[K]>) => string; search: <K extends QueryableKeys<${typeName}>>(field: K, value: string) => string; isNull: <K extends QueryableKeys<${typeName}>>(field: K) => string; isNotNull: <K extends QueryableKeys<${typeName}>>(field: K) => string; startsWith: <K extends QueryableKeys<${typeName}>>(field: K, value: string) => string; endsWith: <K extends QueryableKeys<${typeName}>>(field: K, value: string) => string; between: <K extends QueryableKeys<${typeName}>>(field: K, start: ExtractQueryValue<${typeName}[K]>, end: ExtractQueryValue<${typeName}[K]>) => string; select: <K extends keyof ${typeName}>(fields: K[]) => string; orderAsc: <K extends keyof ${typeName}>(field: K) => string; orderDesc: <K extends keyof ${typeName}>(field: K) => string; limit: (value: number) => string; offset: (value: number) => string; cursorAfter: (documentId: string) => string; cursorBefore: (documentId: string) => string; or: (...queries: string[]) => string; and: (...queries: string[]) => string }) => string[]`;
110849
+ var getQueryCallbackInline = (typeName) => `(q: { equal: <K extends QueryableKeys<${typeName}>>(field: K, value: QueryableFieldValue<${typeName}, K>) => string; notEqual: <K extends QueryableKeys<${typeName}>>(field: K, value: QueryableFieldValue<${typeName}, K>) => string; lessThan: <K extends QueryableKeys<${typeName}>>(field: K, value: QueryableFieldValue<${typeName}, K>) => string; lessThanEqual: <K extends QueryableKeys<${typeName}>>(field: K, value: QueryableFieldValue<${typeName}, K>) => string; greaterThan: <K extends QueryableKeys<${typeName}>>(field: K, value: QueryableFieldValue<${typeName}, K>) => string; greaterThanEqual: <K extends QueryableKeys<${typeName}>>(field: K, value: QueryableFieldValue<${typeName}, K>) => string; contains: <K extends QueryableKeys<${typeName}>>(field: K, value: QueryableFieldValue<${typeName}, K>) => string; search: <K extends QueryableKeys<${typeName}>>(field: K, value: string) => string; isNull: <K extends QueryableKeys<${typeName}>>(field: K) => string; isNotNull: <K extends QueryableKeys<${typeName}>>(field: K) => string; startsWith: <K extends QueryableKeys<${typeName}>>(field: K, value: string) => string; endsWith: <K extends QueryableKeys<${typeName}>>(field: K, value: string) => string; between: <K extends QueryableKeys<${typeName}>>(field: K, start: QueryableFieldValue<${typeName}, K>, end: QueryableFieldValue<${typeName}, K>) => string; select: <K extends keyof ${typeName}>(fields: K[]) => string; orderAsc: <K extends keyof ${typeName}>(field: K) => string; orderDesc: <K extends keyof ${typeName}>(field: K) => string; limit: (value: number) => string; offset: (value: number) => string; cursorAfter: (documentId: string) => string; cursorBefore: (documentId: string) => string; or: (...queries: string[]) => string; and: (...queries: string[]) => string }) => string[]`;
110562
110850
  var TypeScriptDatabasesGenerator = class extends BaseDatabasesGenerator {
110563
110851
  language = "typescript";
110564
110852
  fileExtension = "ts";