diff --git a/bun.lock b/bun.lock index 8a28be835..b5ebfac76 100644 --- a/bun.lock +++ b/bun.lock @@ -6,7 +6,7 @@ "name": "@appwrite/console", "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@95675c4", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@bb72008", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@c1feb89", "@appwrite.io/pink-legacy": "^1.0.3", @@ -107,7 +107,7 @@ "@analytics/type-utils": ["@analytics/type-utils@0.6.4", "", {}, "sha512-Ou1gQxFakOWLcPnbFVsrPb8g1wLLUZYYJXDPjHkG07+5mustGs5yqACx42UAu4A6NszNN6Z5gGxhyH45zPWRxw=="], - "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@95675c4", { "dependencies": { "bignumber.js": "9.0.0", "json-bigint": "1.0.0" } }], + "@appwrite.io/console": ["@appwrite.io/console@https://pkg.vc/-/@appwrite/@appwrite.io/console@bb72008", { "dependencies": { "bignumber.js": "9.0.0", "json-bigint": "1.0.0" } }], "@appwrite.io/pink-icons": ["@appwrite.io/pink-icons@0.25.0", "", {}, "sha512-0O3i2oEuh5mWvjO80i+X6rbzrWLJ1m5wmv2/M3a1p2PyBJsFxN8xQMTEmTn3Wl/D26SsM7SpzbdW6gmfgoVU9Q=="], diff --git a/package.json b/package.json index 604624d1d..fb534d399 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@ai-sdk/svelte": "^1.1.24", - "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@95675c4", + "@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@bb72008", "@appwrite.io/pink-icons": "0.25.0", "@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@c1feb89", "@appwrite.io/pink-legacy": "^1.0.3", diff --git a/src/lib/components/filters/store.ts b/src/lib/components/filters/store.ts index fde630607..734f5e581 100644 --- a/src/lib/components/filters/store.ts +++ b/src/lib/components/filters/store.ts @@ -156,6 +156,10 @@ export enum ValidOperators { export enum ValidTypes { String = 'string', + Varchar = 'varchar', + Text = 'text', + Mediumtext = 'mediumtext', + Longtext = 'longtext', Integer = 'integer', Double = 'double', Boolean = 'boolean', @@ -175,8 +179,32 @@ const operatorsDefault = new Map< hideInput?: boolean; } >([ - [ValidOperators.StartsWith, { query: Query.startsWith, types: [ValidTypes.String] }], - [ValidOperators.EndsWith, { query: Query.endsWith, types: [ValidTypes.String] }], + [ + ValidOperators.StartsWith, + { + query: Query.startsWith, + types: [ + ValidTypes.String, + ValidTypes.Varchar, + ValidTypes.Text, + ValidTypes.Mediumtext, + ValidTypes.Longtext + ] + } + ], + [ + ValidOperators.EndsWith, + { + query: Query.endsWith, + types: [ + ValidTypes.String, + ValidTypes.Varchar, + ValidTypes.Text, + ValidTypes.Mediumtext, + ValidTypes.Longtext + ] + } + ], [ ValidOperators.GreaterThan, { @@ -211,6 +239,10 @@ const operatorsDefault = new Map< query: Query.equal, types: [ ValidTypes.String, + ValidTypes.Varchar, + ValidTypes.Text, + ValidTypes.Mediumtext, + ValidTypes.Longtext, ValidTypes.Integer, ValidTypes.Double, ValidTypes.Boolean, @@ -227,6 +259,10 @@ const operatorsDefault = new Map< query: Query.notEqual, types: [ ValidTypes.String, + ValidTypes.Varchar, + ValidTypes.Text, + ValidTypes.Mediumtext, + ValidTypes.Longtext, ValidTypes.Integer, ValidTypes.Double, ValidTypes.Boolean, @@ -242,6 +278,10 @@ const operatorsDefault = new Map< query: Query.isNotNull, types: [ ValidTypes.String, + ValidTypes.Varchar, + ValidTypes.Text, + ValidTypes.Mediumtext, + ValidTypes.Longtext, ValidTypes.Integer, ValidTypes.Double, ValidTypes.Boolean, @@ -260,6 +300,10 @@ const operatorsDefault = new Map< query: Query.isNull, types: [ ValidTypes.String, + ValidTypes.Varchar, + ValidTypes.Text, + ValidTypes.Mediumtext, + ValidTypes.Longtext, ValidTypes.Integer, ValidTypes.Double, ValidTypes.Boolean, @@ -278,6 +322,10 @@ const operatorsDefault = new Map< query: Query.contains, types: [ ValidTypes.String, + ValidTypes.Varchar, + ValidTypes.Text, + ValidTypes.Mediumtext, + ValidTypes.Longtext, ValidTypes.Integer, ValidTypes.Double, ValidTypes.Boolean, diff --git a/src/lib/helpers/faker.ts b/src/lib/helpers/faker.ts index c7ce16e9d..7abd56c62 100644 --- a/src/lib/helpers/faker.ts +++ b/src/lib/helpers/faker.ts @@ -183,7 +183,8 @@ function generateValueForField( function generateSingleValue(field: Field): string | number | boolean | NestedNumberArray | null { switch (field.type) { - case 'string': { + case 'string': + case 'varchar': { if ('format' in field && field.format) { switch (field.format) { case 'email': { @@ -214,6 +215,21 @@ function generateSingleValue(field: Field): string | number | boolean | NestedNu } } + case 'text': { + // TEXT type max size is 16,383 characters (utf8mb4) + return generateStringValue(field.key, 1000); + } + + case 'mediumtext': { + // MEDIUMTEXT type max size is 4,194,303 characters (utf8mb4) + return generateStringValue(field.key, 1000); + } + + case 'longtext': { + // LONGTEXT type max size is 1,073,741,823 characters (utf8mb4) + return generateStringValue(field.key, 1000); + } + case 'integer': { const intAttr = field as Models.ColumnInteger; const minCompat = coerceToNumber(intAttr.min); diff --git a/src/lib/helpers/types.ts b/src/lib/helpers/types.ts index df6fba0d9..3c3218a40 100644 --- a/src/lib/helpers/types.ts +++ b/src/lib/helpers/types.ts @@ -30,6 +30,10 @@ export type Prettify = T & {}; const columnTypes = [ 'string', + 'varchar', + 'text', + 'mediumtext', + 'longtext', 'integer', 'double', 'boolean', diff --git a/src/lib/stores/migration.ts b/src/lib/stores/migration.ts index 2164ab2a1..534cddc6a 100644 --- a/src/lib/stores/migration.ts +++ b/src/lib/stores/migration.ts @@ -1,5 +1,5 @@ import { writable } from 'svelte/store'; - +import { Resources } from '@appwrite.io/console'; import { includesAll } from '$lib/helpers/array'; const initialFormData = { @@ -51,66 +51,66 @@ export const ResourcesFriendly = { row: { singular: 'Row', plural: 'Rows' } }; -const resources = Object.keys(ResourcesFriendly); - -type Resource = (typeof resources)[number]; - // @todo: @itznotabug - check if other resources are correct and work fine! -export const providerResources: Record = { - appwrite: [...resources], // new terminology, others are ok? +export const providerResources: Record = { + appwrite: Object.values(Resources), supabase: [ - 'user', - 'database', - 'collection', - 'attribute', - 'index', - 'document', - 'bucket', - 'file' + Resources.User, + Resources.Database, + Resources.Collection, + Resources.Attribute, + Resources.Index, + Resources.Document, + Resources.Bucket, + Resources.File ], - nhost: ['user', 'database', 'collection', 'attribute', 'index', 'document', 'bucket', 'file'], - firebase: ['user', 'database', 'collection', 'attribute', 'document', 'bucket', 'file'] + nhost: [ + Resources.User, + Resources.Database, + Resources.Collection, + Resources.Attribute, + Resources.Index, + Resources.Document, + Resources.Bucket, + Resources.File + ], + firebase: [ + Resources.User, + Resources.Database, + Resources.Collection, + Resources.Attribute, + Resources.Document, + Resources.Bucket, + Resources.File + ] }; export const migrationFormToResources = ( formData: MigrationFormData, provider: Provider -): Resource[] => { - const resources: Resource[] = []; - const addResource = (resource: Resource) => { +): Resources[] => { + const resources: Resources[] = []; + const addResource = (resource: Resources) => { if (providerResources[provider].includes(resource)) { resources.push(resource); } }; if (formData.users.root) { - addResource('user'); - } - if (formData.users.teams) { - addResource('team'); - addResource('membership'); + addResource(Resources.User); } if (formData.databases.root) { - addResource('database'); - addResource('table'); - addResource('column'); - addResource('columnIndex'); + addResource(Resources.Database); + addResource(Resources.Table); + addResource(Resources.Column); + addResource(Resources.Index); } if (formData.databases.rows) { - addResource('row'); - } - if (formData.functions.root) { - addResource('function'); - } - if (formData.functions.env) { - addResource('environment-variable'); - } - if (formData.functions.inactive) { - addResource('deployment'); + addResource(Resources.Row); } if (formData.storage.root) { - addResource('bucket'); - addResource('file'); + addResource(Resources.Bucket); + addResource(Resources.File); } return resources; @@ -137,33 +137,18 @@ export const isVersionAtLeast = (version: string, atLeast: string) => { return compareVersions(version, atLeast) >= 0; }; -export const resourcesToMigrationForm = ( - resources: Resource[], - version = '0.0.0' -): MigrationFormData => { +export const resourcesToMigrationForm = (resources: Resources[]): MigrationFormData => { const formData = { ...initialFormData }; - if (resources.includes('user')) { + if (resources.includes(Resources.User)) { formData.users.root = true; } - if (includesAll(resources, ['team', 'membership'])) { - formData.users.teams = true; - } - if (resources.includes('database')) { + if (resources.includes(Resources.Database)) { formData.databases.root = true; } - if (includesAll(resources, ['table', 'column', 'row'])) { + if (includesAll(resources, [Resources.Table, Resources.Column, Resources.Row] as Resources[])) { formData.databases.rows = true; } - if (resources.includes('function') && isVersionAtLeast(version, '1.4.0')) { - formData.functions.root = true; - } - if (resources.includes('environment-variable') && isVersionAtLeast(version, '1.4.0')) { - formData.functions.env = true; - } - if (resources.includes('deployment') && isVersionAtLeast(version, '1.4.0')) { - formData.functions.inactive = true; - } - if (includesAll(resources, ['bucket', 'file'])) { + if (includesAll(resources, [Resources.Bucket, Resources.File] as Resources[])) { formData.storage.root = true; } diff --git a/src/routes/(console)/(migration-wizard)/resource-form.svelte b/src/routes/(console)/(migration-wizard)/resource-form.svelte index 628c6c2a3..54e3f23ba 100644 --- a/src/routes/(console)/(migration-wizard)/resource-form.svelte +++ b/src/routes/(console)/(migration-wizard)/resource-form.svelte @@ -5,14 +5,13 @@ import { createMigrationFormStore, createMigrationProviderStore, - isVersionAtLeast, type MigrationFormData, providerResources, resourcesToMigrationForm } from '$lib/stores/migration'; import { Button } from '$lib/elements/forms'; import { wizard } from '$lib/stores/wizard'; - import type { Models } from '@appwrite.io/console'; + import { Resources, type Models } from '@appwrite.io/console'; import type { sdk } from '$lib/stores/sdk'; import ImportReport from '$routes/(console)/project-[region]-[project]/settings/migrations/(import)/importReport.svelte'; @@ -33,11 +32,9 @@ } function selectAll() { - $formData = resourcesToMigrationForm(resources, version); + $formData = resourcesToMigrationForm(resources); } - $: version = report?.version || '0.0.0'; - let error = false; let isOpen = false; let report: Models.MigrationReport; @@ -98,14 +95,21 @@ const shouldRenderGroup = (groupKey: string): boolean => { if (groupKey === 'functions') { - return resources.includes('function') && isVersionAtLeast(version, '1.4.0'); + // Functions not in SDK Resources enum, skip + return false; } if (groupKey === 'storage') { - return resources.includes('bucket') && resources.includes('file'); + return resources.includes(Resources.Bucket) && resources.includes(Resources.File); } - return resources.includes(groupKey.slice(0, -1)); + // Map groupKey to Resources enum + const groupToResource: Record = { + users: Resources.User, + databases: Resources.Database + }; + const resource = groupToResource[groupKey]; + return resource ? resources.includes(resource) : false; }; // no typecasting in svelte context! @@ -125,14 +129,6 @@ - {#if report && !isVersionAtLeast(version, '1.4.0') && $provider.provider === 'appwrite'} - - Functions not available for import - To migrate your functions, update the version of the Appwrite instance you're importing from - to a version newer than 1.4 - - {/if} - {#if error} {#if migrationType === 'provider'} diff --git a/src/routes/(console)/project-[region]-[project]/databases/create.svelte b/src/routes/(console)/project-[region]-[project]/databases/create.svelte index a48ef0d1f..c1b6fbb91 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/create.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/create.svelte @@ -4,7 +4,7 @@ import { Button, InputText } from '$lib/elements/forms'; import { addNotification } from '$lib/stores/notifications'; import { sdk } from '$lib/stores/sdk'; - import { ID, type Models } from '@appwrite.io/console'; + import { BackupServices, ID, type Models } from '@appwrite.io/console'; import { createEventDispatcher } from 'svelte'; import { isCloud } from '$lib/system'; import { currentPlan } from '$lib/stores/organization'; @@ -65,7 +65,7 @@ return sdk.forProject(page.params.region, page.params.project).backups.createPolicy({ policyId: ID.unique(), - services: ['databases'], + services: [BackupServices.Databases], retention: policy.retained, schedule: policy.schedule, name: policy.label, diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte index bd8d8984a..7b009ccbc 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(entity)/views/indexes/create.svelte @@ -1,10 +1,11 @@ @@ -22,9 +23,7 @@ import { isSmallViewport } from '$lib/stores/viewport'; import { type Entity, getTerminologies } from '$database/(entity)'; import { resolveRoute, withPath } from '$lib/stores/navigation'; - import { IndexType } from '@appwrite.io/console'; import { columnOptions as baseColumnOptions } from '$database/table-[table]/columns/store'; - import { IndexOrder } from '$database/(suggestions)'; let { entity, @@ -63,7 +62,7 @@ let fieldList: Array<{ value: string; - order: IndexOrder | null; + order: OrderBy | null; length: number | null; }> = $state([{ value: '', order: null, length: null }]); @@ -78,13 +77,13 @@ let orderOptions = $derived.by(() => selectedType === IndexType.Spatial ? [ - { value: 'ASC', label: 'ASC' }, - { value: 'DESC', label: 'DESC' }, + { value: OrderBy.Asc, label: 'ASC' }, + { value: OrderBy.Desc, label: 'DESC' }, { value: null, label: 'NONE' } ] : [ - { value: 'ASC', label: 'ASC' }, - { value: 'DESC', label: 'DESC' } + { value: OrderBy.Asc, label: 'ASC' }, + { value: OrderBy.Desc, label: 'DESC' } ] ); @@ -111,7 +110,7 @@ function initialize() { const field = entity.fields.filter((field) => externalFieldKey === field.key); const isSpatial = field.length && isSpatialType(field[0]); - const order = isSpatial ? null : IndexOrder.ASC; + const order = isSpatial ? null : OrderBy.Asc; selectedType = isSpatial ? IndexType.Spatial : IndexType.Key; @@ -165,8 +164,7 @@ try { const orders = fieldList .map((field) => field.order) - .filter((order: IndexOrder) => order !== null) - .map((order) => String(order)); + .filter((order): order is OrderBy => order !== null); await onCreateIndex({ key, diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte index b7b90e70c..7355bf9df 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/empty.svelte @@ -1504,7 +1504,7 @@ id="type" required label="Type" - value={selectedOption?.name || 'String'} + value={selectedOption?.name || 'Text'} on:change={(e) => { const newOption = columnOptions.find( (opt) => opt.name === e.detail diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte index 836ea3b9c..b37783c1b 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/indexes.svelte @@ -2,16 +2,11 @@ import { Alert, Accordion, Icon, Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte'; import { IconPlus, IconX } from '@appwrite.io/pink-icons-svelte'; import { Button, InputSelect /*InputNumber*/ } from '$lib/elements/forms'; - import { - showIndexesSuggestions, - IndexOrder, - mockSuggestions, - type SuggestedIndexSchema - } from './store'; + import { showIndexesSuggestions, mockSuggestions, type SuggestedIndexSchema } from './store'; import { Modal } from '$lib/components'; import { type Entity, SideSheet } from '$database/(entity)'; import { isSmallViewport } from '$lib/stores/viewport'; - import { IndexType } from '@appwrite.io/console'; + import { IndexType, OrderBy } from '@appwrite.io/console'; import { capitalize } from '$lib/helpers/string'; import { type Columns } from '../table-[table]/store'; import { isRelationship } from '../table-[table]/rows/store'; @@ -74,7 +69,7 @@ key: column.name, type: IndexType.Key, fields: [column.name], - orders: index === 2 ? IndexOrder.DESC : IndexOrder.ASC, + orders: index === 2 ? OrderBy.Desc : OrderBy.Asc, lengths: [] })); } else { @@ -90,7 +85,7 @@ return { key: index.columns[0], type: index.type as IndexType, - orders: (index.orders?.[0] as IndexOrder) || IndexOrder.ASC, + orders: (index.orders?.[0] as OrderBy) || OrderBy.Asc, fields: index.columns, lengths: index.lengths ?? [] }; @@ -118,7 +113,7 @@ indexes.push({ key: '', type: IndexType.Key, - orders: IndexOrder.ASC, + orders: OrderBy.Asc, fields: [], lengths: null }); @@ -139,11 +134,11 @@ } function getOrderOptions(selectedType: IndexType) { - const base = [IndexOrder.ASC, IndexOrder.DESC]; - const values = selectedType === IndexType.Spatial ? [...base, IndexOrder.NONE] : base; + const base = [OrderBy.Asc, OrderBy.Desc]; + const values = selectedType === IndexType.Spatial ? [...base, null] : base; return values.map((order) => ({ - label: capitalize(String(order)), + label: order ? capitalize(String(order)) : 'None', value: order })); } @@ -165,7 +160,8 @@ function prepareIndexForCreation(index: SuggestedIndexSchema, columnMap: Map) { // prepare orders array - const orders = index.orders !== null ? index.fields.map(() => String(index.orders)) : []; + const orders: OrderBy[] = + index.orders !== null ? index.fields.map(() => index.orders as OrderBy) : []; // prepare lengths array let lengths: (number | null)[]; @@ -222,7 +218,10 @@ const usedKeys = new Set(); const columnMap: Map = new Map( table.fields - .filter((field) => field.type === 'string' && 'size' in field) + .filter( + (field) => + (field.type === 'string' || field.type === 'varchar') && 'size' in field + ) .map((field) => [field.key, field['size']]) ); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts index 0e8daa036..3e67c90b3 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/(suggestions)/store.ts @@ -1,5 +1,5 @@ import { writable } from 'svelte/store'; -import { IndexType } from '@appwrite.io/console'; +import { IndexType, OrderBy } from '@appwrite.io/console'; import { columnOptions } from '../table-[table]/columns/store'; export type TableColumnSuggestions = { @@ -30,11 +30,7 @@ export type SuggestedColumnSchema = { isPlaceholder?: boolean; }; -export enum IndexOrder { - ASC = 'ASC', - DESC = 'DESC', - NONE = null -} +export type IndexOrder = OrderBy | null; export type SuggestedIndexSchema = { key: string; @@ -146,7 +142,7 @@ export function mapSuggestedColumns(columns: T[]): Sugges required: col.required ?? false, array: false, default: col.default ?? null, - size: col.type === 'string' ? (col.size ?? undefined) : undefined, + size: col.type === 'string' || col.type === 'varchar' ? (col.size ?? undefined) : undefined, min: col.type === 'integer' || col.type === 'double' ? (col.min ?? col.formatOptions?.min ?? undefined) diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte index 2374f5306..12cb11a54 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/+page.svelte @@ -17,7 +17,7 @@ import { onMount } from 'svelte'; import { feedback } from '$lib/stores/feedback'; import { cronExpression, type UserBackupPolicy } from '$lib/helpers/backups'; - import { ID } from '@appwrite.io/console'; + import { BackupServices, ID } from '@appwrite.io/console'; import { showCreateBackup, showCreatePolicy } from './store'; import { getProjectId } from '$lib/helpers/project'; import { Submit, trackError, trackEvent } from '$lib/actions/analytics'; @@ -68,7 +68,7 @@ const createManualBackup = async () => { try { await sdk.forProject(page.params.region, page.params.project).backups.createArchive({ - services: ['databases'], + services: [BackupServices.Databases], resourceId: data.database.$id }); await invalidate(Dependencies.BACKUPS); @@ -123,7 +123,7 @@ return sdk.forProject(page.params.region, page.params.project).backups.createPolicy({ policyId: ID.unique(), - services: ['databases'], + services: [BackupServices.Databases], retention: policy.retained, schedule: policy.schedule, name: policy.label, diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte index d1c29d712..c64a53e8e 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/backups/table.svelte @@ -15,7 +15,7 @@ import { addNotification } from '$lib/stores/notifications'; import { invalidate } from '$app/navigation'; import { calculateSize } from '$lib/helpers/sizeConvertion'; - import { ID, type Models } from '@appwrite.io/console'; + import { BackupServices, ID, type Models } from '@appwrite.io/console'; import { columns } from './store'; import { Click, Submit, trackError, trackEvent } from '$lib/actions/analytics'; import { copy } from '$lib/helpers/copy'; @@ -157,7 +157,7 @@ .forProject(page.params.region, page.params.project) .backups.createRestoration({ archiveId: selectedBackup.$id, - services: ['databases'], + services: [BackupServices.Databases], newResourceId: newDatabaseInfo.id ?? ID.unique(), newResourceName: newDatabaseInfo.name }); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte index 8bf9dee80..cd99973a9 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/+layout.svelte @@ -90,7 +90,7 @@ let createIndex: CreateIndex; let createColumn: CreateColumn; - let selectedOption: Option['name'] = 'String'; + let selectedOption: Option['name'] = 'Text'; let createMoreColumns = false; /* terminology */ diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte index a4649c505..e300431a3 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/+page.svelte @@ -191,7 +191,11 @@ function getMinMaxSizeForColumn( column: Columns ): { display: string; tooltip?: string } | undefined { - if (column.type === 'string' && !column['format'] && column.key !== '$id') { + if ( + (column.type === 'string' || column.type === 'varchar') && + !column['format'] && + column.key !== '$id' + ) { const stringColumn = column as Models.ColumnString; return { display: `Size: ${stringColumn.size}` }; } else if (column.type === 'integer' || column.type === 'double') { diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/longtext.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/longtext.svelte new file mode 100644 index 000000000..8087541af --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/longtext.svelte @@ -0,0 +1,99 @@ + + + + + + + Maximum size: 1,073,741,823 characters + + + + + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/mediumtext.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/mediumtext.svelte new file mode 100644 index 000000000..e87ef840f --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/mediumtext.svelte @@ -0,0 +1,99 @@ + + + + + + + Maximum size: 4,194,303 characters + + + + + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/store.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/store.ts index 0a29d12ef..0b94d185d 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/store.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/store.ts @@ -7,6 +7,10 @@ import Float, { submitFloat, updateFloat } from './float.svelte'; import Integer, { submitInteger, updateInteger } from './integer.svelte'; import Ip, { submitIp, updateIp } from './ip.svelte'; import String, { submitString, updateString } from './string.svelte'; +import Varchar, { submitVarchar, updateVarchar } from './varchar.svelte'; +import Text, { submitText, updateText } from './text.svelte'; +import Mediumtext, { submitMediumtext, updateMediumtext } from './mediumtext.svelte'; +import Longtext, { submitLongtext, updateLongtext } from './longtext.svelte'; import Url, { submitUrl, updateUrl } from './url.svelte'; import Datetime, { submitDatetime, updateDatetime } from './datetime.svelte'; import Point, { submitPoint, updatePoint } from './point.svelte'; @@ -32,7 +36,10 @@ import type { ComponentType } from 'svelte'; export type Option = { name: - | 'String' + | 'Text' + | 'Mediumtext' + | 'Longtext' + | 'Varchar' | 'Integer' | 'Float' | 'Boolean' @@ -44,11 +51,16 @@ export type Option = { | 'Relationship' | 'Point' | 'Line' - | 'Polygon'; + | 'Polygon' + | 'String (deprecated)'; sentenceName: string; component: Component; type: | 'string' + | 'text' + | 'mediumtext' + | 'longtext' + | 'varchar' | 'integer' | 'double' | 'boolean' @@ -75,12 +87,39 @@ export type Option = { export const columnOptions: Option[] = [ { - name: 'String', - sentenceName: 'string', - component: String, - type: 'string', - create: submitString, - update: updateString, + name: 'Text', + sentenceName: 'text', + component: Text, + type: 'text', + create: submitText, + update: updateText, + icon: IconText + }, + { + name: 'Mediumtext', + sentenceName: 'mediumtext', + component: Mediumtext, + type: 'mediumtext', + create: submitMediumtext, + update: updateMediumtext, + icon: IconText + }, + { + name: 'Longtext', + sentenceName: 'longtext', + component: Longtext, + type: 'longtext', + create: submitLongtext, + update: updateLongtext, + icon: IconText + }, + { + name: 'Varchar', + sentenceName: 'varchar', + component: Varchar, + type: 'varchar', + create: submitVarchar, + update: updateVarchar, icon: IconText }, { @@ -194,6 +233,15 @@ export const columnOptions: Option[] = [ create: submitRelationship, update: updateRelationship, icon: IconRelationship + }, + { + name: 'String (deprecated)', + sentenceName: 'string', + component: String, + type: 'string', + create: submitString, + update: updateString, + icon: IconText } ]; diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/text.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/text.svelte new file mode 100644 index 000000000..2f2a4443b --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/text.svelte @@ -0,0 +1,95 @@ + + + + + + + Maximum size: 16,383 characters + + + + + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/varchar.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/varchar.svelte new file mode 100644 index 000000000..f2f046a75 --- /dev/null +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/columns/varchar.svelte @@ -0,0 +1,172 @@ + + + + + + +{#if !editing} + + + + Row size usage + + + + + Database rows have a maximum size of 64 KB. varchar columns use 4 bytes per + character plus a small overhead. text, mediumtext, and longtext columns only use + ~20 bytes regardless of content length. + + + + + {#if exceedsLimit} + + This column exceeds the remaining row space. Consider using text, mediumtext, or + longtext instead. + + {/if} + +{/if} + += 50 ? InputTextarea : InputText} + id="default" + label="Default" + placeholder="Enter string" + maxlength={size} + bind:value={data.default} + disabled={data.required || data.array || disabled} + nullable={!data.required && !data.array} /> + + diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/createColumn.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/createColumn.svelte index 6de8d61ff..bddf43762 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/createColumn.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/createColumn.svelte @@ -23,7 +23,7 @@ columns = $bindable(null), columnId = $bindable(null), columnsOrder = $bindable(null), - selectedOption = $bindable('String'), + selectedOption = $bindable('Text'), createMore = $bindable(false), onColumnsReorder = null }: { @@ -63,8 +63,8 @@ default: null }; - /* default to string */ - selectedOption = 'String'; + /* default to text */ + selectedOption = 'Text'; $option = columnOptions[0]; } diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/column.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/column.svelte index a8865d78d..9be533a7c 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/column.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/column.svelte @@ -27,6 +27,10 @@ | Models.ColumnInteger | Models.ColumnIp | Models.ColumnString + | Models.ColumnText + | Models.ColumnMediumtext + | Models.ColumnLongtext + | Models.ColumnVarchar | Models.ColumnDatetime | Models.ColumnUrl | Models.ColumnPoint @@ -35,6 +39,10 @@ const columnsTypeMap = { string: String, + varchar: String, + text: String, + mediumtext: String, + longtext: String, integer: Integer, double: Integer, boolean: Boolean, diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/types/string.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/types/string.svelte index 1e7c5f8d0..fbfa549ae 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/types/string.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/columns/types/string.svelte @@ -20,6 +20,10 @@ limited?: boolean; column: | Models.ColumnString + | Models.ColumnVarchar + | Models.ColumnText + | Models.ColumnMediumtext + | Models.ColumnLongtext | Models.ColumnInteger | Models.ColumnFloat | Models.ColumnBoolean @@ -32,8 +36,8 @@ const maxlength = $derived( limited ? undefined - : column.type === 'string' - ? (column as Models.ColumnString).size + : column.type === 'string' || column.type === 'varchar' + ? (column as Models.ColumnString | Models.ColumnVarchar).size : undefined ); diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/store.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/store.ts index a007c01fc..1a65e7873 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/store.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/rows/store.ts @@ -30,6 +30,12 @@ export function isString(field: Field): field is Models.ColumnString | Models.At return field?.type === 'string'; } +export function isTextType(field: Field): boolean { + if (!field) return false; + const textTypes = ['string', 'varchar', 'text', 'mediumtext', 'longtext']; + return textTypes.includes(field?.type); +} + export function isSpatialType( field: Columns | Attributes | Column ): field is diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte index 8660d70fa..080f210fa 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/settings/displayName.svelte @@ -8,6 +8,7 @@ import { addNotification } from '$lib/stores/notifications'; import type { Models } from '@appwrite.io/console'; import { columns } from '../store'; + import { isTextType } from '../rows/store'; import { preferences } from '$lib/stores/preferences'; import { page } from '$app/state'; import { Icon, Layout } from '@appwrite.io/pink-svelte'; @@ -47,7 +48,7 @@ function getValidColumns() { return ($columns as Models.ColumnString[]).filter( - (attr) => attr.type === 'string' && !attr?.array + (attr) => isTextType(attr) && !attr?.array ); } diff --git a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.ts b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.ts index d3f4d6a5f..9d701180e 100644 --- a/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.ts +++ b/src/routes/(console)/project-[region]-[project]/databases/database-[database]/table-[table]/store.ts @@ -14,6 +14,10 @@ export type Columns = | Models.ColumnInteger | Models.ColumnIp | Models.ColumnString + | Models.ColumnText + | Models.ColumnMediumtext + | Models.ColumnLongtext + | Models.ColumnVarchar | Models.ColumnUrl | Models.ColumnPoint | Models.ColumnLine diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/deploy/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/deploy/+page.svelte index 04c757d76..684095010 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/deploy/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/deploy/+page.svelte @@ -11,7 +11,7 @@ import { Fieldset, Layout, Icon, Input, Tag } from '@appwrite.io/pink-svelte'; import { IconGithub, IconPencil } from '@appwrite.io/pink-icons-svelte'; import { onMount } from 'svelte'; - import { ID, Runtime, TemplateReferenceType } from '@appwrite.io/console'; + import { ID, Runtime, TemplateReferenceType, type Scopes } from '@appwrite.io/console'; import { CustomId } from '$lib/components'; import { getIconFromRuntime } from '$lib/stores/runtimes'; import { regionalConsoleVariables } from '$routes/(console)/project-[region]-[project]/store'; @@ -39,7 +39,7 @@ let specification = $state(''); let runtime = $state(); let installCommand = $state(''); - let selectedScopes = $state([]); + let selectedScopes = $state([]); let rootDir = $state(data.repository?.rootDirectory); let variables = $state>([]); diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte index 421a217d8..eee490a43 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/+page.svelte @@ -15,7 +15,13 @@ import { writable } from 'svelte/store'; import ProductionBranch from '$lib/components/git/productionBranchFieldset.svelte'; import Configuration from './configuration.svelte'; - import { ID, Runtime, TemplateReferenceType, type Models } from '@appwrite.io/console'; + import { + ID, + Runtime, + TemplateReferenceType, + type Models, + type Scopes + } from '@appwrite.io/console'; import { ConnectBehaviour, NewRepository, @@ -62,7 +68,7 @@ let showConfig = false; let silentMode = false; let entrypoint = ''; - let selectedScopes: string[] = []; + let selectedScopes: Scopes[] = []; let execute = true; let variables: Partial[] = []; let specification = specificationOptions[0]?.value || ''; diff --git a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/permissions.svelte b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/permissions.svelte index 0930c0e4f..3392f994e 100644 --- a/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/permissions.svelte +++ b/src/routes/(console)/project-[region]-[project]/functions/create-function/template-[template]/permissions.svelte @@ -1,15 +1,16 @@