@@ -6,10 +6,10 @@ const inquirer = require("inquirer");
66const JSONbig = require("json-bigint")({ storeAsString: false });
77const { Command } = require("commander");
88const ID = require("../id");
9- const { localConfig, globalConfig, KeysAttributes, KeysFunction, KeysSite, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, KeysCollection } = require("../config");
9+ const { localConfig, globalConfig, KeysAttributes, KeysFunction, KeysSite, whitelistKeys, KeysTopics, KeysStorage, KeysTeams, KeysCollection, KeysTable  } = require("../config");
1010const { Spinner, SPINNER_ARC, SPINNER_DOTS } = require('../spinner');
1111const { paginate } = require('../paginate');
12- const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsPushSites, questionsGetEntrypoint, questionsPushCollections, questionPushChanges, questionPushChangesConfirmation, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
12+ const { questionsPushBuckets, questionsPushTeams, questionsPushFunctions, questionsPushSites, questionsGetEntrypoint, questionsPushCollections, questionsPushTables,  questionPushChanges, questionPushChangesConfirmation, questionsPushMessagingTopics, questionsPushResources } = require("../questions");
1313const { cliConfig, actionRunner, success, warn, log, hint, error, commandDescriptions, drawTable } = require("../parser");
1414const { proxyCreateFunctionRule, proxyCreateSiteRule, proxyListRules } = require('./proxy');
1515const { consoleVariables } = require('./console');
@@ -49,6 +49,10 @@ const {
4949    databasesListIndexes,
5050    databasesUpdateCollection
5151} = require("./databases");
52+ const {
53+     gridsGetDatabase,
54+     gridsGetTable
55+ } = require("./grids");
5256const {
5357    storageGetBucket, storageUpdateBucket, storageCreateBucket
5458} = require("./storage");
@@ -919,6 +923,7 @@ const pushResources = async () => {
919923        functions: pushFunction,
920924        sites: pushSite,
921925        collections: pushCollection,
926+         tables: pushTable,
922927        buckets: pushBucket,
923928        teams: pushTeam,
924929        messages: pushMessagingTopic
@@ -1672,7 +1677,150 @@ const pushFunction = async ({ functionId, async, code, withVariables } = { retur
16721677    }
16731678}
16741679
1680+ const pushTable = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1681+     const tables = [];
1682+ 
1683+     if (attempts) {
1684+         pollMaxDebounces = attempts;
1685+     }
1686+ 
1687+     if (cliConfig.all) {
1688+         checkDeployConditions(localConfig);
1689+         tables.push(...localConfig.getTables());
1690+     } else {
1691+         const answers = await inquirer.prompt(questionsPushTables)
1692+         if (answers.tables) {
1693+             const configTables = new Map();
1694+             localConfig.getTables().forEach((c) => {
1695+                 configTables.set(`${c['databaseId']}|${c['$id']}`, c);
1696+             });
1697+             answers.tables.forEach((a) => {
1698+                 const table = configTables.get(a);
1699+                 tables.push(table);
1700+             })
1701+         }
1702+     }
1703+ 
1704+     if (tables.length === 0) {
1705+         log("No tables found.");
1706+         hint("Use 'appwrite pull tables' to synchronize existing one, or use 'appwrite init table' to create a new one.");
1707+         return;
1708+     }
1709+ 
1710+     const databases = Array.from(new Set(tables.map(table => table['databaseId'])));
1711+ 
1712+     // Parallel db actions
1713+     await Promise.all(databases.map(async (databaseId) => {
1714+         const localDatabase = localConfig.getDatabase(databaseId);
1715+ 
1716+         try {
1717+             const database = await gridsGetDatabase({
1718+                 databaseId: databaseId,
1719+                 parseOutput: false,
1720+             });
1721+ 
1722+             if (database.name !== (localDatabase.name ?? databaseId)) {
1723+                 await databasesUpdate({
1724+                     databaseId: databaseId,
1725+                     name: localDatabase.name ?? databaseId,
1726+                     parseOutput: false
1727+                 })
1728+ 
1729+                 success(`Updated ${localDatabase.name} ( ${databaseId} ) name`);
1730+             }
1731+         } catch (err) {
1732+             log(`Database ${databaseId} not found. Creating it now ...`);
1733+ 
1734+             await databasesCreate({
1735+                 databaseId: databaseId,
1736+                 name: localDatabase.name ?? databaseId,
1737+                 parseOutput: false,
1738+             });
1739+         }
1740+     }));
1741+ 
1742+ 
1743+     if (!(await approveChanges(tables, gridsGetTable, KeysTable, 'tableId', 'tables', ['columns', 'indexes'], 'databaseId', 'databaseId',))) {
1744+         return;
1745+     }
1746+     // Parallel collection actions
1747+     await Promise.all(tables.map(async (table) => {
1748+         try {
1749+             const remoteTable = await gridsGetTable({
1750+                 databaseId: table['databaseId'],
1751+                 tableId: table['$id'],
1752+                 parseOutput: false,
1753+             });
1754+ 
1755+             if (remoteTable.name !== table.name) {
1756+                 await databasesUpdateTable({
1757+                     databaseId: table['databaseId'],
1758+                     tableId: table['$id'],
1759+                     name: table.name,
1760+                     name: table.name,
1761+                     parseOutput: false
1762+                 })
1763+ 
1764+                 success(`Updated ${table.name} ( ${table['$id']} ) name`);
1765+             }
1766+             table.remoteVersion = remoteTable;
1767+ 
1768+             table.isExisted = true;
1769+         } catch
1770+             (e) {
1771+             if (Number(e.code) === 404) {
1772+                 log(`Table ${table.name} does not exist in the project. Creating ... `);
1773+                 await databasesCreateTable({
1774+                     databaseId: table['databaseId'],
1775+                     tableId: table['$id'],
1776+                     name: table.name,
1777+                     documentSecurity: table.documentSecurity,
1778+                     permissions: table['$permissions'],
1779+                     parseOutput: false
1780+                 })
1781+             } else {
1782+                 throw e;
1783+             }
1784+         }
1785+     }))
1786+     let numberOfTables = 0;
1787+     // Serialize attribute actions
1788+     for (let table of tables) {
1789+         let columns = table.columns;
1790+         let indexes = table.indexes;
1791+ 
1792+         if (table.isExisted) {
1793+             columns = await attributesToCreate(table.remoteVersion.columns, table.columns, table);
1794+             indexes = await attributesToCreate(table.remoteVersion.indexes, table.indexes, table, true);
1795+ 
1796+             if ((Array.isArray(columns) &&  columns.length < = 0) &&  (Array.isArray(indexes) &&  indexes.length < = 0)) {
1797+                 continue;
1798+             }
1799+ 
1800+         }
1801+ 
1802+         log(`Pushing table ${table.name} ( ${table['databaseId']} - ${table['$id']} ) attributes`)
1803+ 
1804+         try {
1805+             await createAttributes(columns, table)
1806+         } catch (e) {
1807+             throw e;
1808+         }
1809+ 
1810+         try {
1811+             await createIndexes(indexes, table);
1812+         } catch (e) {
1813+             throw e;
1814+         }
1815+         numberOfTables++;
1816+         success(`Successfully pushed ${table.name} ( ${table['$id']} )`);
1817+     }
1818+ 
1819+     success(`Successfully pushed ${numberOfTables} tables`);
1820+ }
1821+ 
16751822const pushCollection = async ({ returnOnZero, attempts } = { returnOnZero: false }) => {
1823+     warn("appwrite push collection has been deprecated. Please consider using 'appwrite push tables' instead");
16761824    const collections = [];
16771825
16781826    if (attempts) {
@@ -2083,10 +2231,17 @@ push
20832231push
20842232    .command("collection")
20852233    .alias("collections")
2086-     .description("Push collections in the current project.")
2234+     .description("Push collections in the current project. (deprecated, please use 'push tables' instead) ")
20872235    .option(`-a, --attempts <numberOfAttempts >`, `Max number of attempts before timing out. default: 30.`)
20882236    .action(actionRunner(pushCollection));
20892237
2238+ push
2239+     .command("table")
2240+     .alias("tables")
2241+     .description("Push tables in the current project.")
2242+     .option(`-a, --attempts <numberOfAttempts >`, `Max number of attempts before timing out. default: 30.`)
2243+     .action(actionRunner(pushTable));
2244+ 
20902245push
20912246    .command("bucket")
20922247    .alias("buckets")
0 commit comments