Merge pull request #2838 from appwrite/feat-string-types

This commit is contained in:
Darshan
2026-02-06 20:21:47 +05:30
committed by GitHub
50 changed files with 820 additions and 222 deletions
+2 -2
View File
@@ -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=="],
+1 -1
View File
@@ -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",
+50 -2
View File
@@ -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,
+17 -1
View File
@@ -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);
+4
View File
@@ -30,6 +30,10 @@ export type Prettify<T> = T & {};
const columnTypes = [
'string',
'varchar',
'text',
'mediumtext',
'longtext',
'integer',
'double',
'boolean',
+46 -61
View File
@@ -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<Provider, Resource[]> = {
appwrite: [...resources], // new terminology, others are ok?
export const providerResources: Record<Provider, Resources[]> = {
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;
}
@@ -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<string, Resources> = {
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 @@
</script>
<Layout.Stack gap="l">
{#if report && !isVersionAtLeast(version, '1.4.0') && $provider.provider === 'appwrite'}
<Alert.Inline status="warning">
<svelte:fragment slot="title">Functions not available for import</svelte:fragment>
To migrate your functions, update the version of the Appwrite instance you're importing from
to a version newer than 1.4
</Alert.Inline>
{/if}
{#if error}
<Alert.Inline status="error" title="Couldn’t load resources">
{#if migrationType === 'provider'}
@@ -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,
@@ -1,10 +1,11 @@
<script module lang="ts">
import { IndexType, OrderBy } from '@appwrite.io/console';
export type CreateIndexesCallbackType = {
key: string;
type: IndexType;
fields: string[];
lengths: (number | null)[];
orders: string[];
orders: OrderBy[];
};
</script>
@@ -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,
@@ -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
@@ -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<string, number>) {
// 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<string>();
const columnMap: Map<string, number> = 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']])
);
@@ -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<T extends ColumnInput>(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)
@@ -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,
@@ -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
});
@@ -90,7 +90,7 @@
let createIndex: CreateIndex;
let createColumn: CreateColumn;
let selectedOption: Option['name'] = 'String';
let selectedOption: Option['name'] = 'Text';
let createMoreColumns = false;
/* terminology */
@@ -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') {
@@ -0,0 +1,99 @@
<script context="module" lang="ts">
import { page } from '$app/state';
import { sdk } from '$lib/stores/sdk';
import type { Models } from '@appwrite.io/console';
export async function submitLongtext(
databaseId: string,
tableId: string,
key: string,
data: Partial<Models.ColumnLongtext>
) {
await sdk
.forProject(page.params.region, page.params.project)
.tablesDB.createLongtextColumn({
databaseId,
tableId,
key,
required: data.required,
xdefault: data.default,
array: data.array
});
}
export async function updateLongtext(
databaseId: string,
tableId: string,
data: Partial<Models.ColumnLongtext>,
originalKey?: string
) {
await sdk
.forProject(page.params.region, page.params.project)
.tablesDB.updateLongtextColumn({
databaseId,
tableId,
key: originalKey,
required: data.required,
xdefault: data.default,
newKey: data.key !== originalKey ? data.key : undefined
});
}
</script>
<script lang="ts">
import { createConservative } from '$lib/helpers/stores';
import RequiredArrayCheckboxes from './requiredArrayCheckboxes.svelte';
import { InputTextarea } from '$lib/elements/forms';
import { Layout, Typography } from '@appwrite.io/pink-svelte';
export let data: Partial<Models.ColumnLongtext> = {
required: false,
array: false
};
export let editing = false;
export let disabled = false;
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
if (hideDefault) {
savedDefault = data.default;
data.default = null;
} else {
data.default = savedDefault;
}
}
const {
stores: { required, array },
listen
} = createConservative<Partial<Models.ColumnLongtext>>({
required: false,
array: false,
...data
});
$: listen(data);
$: handleDefaultState($required || $array);
</script>
<Layout.Stack gap="xs" direction="column">
<Typography.Text variant="m-500" color="--fgcolor-neutral-secondary">
Maximum size: 1,073,741,823 characters
</Typography.Text>
</Layout.Stack>
<InputTextarea
id="default"
label="Default"
placeholder="Enter text"
bind:value={data.default}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<RequiredArrayCheckboxes
{editing}
{disabled}
bind:array={data.array}
bind:required={data.required} />
@@ -0,0 +1,99 @@
<script context="module" lang="ts">
import { page } from '$app/state';
import { sdk } from '$lib/stores/sdk';
import type { Models } from '@appwrite.io/console';
export async function submitMediumtext(
databaseId: string,
tableId: string,
key: string,
data: Partial<Models.ColumnMediumtext>
) {
await sdk
.forProject(page.params.region, page.params.project)
.tablesDB.createMediumtextColumn({
databaseId,
tableId,
key,
required: data.required,
xdefault: data.default,
array: data.array
});
}
export async function updateMediumtext(
databaseId: string,
tableId: string,
data: Partial<Models.ColumnMediumtext>,
originalKey?: string
) {
await sdk
.forProject(page.params.region, page.params.project)
.tablesDB.updateMediumtextColumn({
databaseId,
tableId,
key: originalKey,
required: data.required,
xdefault: data.default,
newKey: data.key !== originalKey ? data.key : undefined
});
}
</script>
<script lang="ts">
import { createConservative } from '$lib/helpers/stores';
import RequiredArrayCheckboxes from './requiredArrayCheckboxes.svelte';
import { InputTextarea } from '$lib/elements/forms';
import { Layout, Typography } from '@appwrite.io/pink-svelte';
export let data: Partial<Models.ColumnMediumtext> = {
required: false,
array: false
};
export let editing = false;
export let disabled = false;
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
if (hideDefault) {
savedDefault = data.default;
data.default = null;
} else {
data.default = savedDefault;
}
}
const {
stores: { required, array },
listen
} = createConservative<Partial<Models.ColumnMediumtext>>({
required: false,
array: false,
...data
});
$: listen(data);
$: handleDefaultState($required || $array);
</script>
<Layout.Stack gap="xs" direction="column">
<Typography.Text variant="m-500" color="--fgcolor-neutral-secondary">
Maximum size: 4,194,303 characters
</Typography.Text>
</Layout.Stack>
<InputTextarea
id="default"
label="Default"
placeholder="Enter text"
bind:value={data.default}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<RequiredArrayCheckboxes
{editing}
{disabled}
bind:array={data.array}
bind:required={data.required} />
@@ -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
}
];
@@ -0,0 +1,95 @@
<script context="module" lang="ts">
import { page } from '$app/state';
import { sdk } from '$lib/stores/sdk';
import type { Models } from '@appwrite.io/console';
export async function submitText(
databaseId: string,
tableId: string,
key: string,
data: Partial<Models.ColumnText>
) {
await sdk.forProject(page.params.region, page.params.project).tablesDB.createTextColumn({
databaseId,
tableId,
key,
required: data.required,
xdefault: data.default,
array: data.array
});
}
export async function updateText(
databaseId: string,
tableId: string,
data: Partial<Models.ColumnText>,
originalKey?: string
) {
await sdk.forProject(page.params.region, page.params.project).tablesDB.updateTextColumn({
databaseId,
tableId,
key: originalKey,
required: data.required,
xdefault: data.default,
newKey: data.key !== originalKey ? data.key : undefined
});
}
</script>
<script lang="ts">
import { createConservative } from '$lib/helpers/stores';
import RequiredArrayCheckboxes from './requiredArrayCheckboxes.svelte';
import { InputTextarea } from '$lib/elements/forms';
import { Layout, Typography } from '@appwrite.io/pink-svelte';
export let data: Partial<Models.ColumnText> = {
required: false,
array: false
};
export let editing = false;
export let disabled = false;
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
if (hideDefault) {
savedDefault = data.default;
data.default = null;
} else {
data.default = savedDefault;
}
}
const {
stores: { required, array },
listen
} = createConservative<Partial<Models.ColumnText>>({
required: false,
array: false,
...data
});
$: listen(data);
$: handleDefaultState($required || $array);
</script>
<Layout.Stack gap="xs" direction="column">
<Typography.Text variant="m-500" color="--fgcolor-neutral-secondary">
Maximum size: 16,383 characters
</Typography.Text>
</Layout.Stack>
<InputTextarea
id="default"
label="Default"
placeholder="Enter text"
bind:value={data.default}
disabled={data.required || data.array || disabled}
nullable={!data.required && !data.array} />
<RequiredArrayCheckboxes
{editing}
{disabled}
bind:array={data.array}
bind:required={data.required} />
@@ -0,0 +1,172 @@
<script context="module" lang="ts">
import { page } from '$app/state';
import { sdk } from '$lib/stores/sdk';
import type { Models } from '@appwrite.io/console';
export async function submitVarchar(
databaseId: string,
tableId: string,
key: string,
data: Partial<Models.ColumnVarchar>
) {
await sdk.forProject(page.params.region, page.params.project).tablesDB.createVarcharColumn({
databaseId,
tableId,
key,
size: data.size,
required: data.required,
xdefault: data.default,
array: data.array
});
}
export async function updateVarchar(
databaseId: string,
tableId: string,
data: Partial<Models.ColumnVarchar>,
originalKey?: string
) {
await sdk.forProject(page.params.region, page.params.project).tablesDB.updateVarcharColumn({
databaseId,
tableId,
key: originalKey,
required: data.required,
xdefault: data.default,
size: data.size,
newKey: data.key !== originalKey ? data.key : undefined
});
}
</script>
<script lang="ts">
import { createConservative } from '$lib/helpers/stores';
import RequiredArrayCheckboxes from './requiredArrayCheckboxes.svelte';
import { InputNumber, InputText, InputTextarea } from '$lib/elements/forms';
import { table } from '../store';
import { ProgressBar } from '$lib/components';
import { Layout, Typography, Tooltip, Icon } from '@appwrite.io/pink-svelte';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
export let data: Partial<Models.ColumnVarchar> = {
required: false,
size: 255,
array: false
};
export let editing = false;
export let disabled = false;
// Local size for reactivity
let size = data.size ?? 255;
$: data.size = size;
function formatBytes(bytes: number): string {
return bytes < 1024 ? `${bytes.toLocaleString()} bytes` : `${(bytes / 1024).toFixed(1)} KB`;
}
function getNewColumnBytes(s: number): number {
return s * 4 + (s <= 255 ? 1 : 2);
}
function getProgressData(bytesUsed: number, bytesMax: number, s: number) {
const newBytes = getNewColumnBytes(s);
const exceeds = bytesUsed + newBytes > bytesMax;
return [
{
size: bytesUsed,
color: 'hsl(var(--color-information-100))',
tooltip: {
title: 'Current usage:',
label: formatBytes(bytesUsed)
}
},
{
size: newBytes,
color: exceeds ? 'hsl(var(--color-danger-100))' : 'hsl(var(--color-success-100))',
tooltip: {
title: 'New column:',
label: formatBytes(newBytes)
}
}
];
}
$: bytesMax = $table?.bytesMax ?? 65535;
$: bytesUsed = $table?.bytesUsed ?? 0;
$: newColumnBytes = getNewColumnBytes(size);
$: exceedsLimit = !editing && bytesUsed + newColumnBytes > bytesMax;
let savedDefault = data.default;
function handleDefaultState(hideDefault: boolean) {
if (hideDefault) {
savedDefault = data.default;
data.default = null;
} else {
data.default = savedDefault;
}
}
const {
stores: { required, array },
listen
} = createConservative<Partial<Models.ColumnVarchar>>({
required: false,
array: false,
...data
});
$: listen(data);
$: handleDefaultState($required || $array);
</script>
<InputNumber
id="size"
label="Size"
required
{disabled}
placeholder="Enter size"
bind:value={size}
min={1}
max={16383} />
{#if !editing}
<Layout.Stack gap="xs">
<Layout.Stack direction="row" gap="xs" alignItems="center">
<Typography.Text variant="m-500" color="--fgcolor-neutral-secondary">
Row size usage
</Typography.Text>
<Tooltip maxWidth="300px">
<Icon icon={IconInfo} size="s" />
<span slot="tooltip">
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.
</span>
</Tooltip>
</Layout.Stack>
<ProgressBar maxSize={bytesMax} data={getProgressData(bytesUsed, bytesMax, size)} />
{#if exceedsLimit}
<Typography.Text variant="m-400" color="--fgcolor-danger">
This column exceeds the remaining row space. Consider using text, mediumtext, or
longtext instead.
</Typography.Text>
{/if}
</Layout.Stack>
{/if}
<svelte:component
this={size >= 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} />
<RequiredArrayCheckboxes
{editing}
{disabled}
bind:array={data.array}
bind:required={data.required} />
@@ -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];
}
@@ -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,
@@ -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
);
@@ -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
@@ -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
);
}
@@ -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
@@ -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<Runtime>();
let installCommand = $state('');
let selectedScopes = $state<string[]>([]);
let selectedScopes = $state<Scopes[]>([]);
let rootDir = $state(data.repository?.rootDirectory);
let variables = $state<Array<{ key: string; value: string; secret: boolean }>>([]);
@@ -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<Models.TemplateVariable>[] = [];
let specification = specificationOptions[0]?.value || '';
@@ -1,15 +1,16 @@
<script lang="ts">
import { scopes } from '$lib/constants';
import { Fieldset, Layout, Selector } from '@appwrite.io/pink-svelte';
import type { Scopes } from '@appwrite.io/console';
export let templateScopes: string[];
export let selectedScopes: string[];
export let selectedScopes: Scopes[];
export let execute = true;
let scopeList = scopes
.filter((s) => templateScopes.includes(s.scope))
.map((s) => {
selectedScopes.push(s.scope);
selectedScopes.push(s.scope as Scopes);
return {
value: s,
checked: true
@@ -37,7 +38,7 @@
on:change={() => {
selectedScopes = scopeList
.filter((s) => s.checked)
.map((s) => s.value.scope);
.map((s) => s.value.scope as Scopes);
}}>
</Selector.Switch>
{/each}
@@ -9,7 +9,7 @@
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
import { installation, repository, sortBranches } from '$lib/stores/vcs';
import { Runtime, VCSReferenceType, type Models } from '@appwrite.io/console';
import { Runtime, VCSReferenceType, type Models, type Scopes } from '@appwrite.io/console';
import { IconGithub } from '@appwrite.io/pink-icons-svelte';
import { Icon, Input, Layout, Skeleton, Typography } from '@appwrite.io/pink-svelte';
import { func } from '../store';
@@ -87,7 +87,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $installation.$id || undefined,
providerRepositoryId: selectedRepository || undefined,
providerBranch: branch || undefined
@@ -10,7 +10,13 @@
import { sortBranches } from '$lib/stores/vcs';
import { IconInfo } from '@appwrite.io/pink-icons-svelte';
import { LabelCard } from '$lib/components';
import { type Models, ProxyResourceType, Runtime, StatusCode } from '@appwrite.io/console';
import {
type Models,
ProxyResourceType,
Runtime,
StatusCode,
type Scopes
} from '@appwrite.io/console';
import { statusCodeOptions } from '$lib/stores/domains';
import { writable } from 'svelte/store';
import { onMount } from 'svelte';
@@ -140,7 +146,7 @@
logging: data.func.logging || undefined,
entrypoint: data.func.entrypoint,
commands: data.func.commands || undefined,
scopes: data.func.scopes || undefined,
scopes: (data.func.scopes as Scopes[]) || undefined,
installationId: selectedInstallationId,
providerRepositoryId: selectedRepository,
providerBranch: 'main'
@@ -10,7 +10,7 @@
import { createEventDispatcher } from 'svelte';
import { func } from '../store';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime } from '@appwrite.io/console';
import { Runtime, type Scopes } from '@appwrite.io/console';
export let show = false;
const functionId = page.params.function;
@@ -35,7 +35,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: '',
providerRepositoryId: '',
providerBranch: '',
@@ -7,7 +7,7 @@
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime, type Models } from '@appwrite.io/console';
import { Runtime, type Models, type Scopes } from '@appwrite.io/console';
import { page } from '$app/state';
export let func: Models.Function;
@@ -30,7 +30,7 @@
logging: func.logging || undefined,
entrypoint: func.entrypoint || undefined,
commands: buildCommand || undefined,
scopes: func.scopes || undefined,
scopes: (func.scopes as Scopes[]) || undefined,
installationId: func.installationId || undefined,
providerRepositoryId: func.providerRepositoryId || undefined,
providerBranch: func.providerBranch || undefined,
@@ -14,7 +14,7 @@
import { EventModal } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime } from '@appwrite.io/console';
import { Runtime, type Scopes } from '@appwrite.io/console';
import { IconPlus, IconX } from '@appwrite.io/pink-icons-svelte';
import { Icon, Layout, Link, Table, Typography } from '@appwrite.io/pink-svelte';
@@ -41,7 +41,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint || undefined,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $func.installationId || undefined,
providerRepositoryId: $func.providerRepositoryId || undefined,
providerBranch: $func.providerBranch || undefined,
@@ -7,7 +7,7 @@
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime, type Models } from '@appwrite.io/console';
import { Runtime, type Models, type Scopes } from '@appwrite.io/console';
import { Typography } from '@appwrite.io/pink-svelte';
import { page } from '$app/state';
@@ -31,7 +31,7 @@
logging,
entrypoint: func.entrypoint || undefined,
commands: func.commands || undefined,
scopes: func.scopes || undefined,
scopes: (func.scopes as Scopes[]) || undefined,
installationId: func.installationId || undefined,
providerRepositoryId: func.providerRepositoryId || undefined,
providerBranch: func.providerBranch || undefined,
@@ -10,7 +10,7 @@
import { onMount } from 'svelte';
import { func } from '../store';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime } from '@appwrite.io/console';
import { Runtime, type Scopes } from '@appwrite.io/console';
const functionId = page.params.function;
let functionName: string = null;
@@ -36,7 +36,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint || undefined,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $func.installationId || undefined,
providerRepositoryId: $func.providerRepositoryId || undefined,
providerBranch: $func.providerBranch || undefined,
@@ -12,7 +12,7 @@
import { Roles } from '$lib/components/permissions';
import { symmetricDifference } from '$lib/helpers/array';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime } from '@appwrite.io/console';
import { Runtime, type Scopes } from '@appwrite.io/console';
import { Link } from '$lib/elements';
const functionId = page.params.function;
@@ -41,7 +41,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint || undefined,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $func.installationId || undefined,
providerRepositoryId: $func.providerRepositoryId || undefined,
providerBranch: $func.providerBranch || undefined,
@@ -6,7 +6,7 @@
import { Button, Form, InputText } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
import { Runtime, type Models } from '@appwrite.io/console';
import { Runtime, type Models, type Scopes } from '@appwrite.io/console';
import { onMount } from 'svelte';
import DisconnectRepo from './disconnectRepo.svelte';
import { installation, repository as repositoryStore, sortBranches } from '$lib/stores/vcs';
@@ -86,7 +86,7 @@
logging: func.logging || undefined,
entrypoint: func.entrypoint || undefined,
commands: func.commands || undefined,
scopes: func.scopes || undefined,
scopes: (func.scopes as Scopes[]) || undefined,
installationId: func.installationId || undefined,
providerRepositoryId: func.providerRepositoryId || undefined,
providerBranch: selectedBranch,
@@ -145,7 +145,7 @@
logging: func.logging || undefined,
entrypoint: func.entrypoint,
commands: func.commands || undefined,
scopes: func.scopes || undefined,
scopes: (func.scopes as Scopes[]) || undefined,
installationId: selectedInstallationId,
providerRepositoryId: selectedRepository,
providerBranch: 'main'
@@ -7,7 +7,7 @@
import { addNotification } from '$lib/stores/notifications';
import { sdk } from '$lib/stores/sdk';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime, type Models } from '@appwrite.io/console';
import { Runtime, type Models, type Scopes } from '@appwrite.io/console';
import Link from '$lib/elements/link.svelte';
import { Alert } from '@appwrite.io/pink-svelte';
import { isStarterPlan, getChangePlanUrl } from '$lib/stores/billing';
@@ -39,7 +39,7 @@
logging: func.logging || undefined,
entrypoint: func.entrypoint || undefined,
commands: func.commands || undefined,
scopes: func.scopes || undefined,
scopes: (func.scopes as Scopes[]) || undefined,
installationId: func.installationId || undefined,
providerRepositoryId: func.providerRepositoryId || undefined,
providerBranch: func.providerBranch || undefined,
@@ -10,7 +10,7 @@
import { func } from '../store';
import InputSelect from '$lib/elements/forms/inputSelect.svelte';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime, type Models } from '@appwrite.io/console';
import { Runtime, type Models, type Scopes } from '@appwrite.io/console';
import { Layout, Typography } from '@appwrite.io/pink-svelte';
import Link from '$lib/elements/link.svelte';
@@ -40,7 +40,7 @@
logging: $func.logging || undefined,
entrypoint: entrypoint || undefined,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $func.installationId || undefined,
providerRepositoryId: $func.providerRepositoryId || undefined,
providerBranch: $func.providerBranch || undefined,
@@ -10,7 +10,7 @@
import { onMount } from 'svelte';
import { func } from '../store';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime } from '@appwrite.io/console';
import { Runtime, type Scopes } from '@appwrite.io/console';
import { Link } from '$lib/elements';
import { parseExpression } from 'cron-parser';
@@ -41,7 +41,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint || undefined,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $func.installationId || undefined,
providerRepositoryId: $func.providerRepositoryId || undefined,
providerBranch: $func.providerBranch || undefined,
@@ -10,16 +10,16 @@
import { onMount } from 'svelte';
import { func } from '../store';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime } from '@appwrite.io/console';
import { Runtime, type Scopes as ScopesType } from '@appwrite.io/console';
import Scopes from '$routes/(console)/project-[region]-[project]/overview/api-keys/scopes.svelte';
import { symmetricDifference } from '$lib/helpers/array';
import { Link } from '$lib/elements';
const functionId = page.params.function;
let functionScopes: string[] = null;
let functionScopes: ScopesType[] = null;
onMount(async () => {
functionScopes ??= $func.scopes;
functionScopes ??= $func.scopes as ScopesType[];
});
async function updateScopes() {
@@ -39,7 +39,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint || undefined,
commands: $func.commands || undefined,
scopes: functionScopes,
scopes: functionScopes || undefined,
installationId: $func.installationId || undefined,
providerRepositoryId: $func.providerRepositoryId || undefined,
providerBranch: $func.providerBranch || undefined,
@@ -10,7 +10,7 @@
import { onMount } from 'svelte';
import { func } from '../store';
import { isValueOfStringEnum } from '$lib/helpers/types';
import { Runtime } from '@appwrite.io/console';
import { Runtime, type Scopes } from '@appwrite.io/console';
const functionId = page.params.function;
let timeout: number = null;
@@ -36,7 +36,7 @@
logging: $func.logging || undefined,
entrypoint: $func.entrypoint || undefined,
commands: $func.commands || undefined,
scopes: $func.scopes || undefined,
scopes: ($func.scopes as Scopes[]) || undefined,
installationId: $func.installationId || undefined,
providerRepositoryId: $func.providerRepositoryId || undefined,
providerBranch: $func.providerBranch || undefined,
@@ -14,6 +14,7 @@
import { addNotification } from '$lib/stores/notifications';
import { writable } from 'svelte/store';
import Scopes from '../api-keys/scopes.svelte';
import { type Scopes as ScopesType } from '@appwrite.io/console';
import { page } from '$app/state';
import { copy } from '$lib/helpers/copy';
@@ -23,7 +24,7 @@
let formComponent: Form;
let isSubmitting = writable(false);
let scopes: string[] = [];
let scopes: ScopesType[] = [];
let name = '';
let expire: string | null = null;
@@ -12,7 +12,7 @@
import { project } from '../../store';
import Delete from './delete.svelte';
import UpdateExpirationDate from './updateExpirationDate.svelte';
import type { Models } from '@appwrite.io/console';
import type { Models, Scopes as ScopesType } from '@appwrite.io/console';
import { symmetricDifference } from '$lib/helpers/array';
import Scopes from '../api-keys/scopes.svelte';
import { InteractiveText, Layout, Typography } from '@appwrite.io/pink-svelte';
@@ -22,7 +22,7 @@
export let keyType: 'api' | 'dev' = 'api';
let name: string = null;
let scopes: string[] = null;
let scopes: ScopesType[] = null;
let showDelete = false;
const isApiKey = keyType === 'api';
@@ -33,7 +33,7 @@
onMount(() => {
name ??= key.name;
if (isApiKey) {
scopes ??= (key as Models.Key).scopes;
scopes ??= (key as Models.Key).scopes as ScopesType[];
}
});
@@ -9,7 +9,7 @@
import { sdk } from '$lib/stores/sdk';
import { Alert } from '@appwrite.io/pink-svelte';
import { ExpirationInput } from '$lib/components';
import type { Models } from '@appwrite.io/console';
import type { Models, Scopes } from '@appwrite.io/console';
import { page } from '$app/state';
export let keyType: 'api' | 'dev' = 'api';
@@ -32,7 +32,7 @@
projectId,
keyId: key.$id,
name: key.name,
scopes: (key as Models.Key).scopes,
scopes: (key as Models.Key).scopes as Scopes[],
expire: expiration
});
} else {
@@ -32,8 +32,9 @@
import { symmetricDifference } from '$lib/helpers/array';
import { scopes as allScopes, cloudOnlyBackupScopes } from '$lib/constants';
import { Accordion, Divider, Layout, Selector } from '@appwrite.io/pink-svelte';
import type { Scopes } from '@appwrite.io/console';
export let scopes: string[];
export let scopes: Scopes[];
const baseFilteredScopes = allScopes.filter((scope) => {
const val = scope.scope;
@@ -159,7 +160,7 @@
});
}
function generateSyncedScopes(activeScopesObj: Record<string, boolean>): string[] {
function generateSyncedScopes(activeScopesObj: Record<string, boolean>): Scopes[] {
const result = new Set<string>();
Object.entries(activeScopesObj).forEach(([scope, isActive]) => {
@@ -173,7 +174,7 @@
}
});
return Array.from(result);
return Array.from(result) as Scopes[];
}
$: {
@@ -14,7 +14,7 @@
import Details from './details.svelte';
import ExportModal from './exportModal.svelte';
import { readOnly } from '$lib/stores/billing';
import type { Models } from '@appwrite.io/console';
import { Scopes, type Models } from '@appwrite.io/console';
import { canWriteProjects } from '$lib/stores/roles';
import {
IconCloud,
@@ -90,23 +90,23 @@
projectId: $project.$id,
name: `[AUTO-GENERATED] Migration ${new Date().toISOString()}`,
scopes: [
'users.read',
'teams.read',
'databases.read',
'collections.read' /* legacy */,
'attributes.read' /* legacy */,
'indexes.read',
'documents.read' /* legacy */,
'tables.read',
'columns.read',
'rows.read',
'files.read',
'buckets.read',
'functions.read',
'execution.read',
'locale.read',
'avatars.read',
'health.read'
Scopes.UsersRead,
Scopes.TeamsRead,
Scopes.DatabasesRead,
Scopes.CollectionsRead /* legacy */,
Scopes.AttributesRead /* legacy */,
Scopes.IndexesRead,
Scopes.DocumentsRead /* legacy */,
Scopes.TablesRead,
Scopes.ColumnsRead,
Scopes.RowsRead,
Scopes.FilesRead,
Scopes.BucketsRead,
Scopes.FunctionsRead,
Scopes.ExecutionRead,
Scopes.LocaleRead,
Scopes.AvatarsRead,
Scopes.HealthRead
]
});
@@ -10,6 +10,7 @@
import { sdk } from '$lib/stores/sdk';
import { user } from '$lib/stores/user';
import { organization } from '$lib/stores/organization';
import { Scopes } from '@appwrite.io/console';
export let show = false;
@@ -91,23 +92,23 @@
projectId: $project.$id,
name: `[AUTO-GENERATED] Migration ${new Date().toISOString()}`,
scopes: [
'users.read',
'teams.read',
'databases.read',
'collections.read' /* legacy */,
'attributes.read' /* legacy */,
'indexes.read',
'documents.read' /* legacy */,
'tables.read',
'columns.read',
'rows.read',
'files.read',
'buckets.read',
'functions.read',
'execution.read',
'locale.read',
'avatars.read',
'health.read'
Scopes.UsersRead,
Scopes.TeamsRead,
Scopes.DatabasesRead,
Scopes.CollectionsRead /* legacy */,
Scopes.AttributesRead /* legacy */,
Scopes.IndexesRead,
Scopes.DocumentsRead /* legacy */,
Scopes.TablesRead,
Scopes.ColumnsRead,
Scopes.RowsRead,
Scopes.FilesRead,
Scopes.BucketsRead,
Scopes.FunctionsRead,
Scopes.ExecutionRead,
Scopes.LocaleRead,
Scopes.AvatarsRead,
Scopes.HealthRead
]
});