mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +00:00 
			
		
		
		
	(core) updates from grist-core
This commit is contained in:
		
						commit
						cea0404a22
					
				
							
								
								
									
										107
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								README.md
									
									
									
									
									
								
							| @ -1,23 +1,12 @@ | ||||
| # Grist | ||||
| 
 | ||||
| Grist is a modern relational spreadsheet. It combines the flexibility of a spreadsheet with the | ||||
| robustness of a database to organize your data and make you more productive. | ||||
| Grist is a modern relational spreadsheet. It combines the flexibility of a spreadsheet with the robustness of a database to organize your data and make you more productive. | ||||
| 
 | ||||
| This repository, `grist-core`, is the heart of Grist, and has what you | ||||
| need to run a powerful spreadsheet hosting server. If you wish to view and edit | ||||
| spreadsheets stored locally, another option is to use the | ||||
| [`grist-electron`](https://github.com/gristlabs/grist-electron) desktop app for Linux, Mac, and Windows. And to show Grist spreadsheets on a website | ||||
| without any special back-end support, your options include | ||||
| [`grist-static`](https://github.com/gristlabs/grist-static), | ||||
| a fully in-browser build of Grist. | ||||
| The `grist-core` repository is the basis for all these options, and | ||||
| for the hosted spreadsheet services offered by | ||||
| [`Grist Labs`](https://getgrist.com), an NYC-based company 🇺🇸 that is the main developer of Grist, and by | ||||
| [`ANCT Données et Territoires`](https://donnees.incubateur.anct.gouv.fr/toolbox/grist), | ||||
| a French government agency 🇫🇷 whose developers have made many | ||||
| contributions to the code-base. | ||||
| The `grist-core`, `grist-electron`, and `grist-static` repositories | ||||
| are all open-source (Apache License, Version 2.0). | ||||
| This repository, `grist-core`, is the heart of Grist, and has what you need to run a powerful spreadsheet hosting server. If you wish to view and edit spreadsheets stored locally, another option is to use the [`grist-electron`](https://github.com/gristlabs/grist-electron) desktop app for Linux, Mac, and Windows. And to show Grist spreadsheets on a website without any special back-end support, you can use [`grist-static`](https://github.com/gristlabs/grist-static), a fully in-browser build of Grist. | ||||
| 
 | ||||
| The `grist-core` repository is the basis for all these options, and for the hosted spreadsheet services offered by [Grist Labs](https://getgrist.com), an NYC-based company 🇺🇸 that is the main developer of Grist, and by [ANCT Données et Territoires](https://donnees.incubateur.anct.gouv.fr/toolbox/grist), a French government agency 🇫🇷 whose developers have made many contributions to the codebase. | ||||
| 
 | ||||
| The `grist-core`, `grist-electron`, and `grist-static` repositories are all open source (Apache License, Version 2.0). | ||||
| 
 | ||||
| https://user-images.githubusercontent.com/118367/151245587-892e50a6-41f5-4b74-9786-fe3566f6b1fb.mp4 | ||||
| 
 | ||||
| @ -25,81 +14,69 @@ https://user-images.githubusercontent.com/118367/151245587-892e50a6-41f5-4b74-97 | ||||
| 
 | ||||
| Grist is a hybrid database/spreadsheet, meaning that: | ||||
| 
 | ||||
|   - Columns work like they do in databases. They are named, and hold one kind of data. | ||||
|   - Columns work like they do in databases: they are named, and they hold one kind of data. | ||||
|   - Columns can be filled by formula, spreadsheet-style, with automatic updates when referenced cells change. | ||||
| 
 | ||||
| This difference can confuse people coming directly from Excel or Google Sheets. Give it a chance! | ||||
| If you are coming from Airtable, you'll find the model familiar though (and there's a | ||||
| [Grist vs Airtable](https://www.getgrist.com/blog/grist-v-airtable/) article that might interest you). | ||||
| 
 | ||||
| This difference can confuse people coming directly from Excel or Google Sheets. Give it a chance! If you are coming from Airtable, you'll find the model familiar though (and there's a [Grist vs Airtable](https://www.getgrist.com/blog/grist-v-airtable/) article that might interest you). | ||||
| 
 | ||||
| Here are some specific feature highlights of Grist: | ||||
| 
 | ||||
|   * Python formulas. | ||||
|     - Full [Python syntax is supported](https://support.getgrist.com/formulas/#python), and the standard library. | ||||
|     - Full [Python syntax is supported](https://support.getgrist.com/formulas/#python), including the standard library. | ||||
|     - Many [Excel functions](https://support.getgrist.com/functions/) also available. | ||||
|     - An [AI Assistant](https://www.getgrist.com/ai-formula-assistant/) specifically tuned for formula generation (using OpenAI gpt-3.5-turbo or [Llama](https://ai.meta.com/llama/) via <a href="https://github.com/abetlen/llama-cpp-python">llama-cpp-python</a>). | ||||
|   * A portable, self-contained format. | ||||
|     - Based on SQLite, the most widely deployed database engine. | ||||
|     - Any tool that can read SQLite can read numeric and text data from a Grist file. | ||||
|     - Great format for [backups](https://support.getgrist.com/exports/#backing-up-an-entire-document) that you can be confident you can restore in full. | ||||
|     - Great format for moving between different hosts. | ||||
|   - Can be displayed on a static website with [grist-static](https://github.com/gristlabs/grist-static), no special server needed. | ||||
|   - There's a self-contained desktop app available for viewing and editing: [grist-electron](https://github.com/gristlabs/grist-electron). | ||||
|     - Enables [backups](https://support.getgrist.com/exports/#backing-up-an-entire-document) that you can confidently restore in full. | ||||
|     - Great for moving between different hosts. | ||||
|   * Can be displayed on a static website with [`grist-static`](https://github.com/gristlabs/grist-static) – no special server needed. | ||||
|   * A self-contained desktop app for viewing and editing locally: [`grist-electron`](https://github.com/gristlabs/grist-electron). | ||||
|   * Convenient editing and formatting features. | ||||
|     - Choices and [choice lists](https://support.getgrist.com/col-types/#choice-list-columns), for adding colorful tags to records without fuss. | ||||
|     - Choices and [choice lists](https://support.getgrist.com/col-types/#choice-list-columns), for adding colorful tags to records. | ||||
|     - [References](https://support.getgrist.com/col-refs/#creating-a-new-reference-list-column) and reference lists, for cross-referencing records in other tables. | ||||
|     - [Attachments](https://support.getgrist.com/col-types/#attachment-columns), to include media or document files in records. | ||||
|     - Dates and times, toggles, and special numerics such as currency all have specialized editors and formatting options. | ||||
|     - [Conditional Formatting](https://support.getgrist.com/conditional-formatting/), letting you control the style of cells with formulas, to draw attention to important information. | ||||
|   * Great for dashboards, visualizations, and data entry. | ||||
|     - [Conditional Formatting](https://support.getgrist.com/conditional-formatting/), letting you control the style of cells with formulas to draw attention to important information. | ||||
|   * Drag-and-drop dashboards. | ||||
|     - [Charts](https://support.getgrist.com/widget-chart/) for visualization. | ||||
|     - [Summary tables](https://support.getgrist.com/summary-tables/) for summing and counting across groups. | ||||
|     - [Widget linking](https://support.getgrist.com/linking-widgets/) streamlines filtering and editing data. | ||||
|     Grist has a unique approach to visualization, where you can lay out and link distinct widgets to show together, | ||||
|     without cramming mixed material into a table. | ||||
|     - The [Filter bar](https://support.getgrist.com/search-sort-filter/#filter-buttons) is great for quick slicing and dicing. | ||||
|     - [Filter bar](https://support.getgrist.com/search-sort-filter/#filter-buttons) for quick slicing and dicing. | ||||
|   * [Incremental imports](https://support.getgrist.com/imports/#updating-existing-records). | ||||
|     - So you can import a CSV of the last three months activity from your bank... | ||||
|     - ... and import new activity a month later without fuss or duplicates. | ||||
|     - Import a CSV of the last three months activity from your bank... | ||||
|     - ...and import new activity a month later without fuss or duplication. | ||||
|   * Integrations. | ||||
|     - A [REST API](https://support.getgrist.com/api/), [Zapier actions/triggers](https://support.getgrist.com/integrators/#integrations-via-zapier), and support from similar [integrators](https://support.getgrist.com/integrators/). | ||||
|     - Import/export to Google drive, Excel format, CSV. | ||||
|     - Can link data with custom widgets hosted externally. | ||||
|     - You can set up outgoing webhooks. | ||||
|     - Link data with [custom widgets](https://support.getgrist.com/widget-custom/#_top), hosted externally. | ||||
|     - Configurable outgoing webhooks. | ||||
|   * [Many templates](https://templates.getgrist.com/) to get you started, from investment research to organizing treasure hunts. | ||||
|   * Access control options. | ||||
|     - (You'll need SSO logins set up to make use of these options; [grist-omnibus](https://github.com/gristlabs/grist-omnibus) has a prepackaged solution if configuring this feels daunting) | ||||
|     - Share [individual documents](https://support.getgrist.com/sharing/), or workspaces, or [team sites](https://support.getgrist.com/team-sharing/). | ||||
|     - (You'll need SSO logins set up to make use of these options; [`grist-omnibus`](https://github.com/gristlabs/grist-omnibus) has a prepackaged solution if configuring this feels daunting) | ||||
|     - Share [individual documents](https://support.getgrist.com/sharing/), workspaces, or [team sites](https://support.getgrist.com/team-sharing/). | ||||
|     - Control access to [individual rows, columns, and tables](https://support.getgrist.com/access-rules/). | ||||
|     - Control access based on cell values and user attributes. | ||||
|   * Can be self-maintained. | ||||
|   * Self-maintainable. | ||||
|     - Useful for intranet operation and specific compliance requirements. | ||||
|   * Sandboxing options for untrusted documents. | ||||
|     - On Linux or with docker, you can enable | ||||
|       [gVisor](https://github.com/google/gvisor) sandboxing at the individual | ||||
|       document level. | ||||
|     - On OSX, you can use native sandboxing. | ||||
|     - On Linux or with Docker, you can enable [gVisor](https://github.com/google/gvisor) sandboxing at the individual document level. | ||||
|     - On macOS, you can use native sandboxing. | ||||
|     - On any OS, including Windows, you can use a wasm-based sandbox. | ||||
|   * Translated to many languages. | ||||
|   * Support for an AI Formula Assistant (using OpenAI gpt-3.5-turbo or comparable models). | ||||
|   * `F1` key brings up some quick help. This used to go without saying. In general Grist has good keyboard support. | ||||
|   * We post progress on [𝕏 or Twitter or whatever](https://twitter.com/getgrist). | ||||
| 
 | ||||
| If you are curious about where Grist is going heading, | ||||
| see [our roadmap](https://github.com/gristlabs/grist-core/projects/1), drop a | ||||
| question in [our forum](https://community.getgrist.com), | ||||
| or browse [our extensive documentation](https://support.getgrist.com). | ||||
|   * `F1` key brings up some quick help. This used to go without saying, but in general Grist has good keyboard support. | ||||
|   * We post progress on [𝕏 or Twitter or whatever](https://twitter.com/getgrist) and publish [monthly newsletters](https://support.getgrist.com/newsletters/). | ||||
| 
 | ||||
| If you are curious about where Grist is heading, see [our roadmap](https://github.com/gristlabs/grist-core/projects/1), drop a question in [our forum](https://community.getgrist.com), or browse [our extensive documentation](https://support.getgrist.com). | ||||
| 
 | ||||
| ## Using Grist | ||||
| 
 | ||||
| If you just want a quick demo of Grist: | ||||
| 
 | ||||
|   * You can try Grist out at the hosted service run | ||||
|     by Grist Labs at [docs.getgrist.com](https://docs.getgrist.com) | ||||
|   (no registration needed). | ||||
|   * Or you can see an experimental fully in-browser build of Grist | ||||
|     at [gristlabs.github.io/grist-static](https://gristlabs.github.io/grist-static/). | ||||
|   * You can try Grist out at the hosted service run by Grist Labs at [docs.getgrist.com](https://docs.getgrist.com) (no registration needed). | ||||
|   * Or you can see a fully in-browser build of Grist at [gristlabs.github.io/grist-static](https://gristlabs.github.io/grist-static/). | ||||
|   * Or you can download Grist as a desktop app from [github.com/gristlabs/grist-electron](https://github.com/gristlabs/grist-electron). | ||||
| 
 | ||||
| To get `grist-core` running on your computer with [Docker](https://www.docker.com/get-started), do: | ||||
| @ -150,7 +127,7 @@ Grist formulas in documents will be run using Python executed directly on your | ||||
| machine. You can configure sandboxing using a `GRIST_SANDBOX_FLAVOR` | ||||
| environment variable. | ||||
| 
 | ||||
|  * On OSX, `export GRIST_SANDBOX_FLAVOR=macSandboxExec` | ||||
|  * On macOS, `export GRIST_SANDBOX_FLAVOR=macSandboxExec` | ||||
|    uses the native `sandbox-exec` command for sandboxing. | ||||
|  * On Linux with [gVisor's runsc](https://github.com/google/gvisor) | ||||
|    installed, `export GRIST_SANDBOX_FLAVOR=gvisor` is an option. | ||||
| @ -195,18 +172,15 @@ did the hard work of making a good chunk of the application localizable. Merci b | ||||
| 
 | ||||
| This repository, [grist-core](https://github.com/gristlabs/grist-core), is maintained by Grist | ||||
| Labs. Our flagship product available at [getgrist.com](https://www.getgrist.com) is built from the code you see | ||||
| here, combined with business-specific software designed to scale it to many users, handle billing, | ||||
| here, combined with business-specific software designed to scale to many users, handle billing, | ||||
| etc. | ||||
| 
 | ||||
| Grist Labs is an open-core company. We offer Grist hosting as a | ||||
| service, with free and paid plans. We also develop and sell | ||||
| features related to Grist using a proprietary license, targeted at the | ||||
| needs of enterprises with large self-managed installations. We see | ||||
| data portability and autonomy as a key value Grist can bring to our | ||||
| users, and `grist-core` as an essential means to deliver that. We are | ||||
| committed to maintaining and improving the `grist-core` codebase, and | ||||
| to be thoughtful about how proprietary offerings impact data portability | ||||
| and autonomy. | ||||
| needs of enterprises with large self-managed installations.  | ||||
| 
 | ||||
| We see data portability and autonomy as a key value, and `grist-core` is an essential part of that. We are committed to maintaining and improving the `grist-core` codebase, and to be thoughtful about how proprietary offerings impact data portability and autonomy. | ||||
| 
 | ||||
| By opening its source code and offering an [OSI](https://opensource.org/)-approved free license, | ||||
| Grist benefits its users: | ||||
| @ -223,10 +197,9 @@ Grist benefits its users: | ||||
| - **Price flexibility.** If you are low on funds but have time to invest, self-hosting is a great | ||||
|   option to have. And DIY users may have the technical savvy and motivation to delve in and make improvements, | ||||
|   which can benefit all users of Grist. | ||||
| - **Extensibility.** For developers, having the source open makes it easier to build extensions (such as the | ||||
|   experimental [Custom Widget](https://support.getgrist.com/widget-custom/)). You can more easily | ||||
|   include Grist in your pipeline. And if a feature is missing, you can just take the source code and | ||||
|   build on top of it. | ||||
| - **Extensibility.** For developers, having the source open makes it easier to build extensions (such as [Custom Widgets](https://support.getgrist.com/widget-custom/)). You can more easily include Grist in your pipeline. And if a feature is missing, you can just take the source code and build on top of it. | ||||
| 
 | ||||
| For more on Grist Labs' history and principles, see our [About Us](https://www.getgrist.com/about/) page. | ||||
| 
 | ||||
| ## Sponsors | ||||
| 
 | ||||
|  | ||||
| @ -72,6 +72,8 @@ export interface SessionObj { | ||||
|   oidc?: { | ||||
|     // codeVerifier is used during OIDC authentication, to protect against attacks like CSRF.
 | ||||
|     codeVerifier?: string; | ||||
|     state?: string; | ||||
|     targetUrl?: string; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -36,7 +36,7 @@ export async function collectTableSchemaInFrictionlessFormat( | ||||
|   req: express.Request, | ||||
|   options: DownloadOptions | ||||
| ): Promise<FrictionlessFormat> { | ||||
|   const {tableId} = options; | ||||
|   const {tableId, header} = options; | ||||
|   if (!activeDoc.docData) { | ||||
|     throw new Error('No docData in active document'); | ||||
|   } | ||||
| @ -50,24 +50,15 @@ export async function collectTableSchemaInFrictionlessFormat( | ||||
|     throw new ApiError(`Table ${tableId} not found.`, 404); | ||||
|   } | ||||
| 
 | ||||
|   const data = await exportTable(activeDoc, tableRef, req); | ||||
|   const tableSchema = columnsToTableSchema(tableId, data, settings.locale); | ||||
|   return tableSchema; | ||||
| } | ||||
| 
 | ||||
| function columnsToTableSchema( | ||||
|   tableId: string, | ||||
|   {tableName, columns}: {tableName: string, columns: ExportColumn[]}, | ||||
|   locale: string, | ||||
| ): FrictionlessFormat { | ||||
|   const {tableName, columns} = await exportTable(activeDoc, tableRef, req); | ||||
|   return { | ||||
|     name: tableId.toLowerCase().replace(/_/g, '-'), | ||||
|     title: tableName, | ||||
|     schema: { | ||||
|       fields: columns.map(col => ({ | ||||
|         name: col.label, | ||||
|         name: col[header || "label"], | ||||
|         ...(col.description ? {description: col.description} : {}), | ||||
|         ...buildTypeField(col, locale), | ||||
|         ...buildTypeField(col, settings.locale), | ||||
|       })), | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| @ -78,6 +78,7 @@ export class OIDCConfig { | ||||
|       redirect_uris: [ this._redirectUrl ], | ||||
|       response_types: [ 'code' ], | ||||
|     }); | ||||
|     log.info(`OIDCConfig: initialized with issuer ${issuerUrl}`); | ||||
|   } | ||||
| 
 | ||||
|   public addEndpoints(app: express.Application, sessions: Sessions): void { | ||||
| @ -85,15 +86,18 @@ export class OIDCConfig { | ||||
|   } | ||||
| 
 | ||||
|   public async handleCallback(sessions: Sessions, req: express.Request, res: express.Response): Promise<void> { | ||||
|     const mreq = req as RequestWithLogin; | ||||
|     try { | ||||
|       const params = this._client.callbackParams(req); | ||||
|       const { state } = params; | ||||
|       const { state, targetUrl } = mreq.session?.oidc ?? {}; | ||||
|       if (!state) { | ||||
|         throw new Error('Login or logout failed to complete'); | ||||
|       } | ||||
| 
 | ||||
|       const codeVerifier = await this._retrieveCodeVerifierFromSession(req); | ||||
| 
 | ||||
|       // The callback function will compare the state present in the params and the one we retrieved from the session.
 | ||||
|       // If they don't match, it will throw an error.
 | ||||
|       const tokenSet = await this._client.callback( | ||||
|         this._redirectUrl, | ||||
|         params, | ||||
| @ -102,23 +106,29 @@ export class OIDCConfig { | ||||
| 
 | ||||
|       const userInfo = await this._client.userinfo(tokenSet); | ||||
|       const profile = this._makeUserProfileFromUserInfo(userInfo); | ||||
|       log.info(`OIDCConfig: got OIDC response for ${profile.email} (${profile.name}) redirecting to ${targetUrl}`); | ||||
| 
 | ||||
|       const scopedSession = sessions.getOrCreateSessionFromRequest(req); | ||||
|       await scopedSession.operateOnScopedSession(req, async (user) => Object.assign(user, { | ||||
|         profile, | ||||
|       })); | ||||
| 
 | ||||
|       res.redirect('/'); | ||||
|       delete mreq.session.oidc; | ||||
|       res.redirect(targetUrl ?? '/'); | ||||
|     } catch (err) { | ||||
|       log.error(`OIDC callback failed: ${err.message}`); | ||||
|       res.status(500).send(`OIDC callback failed: ${err.message}`); | ||||
|       log.error(`OIDC callback failed: ${err.stack}`); | ||||
|       // Delete the session data even if the login failed.
 | ||||
|       // This way, we prevent several login attempts.
 | ||||
|       //
 | ||||
|       // Also session deletion must be done before sending the response.
 | ||||
|       delete mreq.session.oidc; | ||||
|       res.status(500).send(`OIDC callback failed.`); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   public async getLoginRedirectUrl(req: express.Request): Promise<string> { | ||||
|     const codeVerifier = await this._generateAndStoreCodeVerifier(req); | ||||
|   public async getLoginRedirectUrl(req: express.Request, targetUrl: URL): Promise<string> { | ||||
|     const { codeVerifier, state } = await this._generateAndStoreConnectionInfo(req, targetUrl.href); | ||||
|     const codeChallenge = generators.codeChallenge(codeVerifier); | ||||
|     const state = generators.state(); | ||||
| 
 | ||||
|     const authUrl = this._client.authorizationUrl({ | ||||
|       scope: process.env.GRIST_OIDC_IDP_SCOPES || 'openid email profile', | ||||
| @ -135,15 +145,18 @@ export class OIDCConfig { | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   private async _generateAndStoreCodeVerifier(req: express.Request) { | ||||
|   private async _generateAndStoreConnectionInfo(req: express.Request, targetUrl: string) { | ||||
|     const mreq = req as RequestWithLogin; | ||||
|     if (!mreq.session) { throw new Error('no session available'); } | ||||
|     const codeVerifier = generators.codeVerifier(); | ||||
|     const state = generators.state(); | ||||
|     mreq.session.oidc = { | ||||
|       codeVerifier, | ||||
|       state, | ||||
|       targetUrl | ||||
|     }; | ||||
| 
 | ||||
|     return codeVerifier; | ||||
|     return { codeVerifier, state }; | ||||
|   } | ||||
| 
 | ||||
|   private async _retrieveCodeVerifierFromSession(req: express.Request) { | ||||
| @ -151,7 +164,6 @@ export class OIDCConfig { | ||||
|     if (!mreq.session) { throw new Error('no session available'); } | ||||
|     const codeVerifier = mreq.session.oidc?.codeVerifier; | ||||
|     if (!codeVerifier) { throw new Error('Login is stale'); } | ||||
|     delete mreq.session.oidc?.codeVerifier; | ||||
|     return codeVerifier; | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "grist-core", | ||||
|   "version": "1.1.7", | ||||
|   "version": "1.1.8", | ||||
|   "license": "Apache-2.0", | ||||
|   "description": "Grist is the evolution of spreadsheets", | ||||
|   "homepage": "https://github.com/gristlabs/grist-core", | ||||
|  | ||||
| @ -17,7 +17,9 @@ | ||||
|         "Everyone": "Všichni", | ||||
|         "Allow everyone to copy the entire document, or view it in full in fiddle mode.\nUseful for examples and templates, but not for sensitive data.": "Umožni všem kopírovat celý dokument, nebo zobrazit plně v \"fiddle\" režimu.\nUžiitečné pro ukázky a šablony, ale ne pro citlivá data.", | ||||
|         "Add Default Rule": "Přidej Základní Pravidlo", | ||||
|         "Checking...": "Kontroluji…" | ||||
|         "Checking...": "Kontroluji…", | ||||
|         "Permissions": "Povolení", | ||||
|         "Permission to view Access Rules": "Povolení na zobrazení Přistupových Pravidel" | ||||
|     }, | ||||
|     "ACUserManager": { | ||||
|         "Invite new member": "Pozvi nového uživatele", | ||||
|  | ||||
| @ -1055,7 +1055,8 @@ | ||||
|         "Can't find the right columns? Click 'Change Widget' to select the table with events data.": "Не можете найти нужные столбцы? Нажмите «Изменить виджет», чтобы выбрать таблицу с данными о событиях.", | ||||
|         "A UUID is a randomly-generated string that is useful for unique identifiers and link keys.": "UUID - это случайно сгенерированная строка, которая полезна для уникальных идентификаторов и ключевых ссылок.", | ||||
|         "Lookups return data from related tables.": "Lookups возвращают данные из связанных таблиц.", | ||||
|         "Use reference columns to relate data in different tables.": "Используйте ссылочные столбцы для сопоставления данных в разных таблицах." | ||||
|         "Use reference columns to relate data in different tables.": "Используйте ссылочные столбцы для сопоставления данных в разных таблицах.", | ||||
|         "You can choose from widgets available to you in the dropdown, or embed your own by providing its full URL.": "Вы можете выбрать виджеты, доступные вам в раскрывающемся списке, или встроить свой собственный, указав его полный URL-адрес." | ||||
|     }, | ||||
|     "DescriptionConfig": { | ||||
|         "DESCRIPTION": "ОПИСАНИЕ" | ||||
|  | ||||
| @ -19,19 +19,19 @@ | ||||
|         "Type a message...": "Vnesite sporočilo…", | ||||
|         "User Attributes": "Atributi uporabnika", | ||||
|         "View As": "Poglej kot", | ||||
|         "When adding table rules, automatically add a rule to grant OWNER full access.": "Pri dodajanju pravil za tabele samodejno dodajte pravilo, ki lastniku omogoča popoln dostop.", | ||||
|         "When adding table rules, automatically add a rule to grant OWNER full access.": "Pri dodajanju pravil za tabele samodejno dodaj pravilo, ki lastniku omogoča popoln dostop.", | ||||
|         "Permission to edit document structure": "Dovoljenje za urejanje strukture dokumenta", | ||||
|         "Everyone": "Vsi", | ||||
|         "Everyone Else": "Vsi ostali", | ||||
|         "Checking...": "Preverjanje…", | ||||
|         "Condition": "Stanje", | ||||
|         "Enter Condition": "Vnesite pogoj", | ||||
|         "Add Column Rule": "Dodajanje pravila za stolpce", | ||||
|         "Add Column Rule": "Dodaj pravila za stolpec", | ||||
|         "Add Default Rule": "Dodaj privzeto pravilo", | ||||
|         "Add Table Rules": "Dodajanje pravil tabele", | ||||
|         "Add User Attributes": "Dodajanje atributov uporabnika", | ||||
|         "Add Table Rules": "Dodaj pravila  za tabelo", | ||||
|         "Add User Attributes": "Dodaj atribute za uporabnika", | ||||
|         "Allow everyone to copy the entire document, or view it in full in fiddle mode.\nUseful for examples and templates, but not for sensitive data.": "Vsakomur omogočite kopiranje celotnega dokumenta ali pa si ga oglejte v celoti v načinu fiddle.\nUporabno za primere in predloge, ne pa za občutljive podatke.", | ||||
|         "Allow everyone to view Access Rules.": "Vsakomur omogočite ogled pravil za dostop.", | ||||
|         "Allow everyone to view Access Rules.": "Omogoči vsakomur  ogled pravil za dostop.", | ||||
|         "Attribute name": "Ime atributa", | ||||
|         "Attribute to Look Up": "Atribut za iskanje", | ||||
|         "Lookup Table": "Preglednica za iskanje", | ||||
| @ -40,8 +40,8 @@ | ||||
|     }, | ||||
|     "ACUserManager": { | ||||
|         "We'll email an invite to {{email}}": "Vabilo bomo poslali po e-pošti {{email}}", | ||||
|         "Enter email address": "Vnesite e-poštni naslov", | ||||
|         "Invite new member": "Povabite novega člana" | ||||
|         "Enter email address": "Vnesi e-poštni naslov", | ||||
|         "Invite new member": "Povabi novega člana" | ||||
|     }, | ||||
|     "AccountPage": { | ||||
|         "API": "API", | ||||
| @ -110,7 +110,7 @@ | ||||
|         "Translators: please translate this only when your language is ready to be offered to users": "Prevajalci: prosimo, prevedite to šele, ko bo vaš jezik pripravljen, da se ponudi uporabnikom" | ||||
|     }, | ||||
|     "CellContextMenu": { | ||||
|         "Delete {{count}} columns_one": "Brisanje stolpca", | ||||
|         "Delete {{count}} columns_one": "Briši stolpec", | ||||
|         "Delete {{count}} columns_other": "Brisanje stolpcev {{count}}", | ||||
|         "Delete {{count}} rows_one": "Brisanje vrstice", | ||||
|         "Delete {{count}} rows_other": "Brisanje vrstic {{count}}", | ||||
| @ -118,12 +118,12 @@ | ||||
|         "Copy anchor link": "Kopiranje sidrne povezave", | ||||
|         "Duplicate rows_one": "Podvoji vrstico", | ||||
|         "Duplicate rows_other": "Podvoji vrstice", | ||||
|         "Insert column to the right": "Vstavi stolpec na desno", | ||||
|         "Insert column to the left": "Vstavi stolpec na levo", | ||||
|         "Insert column to the right": "Vstavi stolpec na desno stran", | ||||
|         "Insert column to the left": "Vstavi stolpec na levo stran", | ||||
|         "Insert row": "Vstavljanje vrstice", | ||||
|         "Insert row above": "Vstavite vrstico zgoraj", | ||||
|         "Insert row below": "Vstavi vrstico spodaj", | ||||
|         "Reset {{count}} columns_one": "Ponastavitev stolpca", | ||||
|         "Reset {{count}} columns_one": "Ponastavi stolpec", | ||||
|         "Reset {{count}} columns_other": "Ponastavit {{count}} stolpcev", | ||||
|         "Reset {{count}} entire columns_one": "Ponastavi celote stolpec", | ||||
|         "Reset {{count}} entire columns_other": "Ponastavi {{count}} celotnih stolpcev", | ||||
| @ -177,7 +177,7 @@ | ||||
|     }, | ||||
|     "GridViewMenus": { | ||||
|         "Rename column": "Preimenuj stolpec", | ||||
|         "Delete {{count}} columns_one": "Brisanje stolpca", | ||||
|         "Delete {{count}} columns_one": "Briši stolpec", | ||||
|         "Delete {{count}} columns_other": "Brisanje stolpcev {{count}}", | ||||
|         "Unfreeze {{count}} columns_one": "Odmrzni ta stolpec", | ||||
|         "Sorted (#{{count}})_one": "Razvrščeno (#{{count}})", | ||||
| @ -189,7 +189,7 @@ | ||||
|         "Filter Data": "Filtriranje podatkov", | ||||
|         "Hide {{count}} columns_other": "Skrij {{count}} stolpcev", | ||||
|         "Add Column": "Dodaj stolpec", | ||||
|         "Reset {{count}} columns_one": "Ponastavitev stolpca", | ||||
|         "Reset {{count}} columns_one": "Ponastavi stolpec", | ||||
|         "Freeze {{count}} columns_one": "Zamrzni stolpec", | ||||
|         "More sort options ...": "Več možnosti razvrščanja…", | ||||
|         "Freeze {{count}} more columns_one": "Zamrznite še en stolpec", | ||||
| @ -200,10 +200,10 @@ | ||||
|         "Freeze {{count}} more columns_other": "Zamrznite še {{count}} stolpcev", | ||||
|         "Hide {{count}} columns_one": "Skrij stolpec", | ||||
|         "Sorted (#{{count}})_other": "Razvrščeno (#{{count}})", | ||||
|         "Insert column to the {{to}}": "Vstavi stolpec v {{to}}", | ||||
|         "Insert column to the {{to}}": "Vstavi stolpec na {{to}}", | ||||
|         "Reset {{count}} entire columns_other": "Ponastavi {{count}} stolpcev", | ||||
|         "Unfreeze {{count}} columns_other": "Odmrznite {{count}} stolpcev", | ||||
|         "Insert column to the right": "Vstavi stolpec na desno", | ||||
|         "Insert column to the right": "Vstavi stolpec na desno stran", | ||||
|         "Reset {{count}} entire columns_one": "Ponastavi celoten stolpec", | ||||
|         "Insert column to the left": "Vstavi stolpec na levo", | ||||
|         "Shortcuts": "Bližnjice", | ||||
| @ -270,7 +270,7 @@ | ||||
|         "Access Rules": "Pravila dostopa", | ||||
|         "Code View": "Pogled kode", | ||||
|         "Raw Data": "Neobdelani podatki", | ||||
|         "Document History": "Zgodovina dokumentov", | ||||
|         "Document History": "Zgodovina Dokumentov", | ||||
|         "Validate Data": "Potrdi podatke", | ||||
|         "How-to Tutorial": "Vadnica kako narediti", | ||||
|         "Tour of this Document": "Ogled tega dokumenta", | ||||
| @ -278,7 +278,7 @@ | ||||
|     }, | ||||
|     "pages": { | ||||
|         "Rename": "Preimenuj", | ||||
|         "Duplicate Page": "Podvojena stran", | ||||
|         "Duplicate Page": "Podvoji stran", | ||||
|         "You do not have edit access to this document": "Nimate dovoljenja za urejanje tega dokumenta", | ||||
|         "Remove": "Odstrani" | ||||
|     }, | ||||
| @ -293,7 +293,7 @@ | ||||
|         "Add New": "Dodaj" | ||||
|     }, | ||||
|     "DataTables": { | ||||
|         "Delete {{formattedTableName}} data, and remove it from all pages?": "Izbrišite podatke {{formattedTableName}} in jih odstranite z vseh strani?", | ||||
|         "Delete {{formattedTableName}} data, and remove it from all pages?": "Izbriši podatke {{formattedTableName}} in jih odstrani z vseh strani?", | ||||
|         "Click to copy": "Kliknite za kopiranje", | ||||
|         "Duplicate Table": "Podvojena tabela", | ||||
|         "Table ID copied to clipboard": "ID tabele kopiran v odložišče", | ||||
| @ -305,8 +305,8 @@ | ||||
|         "Delete widget": "Izbriši gradnik", | ||||
|         "Advanced Sort & Filter": "Napredno razvrščanje in filtriranje", | ||||
|         "Data selection": "Izbira podatkov", | ||||
|         "Download as XLSX": "Prenesite kot XLSX", | ||||
|         "Download as CSV": "Prenesite kot CSV", | ||||
|         "Download as XLSX": "Prenesi kot XLSX", | ||||
|         "Download as CSV": "Prenesi kot CSV", | ||||
|         "Widget options": "Možnosti gradnika", | ||||
|         "Print widget": "Gradnik za tiskanje", | ||||
|         "Open configuration": "Odpri konfiguracijo", | ||||
| @ -423,13 +423,13 @@ | ||||
|         "Formula Columns_other": "Stolpci formule", | ||||
|         "Formula Columns_one": "Stolpec formule", | ||||
|         "Enter formula": "Vnesite formulo", | ||||
|         "Clear and make into formula": "Brišite in pretvorite v formulo", | ||||
|         "Clear and make into formula": "Briši in pretvori v formulo", | ||||
|         "Mixed Behavior": "Mešano vedenje", | ||||
|         "Convert to trigger formula": "Pretvori v sprožitveno formulo", | ||||
|         "Data Columns_one": "Stolpec podatkov", | ||||
|         "TRIGGER FORMULA": "SPROŽILNA FORMULA", | ||||
|         "Set trigger formula": "Nastavite sprožitveno formulo", | ||||
|         "Make into data column": "Spremenite v podatkovni stolpec", | ||||
|         "Set trigger formula": "Nastavi sprožitveno formulo", | ||||
|         "Make into data column": "Spremeni v podatkovni stolpec", | ||||
|         "COLUMN BEHAVIOR": "OBNAŠANJE STOLPCA" | ||||
|     }, | ||||
|     "DuplicateTable": { | ||||
| @ -440,7 +440,7 @@ | ||||
|     }, | ||||
|     "DocPageModel": { | ||||
|         "Sorry, access to this document has been denied. [{{error}}]": "Žal je bil dostop do tega dokumenta zavrnjen. [{{error}}]", | ||||
|         "Add Empty Table": "Dodajte prazno tabelo", | ||||
|         "Add Empty Table": "Dodaj prazno tabelo", | ||||
|         "You do not have edit access to this document": "Nimate dostopa za urejanje tega dokumenta", | ||||
|         "Add Widget to Page": "Dodaj widget na stran", | ||||
|         "Add Page": "Dodaj stran", | ||||
| @ -552,7 +552,7 @@ | ||||
|         "SOURCE DATA": "IZVORNI PODATKI", | ||||
|         "CHART TYPE": "VRSTA DIAGRAMA", | ||||
|         "Detach": "Odklopi", | ||||
|         "Change Widget": "Spremite widget", | ||||
|         "Change Widget": "Spremeni  Pripomoček", | ||||
|         "Columns_one": "Stolpec", | ||||
|         "Series_other": "Serija", | ||||
|         "Fields_other": "Polja", | ||||
| @ -661,8 +661,8 @@ | ||||
|         "Apply conditional formatting to cells in this column when formula conditions are met.": "Uporabi pogojno oblikovanje za celice v tem stolpcu, ko so izpolnjeni pogoji formule.", | ||||
|         "To make an anchor link that takes the user to a specific cell, click on a row and press {{shortcut}}.": "Če želite narediti sidrno povezavo, ki uporabnika pripelje do določene celice, kliknite vrstico in pritisnite {{shortcut}}.", | ||||
|         "Unpin to hide the the button while keeping the filter.": "Odpnite, da skrijete gumb in obdržite filter.", | ||||
|         "Apply conditional formatting to rows based on formulas.": "Uporabite pogojno oblikovanje za vrstice na podlagi formul.", | ||||
|         "Click on “Open row styles” to apply conditional formatting to rows.": "Kliknite »Odpri sloge vrstic«, da za vrstice uporabite pogojno oblikovanje.", | ||||
|         "Apply conditional formatting to rows based on formulas.": "Uporabi pogojno oblikovanje za vrstice na podlagi formul.", | ||||
|         "Click on “Open row styles” to apply conditional formatting to rows.": "Klikni »Odpri sloge vrstic«, da za vrstice uporabiš pogojno oblikovanje.", | ||||
|         "Pinned filters are displayed as buttons above the widget.": "Pripeti filtri so prikazani kot gumbi nad pripomočkom.", | ||||
|         "Link your new widget to an existing widget on this page.": "Povežite svoj novi pripomoček z obstoječim pripomočkom na tej strani.", | ||||
|         "Use the \\u{1D6BA} icon to create summary (or pivot) tables, for totals or subtotals.": "Uporabite ikono \\u{1D6BA} za ustvarjanje povzetkov (ali vrtilnih) tabel za vsote ali delne vsote.", | ||||
| @ -688,7 +688,7 @@ | ||||
|         "User has view access to {{resource}} resulting from manually-set access to resources inside. If removed here, this user will lose access to resources inside.": "Uporabnik ima vpogled v {{resource}}, ki je posledica ročno nastavljenega dostopa do virov v njem. Če ga tukaj odstranite, bo ta uporabnik izgubil dostop do notranjih virov.", | ||||
|         "User may not modify their own access.": "Uporabnik ne more spreminjati lastnega dostopa.", | ||||
|         "member": "član", | ||||
|         "Add {{member}} to your team": "Dodajte {{member}} v svojo ekipo", | ||||
|         "Add {{member}} to your team": "Dodaj {{member}} v svojo ekipo", | ||||
|         "Collaborator": "Sodelavec", | ||||
|         "Link copied to clipboard": "Povezava kopirana v odložišče", | ||||
|         "team site": "spletno mesto ekipe", | ||||
| @ -758,7 +758,7 @@ | ||||
|     }, | ||||
|     "ColumnTitle": { | ||||
|         "Column ID copied to clipboard": "ID stolpca kopiran v odložišče", | ||||
|         "Add description": "Dodajte opis", | ||||
|         "Add description": "Dodaj opis", | ||||
|         "Column description": "Opis stolpca", | ||||
|         "Provide a column label": "Navedite oznako stolpca", | ||||
|         "Close": "Zapri", | ||||
| @ -870,7 +870,7 @@ | ||||
|     }, | ||||
|     "RecordLayoutEditor": { | ||||
|         "Show field {{- label}}": "Prikaži polje {{- label}}", | ||||
|         "Add Field": "Dodajte polje", | ||||
|         "Add Field": "Dodaj polje", | ||||
|         "Save Layout": "Shrani postavitev", | ||||
|         "Cancel": "Prekliči", | ||||
|         "Create New Field": "Ustvari novo polje" | ||||
| @ -926,7 +926,7 @@ | ||||
|         "Switch appearance automatically to match system": "Samodejno preklopite videz, da se ujema s sistemom" | ||||
|     }, | ||||
|     "SiteSwitcher": { | ||||
|         "Switch Sites": "Preklopite mesta", | ||||
|         "Switch Sites": "Preklopi mesta", | ||||
|         "Create new team site": "Ustvarite novo spletno mesto ekipe" | ||||
|     }, | ||||
|     "WebhookPage": { | ||||
| @ -1016,7 +1016,7 @@ | ||||
|         "Reference List": "Referenčni seznam", | ||||
|         "* Workspaces are available on team plans. ": "* Delovni prostori so na voljo v skupinskih načrtih. ", | ||||
|         "Upgrade now": "Nadgradi zdaj", | ||||
|         "Toggle": "Preklopi", | ||||
|         "Toggle": "Preklop", | ||||
|         "Choice List": "Izbirni seznam", | ||||
|         "Any": "Katerikoli", | ||||
|         "DateTime": "Datum čas", | ||||
| @ -1170,8 +1170,8 @@ | ||||
|     "ConditionalStyle": { | ||||
|         "Rule must return True or False": "Pravilo mora vrniti True ali False", | ||||
|         "Row Style": "Slog vrstice", | ||||
|         "Add another rule": "Dodajte še eno pravilo", | ||||
|         "Add conditional style": "Dodajte pogojni slog", | ||||
|         "Add another rule": "Dodaj dodatno pravilo", | ||||
|         "Add conditional style": "Dodaj pogojni slog", | ||||
|         "Error in style rule": "Napaka v slogovnem pravilu" | ||||
|     }, | ||||
|     "EditorTooltip": { | ||||
| @ -1219,7 +1219,7 @@ | ||||
|     }, | ||||
|     "duplicatePage": { | ||||
|         "Note that this does not copy data, but creates another view of the same data.": "Upoštevajte, da s tem ne kopirate podatkov, ampak ustvarite drug pogled istih podatkov.", | ||||
|         "Duplicate page {{pageName}}": "Podvojena stran {{pageName}}" | ||||
|         "Duplicate page {{pageName}}": "Podvoji stran {{pageName}}" | ||||
|     }, | ||||
|     "CurrencyPicker": { | ||||
|         "Invalid currency": "Neveljavna valuta" | ||||
|  | ||||
| @ -151,7 +151,27 @@ | ||||
|         "Unfreeze {{count}} columns_one": "Відкріпити цей стовпець", | ||||
|         "Unfreeze {{count}} columns_other": "Відкріпити {{count}} стовпців", | ||||
|         "Insert column to the right": "Вставити стовпець праворуч", | ||||
|         "Insert column to the left": "Вставити стовпець ліворуч" | ||||
|         "Insert column to the left": "Вставити стовпець ліворуч", | ||||
|         "Detect Duplicates in...": "Виявлення дублікатів у...", | ||||
|         "UUID": "UUID", | ||||
|         "Shortcuts": "Ярлики", | ||||
|         "Show hidden columns": "Показати приховані стовпці", | ||||
|         "Created At": "Дата створення", | ||||
|         "Authorship": "Авторство", | ||||
|         "Last Updated By": "Автор останньої зміни", | ||||
|         "Hidden Columns": "Приховані стовпці", | ||||
|         "Lookups": "Lookups", | ||||
|         "No reference columns.": "Немає довідкових стовпців.", | ||||
|         "Apply on record changes": "Застосовувати при зміні записів", | ||||
|         "Duplicate in {{- label}}": "Дублікат у {{- label}}\"", | ||||
|         "Created By": "Автор створення", | ||||
|         "Last Updated At": "Дата останньої зміни", | ||||
|         "Apply to new records": "Застосувати до нових записів", | ||||
|         "Search columns": "Шукати стовпці", | ||||
|         "Timestamp": "Часова мітка", | ||||
|         "no reference column": "немає довідкових стовпців", | ||||
|         "Adding UUID column": "Adding UUID column", | ||||
|         "Adding duplicates column": "Adding duplicates column" | ||||
|     }, | ||||
|     "ThemeConfig": { | ||||
|         "Switch appearance automatically to match system": "Автоматично змінювати оформлення відповідно до системи", | ||||
| @ -820,7 +840,8 @@ | ||||
|         "Reference": "Посилання", | ||||
|         "DateTime": "Дата і час", | ||||
|         "Reference List": "Список посилань", | ||||
|         "Attachment": "Вкладення" | ||||
|         "Attachment": "Вкладення", | ||||
|         "Search columns": "Шукати стовпці" | ||||
|     }, | ||||
|     "modals": { | ||||
|         "Cancel": "Відмінити", | ||||
| @ -913,14 +934,15 @@ | ||||
|     }, | ||||
|     "FieldBuilder": { | ||||
|         "CELL FORMAT": "ФОРМАТ КЛІТИНКИ", | ||||
|         "Changing multiple column types": "Зміна кількох типів стовпців", | ||||
|         "Changing multiple column types": "Changing multiple column types", | ||||
|         "DATA FROM TABLE": "ДАНІ З ТАБЛИЦІ", | ||||
|         "Mixed format": "Змішаний формат", | ||||
|         "Mixed types": "Змішані типи", | ||||
|         "Use separate field settings for {{colId}}": "Використати окремі налаштування поля для {{colId}}", | ||||
|         "Apply Formula to Data": "Застосувати формулу до даних", | ||||
|         "Revert field settings for {{colId}} to common": "Змінити налаштування поля для {{colId}} на загальні", | ||||
|         "Save field settings for {{colId}} as common": "Зберегти налаштування поля для {{colId}} як загальні" | ||||
|         "Save field settings for {{colId}} as common": "Зберегти налаштування поля для {{colId}} як загальні", | ||||
|         "Changing column type": "Changing column type" | ||||
|     }, | ||||
|     "FieldEditor": { | ||||
|         "Unable to finish saving edited cell": "Неможливо зберегти відредаговану клітинку", | ||||
| @ -931,7 +953,11 @@ | ||||
|         "Error in the cell": "Помилка в клітинці", | ||||
|         "Errors in all {{numErrors}} cells": "Помилки в усіх клітинках {{numErrors}}", | ||||
|         "editingFormula is required": "editingFormula обов'язкове", | ||||
|         "Errors in {{numErrors}} of {{numCells}} cells": "Помилки в {{numErrors}} в {{numCells}} клітинках" | ||||
|         "Errors in {{numErrors}} of {{numCells}} cells": "Помилки в {{numErrors}} в {{numCells}} клітинках", | ||||
|         "Enter formula or {{button}}.": "Введіть формулу або {{button}}.", | ||||
|         "Enter formula.": "Введіть формулу.", | ||||
|         "Expand Editor": "Розгорнути редактор", | ||||
|         "use AI Assistant": "Використати AI Помічника" | ||||
|     }, | ||||
|     "HyperLinkEditor": { | ||||
|         "[link label] url": "[мітка посилання] URL" | ||||
| @ -1017,9 +1043,14 @@ | ||||
|         "Useful for storing the timestamp or author of a new record, data cleaning, and more.": "Корисно для збереження позначки часу або автора нового запису, очищення даних тощо.", | ||||
|         "You can filter by more than one column.": "Ви можете фільтрувати за кількома стовпцями.", | ||||
|         "Try out changes in a copy, then decide whether to replace the original with your edits.": "Спробуйте змінити копію, а потім вирішіть, чи слід замінювати оригінал своїми правками.", | ||||
|         "Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Правила доступу дають вам можливість створювати детальні правила, щоб визначити, хто може бачити або редагувати (та які) частини вашого документа." | ||||
|         "Access rules give you the power to create nuanced rules to determine who can see or edit which parts of your document.": "Правила доступу дають вам можливість створювати детальні правила, щоб визначити, хто може бачити або редагувати (та які) частини вашого документа.", | ||||
|         "To make an anchor link that takes the user to a specific cell, click on a row and press {{shortcut}}.": "Щоб створити якірне посилання, яке перенаправляє користувача до певної комірки, клацніть на рядку та натисніть {{shortcut}}.", | ||||
|         "Anchor Links": "Якірні посилання" | ||||
|     }, | ||||
|     "DescriptionConfig": { | ||||
|         "DESCRIPTION": "ОПИС" | ||||
|     }, | ||||
|     "FieldContextMenu": { | ||||
|         "Copy anchor link": "Скопіювати якірне посилання" | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2700,6 +2700,43 @@ function testDocApi() { | ||||
|     assert.equal(resp2.data, 'A,B\nSanta,1\nBob,11\nAlice,2\nFelix,22\n'); | ||||
|   }); | ||||
| 
 | ||||
|   it("GET /docs/{did}/download/table-schema serves table-schema-encoded document with header=colId", async function () { | ||||
|     const { docUrl, tableUrl } = await generateDocAndUrl('tableSchemaWithColIdAsHeader'); | ||||
|     const columns = [ | ||||
|       { | ||||
|         id: 'Some_ID', | ||||
|         fields: { | ||||
|           label: 'Some Label', | ||||
|           type: 'Text', | ||||
|         } | ||||
|       }, | ||||
|     ]; | ||||
|     const setupColResp = await axios.put(`${tableUrl}/columns`, { columns }, {...chimpy, params: { replaceall: true }}); | ||||
|     assert.equal(setupColResp.status, 200); | ||||
| 
 | ||||
|     const resp = await axios.get(`${docUrl}/download/table-schema?tableId=Table1&header=colId`, chimpy); | ||||
|     assert.equal(resp.status, 200); | ||||
|     const expected = { | ||||
|       format: "csv", | ||||
|       mediatype: "text/csv", | ||||
|       encoding: "utf-8", | ||||
|       dialect: { | ||||
|         delimiter: ",", | ||||
|         doubleQuote: true, | ||||
|       }, | ||||
|       name: 'table1', | ||||
|       title: 'Table1', | ||||
|       schema: { | ||||
|         fields: [{ | ||||
|           name: 'Some_ID', | ||||
|           type: 'string', | ||||
|           format: 'default', | ||||
|         }] | ||||
|       } | ||||
|     }; | ||||
|     assert.deepInclude(resp.data, expected); | ||||
|   }); | ||||
| 
 | ||||
|   it("GET /docs/{did}/download/table-schema respects permissions", async function () { | ||||
|     // kiwi has no access to TestDoc
 | ||||
|     const resp = await axios.get(`${serverUrl}/api/docs/${docIds.TestDoc}/download/table-schema?tableId=Table1`, kiwi); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user