mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-19 11:02:11 +08:00
feat(server): improve context management (#15448)
#### PR Dependency Tree * **PR #15448** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added workspace artifact upload, browsing, removal, deduplication, and library ownership support. * Copilot now supports scoped document and artifact search, canvas reading, live editor context, and frontend tools. * Added scope and focus selectors with source-resolution receipts in chat. * Added embedding health, progress, synchronization, and retrieval capabilities. * Added BYOK policy visibility, provider restrictions, endpoint dialect selection, and validation. * Added delegated editor interactions and userdata document authorization. * **Bug Fixes** * Improved attachment handling, cancellation, access control, retrieval fallbacks, workspace synchronization, and configuration validation. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -16,6 +16,12 @@ test('should create config', t => {
|
||||
|
||||
t.is(typeof config.auth.passwordRequirements.max, 'number');
|
||||
t.is(typeof config.job.queue, 'object');
|
||||
t.deepEqual(config.copilot.byok.allowedProviders, [
|
||||
'openai',
|
||||
'anthropic',
|
||||
'gemini',
|
||||
'fal',
|
||||
]);
|
||||
});
|
||||
|
||||
test('should override config', async t => {
|
||||
@@ -89,6 +95,16 @@ test('should validate config', t => {
|
||||
error.message,
|
||||
'Invalid app config for module `auth` with key `passwordRequirements`. Minimum length of password must be less than maximum length.'
|
||||
);
|
||||
|
||||
const [nativeError] = config.validate([
|
||||
{
|
||||
module: 'copilot',
|
||||
key: 'byok.allowedProviders',
|
||||
value: ['openai', 'openai'],
|
||||
},
|
||||
])!;
|
||||
t.true(nativeError instanceof InvalidAppConfig);
|
||||
t.regex(nativeError.message, /supported and unique/);
|
||||
});
|
||||
|
||||
test('should override correctly', t => {
|
||||
|
||||
@@ -26,4 +26,9 @@ export class ConfigModule {
|
||||
}
|
||||
|
||||
export { Config, ConfigFactory };
|
||||
export { defineModuleConfig, type JSONSchema } from './register';
|
||||
export {
|
||||
defineModuleConfig,
|
||||
defineNativeModuleConfig,
|
||||
type JSONSchema,
|
||||
type NativeAppConfigDescriptor,
|
||||
} from './register';
|
||||
|
||||
@@ -8,22 +8,35 @@ import { z } from 'zod';
|
||||
import { type EnvConfigType, parseEnvValue } from './env';
|
||||
import { AppConfigByPath } from './types';
|
||||
|
||||
export type JSONSchema = { description?: string } & (
|
||||
| { type?: undefined; oneOf?: JSONSchema[] }
|
||||
| {
|
||||
type: 'string' | 'number' | 'boolean';
|
||||
enum?: string[];
|
||||
}
|
||||
| {
|
||||
type: 'array';
|
||||
items?: JSONSchema;
|
||||
}
|
||||
| {
|
||||
type: 'object';
|
||||
properties?: Record<string, JSONSchema>;
|
||||
required?: string[];
|
||||
}
|
||||
);
|
||||
export type JSONSchema = {
|
||||
$id?: string;
|
||||
$ref?: string;
|
||||
$schema?: string;
|
||||
additionalProperties?: boolean | JSONSchema;
|
||||
allOf?: JSONSchema[];
|
||||
anyOf?: JSONSchema[];
|
||||
definitions?: Record<string, JSONSchema>;
|
||||
description?: string;
|
||||
default?: unknown;
|
||||
enum?: unknown[];
|
||||
format?: string;
|
||||
items?: JSONSchema;
|
||||
minItems?: number;
|
||||
minLength?: number;
|
||||
oneOf?: JSONSchema[];
|
||||
pattern?: string;
|
||||
properties?: Record<string, JSONSchema>;
|
||||
required?: string[];
|
||||
title?: string;
|
||||
type?:
|
||||
| 'string'
|
||||
| 'number'
|
||||
| 'boolean'
|
||||
| 'array'
|
||||
| 'object'
|
||||
| 'null'
|
||||
| Array<'string' | 'number' | 'boolean' | 'array' | 'object' | 'null'>;
|
||||
};
|
||||
|
||||
type ConfigType = EnvConfigType | 'array' | 'object' | 'any';
|
||||
export type ConfigDescriptor<T> = {
|
||||
@@ -34,6 +47,7 @@ export type ConfigDescriptor<T> = {
|
||||
default: T;
|
||||
env?: [string, EnvConfigType];
|
||||
link?: string;
|
||||
internal?: boolean;
|
||||
};
|
||||
|
||||
type ConfigDefineDescriptor<T> = {
|
||||
@@ -44,6 +58,7 @@ type ConfigDefineDescriptor<T> = {
|
||||
env?: string | [string, EnvConfigType];
|
||||
link?: string;
|
||||
schema?: JSONSchema;
|
||||
internal?: boolean;
|
||||
};
|
||||
|
||||
function typeFromShape(shape: z.ZodType<any>): ConfigType {
|
||||
@@ -87,19 +102,17 @@ function shapeFromType(type: ConfigType): z.ZodType<any> {
|
||||
}
|
||||
|
||||
function typeFromSchema(schema: JSONSchema): ConfigType {
|
||||
if ('type' in schema) {
|
||||
switch (schema.type) {
|
||||
case 'string':
|
||||
return 'string';
|
||||
case 'number':
|
||||
return 'float';
|
||||
case 'boolean':
|
||||
return 'boolean';
|
||||
case 'array':
|
||||
return 'array';
|
||||
case 'object':
|
||||
return 'object';
|
||||
}
|
||||
switch (schema.type) {
|
||||
case 'string':
|
||||
return 'string';
|
||||
case 'number':
|
||||
return 'float';
|
||||
case 'boolean':
|
||||
return 'boolean';
|
||||
case 'array':
|
||||
return 'array';
|
||||
case 'object':
|
||||
return 'object';
|
||||
}
|
||||
|
||||
return 'any';
|
||||
@@ -168,6 +181,7 @@ function standardizeDescriptor<T>(
|
||||
},
|
||||
env,
|
||||
link: desc.link,
|
||||
internal: desc.internal,
|
||||
schema: {
|
||||
type: schemaFromType(type),
|
||||
description: desc.desc,
|
||||
@@ -200,12 +214,20 @@ export const getDescriptors = once(() => {
|
||||
export function defineModuleConfig<T extends keyof AppConfigSchema>(
|
||||
module: T,
|
||||
defs: ModuleConfigDescriptors<AppConfigByPath<T>>
|
||||
) {
|
||||
registerModuleConfig(
|
||||
module,
|
||||
defs as Record<string, ConfigDefineDescriptor<unknown>>
|
||||
);
|
||||
}
|
||||
|
||||
function registerModuleConfig(
|
||||
module: string,
|
||||
defs: Record<string, ConfigDefineDescriptor<unknown>>
|
||||
) {
|
||||
const descriptors: Record<string, ConfigDescriptor<any>> = {};
|
||||
Object.entries(defs).forEach(([key, desc]) => {
|
||||
descriptors[key] = standardizeDescriptor(
|
||||
desc as ConfigDefineDescriptor<any>
|
||||
);
|
||||
descriptors[key] = standardizeDescriptor(desc);
|
||||
});
|
||||
|
||||
APP_CONFIG_DESCRIPTORS[module] = {
|
||||
@@ -214,7 +236,52 @@ export function defineModuleConfig<T extends keyof AppConfigSchema>(
|
||||
};
|
||||
}
|
||||
|
||||
const CONFIG_JSON_PATHS = [
|
||||
export type NativeAppConfigDescriptor = {
|
||||
key: string;
|
||||
description: string;
|
||||
defaultValue: unknown;
|
||||
schema: JSONSchema;
|
||||
internal: boolean;
|
||||
};
|
||||
|
||||
export function defineNativeModuleConfig<T extends keyof AppConfigSchema>(
|
||||
module: T,
|
||||
descriptors: NativeAppConfigDescriptor[],
|
||||
validate: (module: string, key: string, value: unknown) => string[],
|
||||
nodeDefinitions: Partial<ModuleConfigDescriptors<AppConfigByPath<T>>> = {}
|
||||
) {
|
||||
registerModuleConfig(module, {
|
||||
...nodeDefinitions,
|
||||
...Object.fromEntries(
|
||||
descriptors.map(descriptor => [
|
||||
descriptor.key,
|
||||
{
|
||||
desc: descriptor.description,
|
||||
default: descriptor.defaultValue,
|
||||
schema: descriptor.schema,
|
||||
internal: descriptor.internal,
|
||||
validate: (value: unknown) => {
|
||||
const errors = validate(module, descriptor.key, value);
|
||||
return errors.length
|
||||
? {
|
||||
success: false as const,
|
||||
error: new z.ZodError(
|
||||
errors.map(message => ({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message,
|
||||
path: [],
|
||||
}))
|
||||
),
|
||||
}
|
||||
: { success: true as const, data: value };
|
||||
},
|
||||
},
|
||||
])
|
||||
),
|
||||
} as Record<string, ConfigDefineDescriptor<unknown>>);
|
||||
}
|
||||
|
||||
export const CONFIG_JSON_PATHS = [
|
||||
join(env.projectRoot, 'config.json'),
|
||||
`${homedir()}/.affine/config/config.json`,
|
||||
];
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { STATUS_CODES } from 'node:http';
|
||||
import { escape } from 'node:querystring';
|
||||
|
||||
import { HttpStatus, Logger } from '@nestjs/common';
|
||||
import { ClsServiceManager } from 'nestjs-cls';
|
||||
@@ -791,35 +790,6 @@ export const USER_FRIENDLY_ERRORS = {
|
||||
message: ({ provider, kind, message }) =>
|
||||
`Provider ${provider} failed with ${kind} error: ${message || 'unknown'}`,
|
||||
},
|
||||
copilot_invalid_context: {
|
||||
type: 'invalid_input',
|
||||
args: { contextId: 'string' },
|
||||
message: ({ contextId }) => `Invalid copilot context ${contextId}.`,
|
||||
},
|
||||
copilot_context_file_not_supported: {
|
||||
type: 'bad_request',
|
||||
args: { fileName: 'string', message: 'string' },
|
||||
message: ({ fileName, message }) =>
|
||||
`File ${fileName} is not supported to use as context: ${message}`,
|
||||
},
|
||||
copilot_failed_to_modify_context: {
|
||||
type: 'internal_server_error',
|
||||
args: { contextId: 'string', message: 'string' },
|
||||
message: ({ contextId, message }) =>
|
||||
`Failed to modify context ${contextId}: ${message}`,
|
||||
},
|
||||
copilot_failed_to_match_context: {
|
||||
type: 'internal_server_error',
|
||||
args: { contextId: 'string', content: 'string', message: 'string' },
|
||||
message: ({ contextId, content, message }) =>
|
||||
`Failed to match context ${contextId} with "${escape(content)}": ${message}`,
|
||||
},
|
||||
copilot_failed_to_match_global_context: {
|
||||
type: 'internal_server_error',
|
||||
args: { workspaceId: 'string', content: 'string', message: 'string' },
|
||||
message: ({ workspaceId, content, message }) =>
|
||||
`Failed to match context in workspace ${workspaceId} with "${escape(content)}": ${message}`,
|
||||
},
|
||||
copilot_embedding_disabled: {
|
||||
type: 'action_forbidden',
|
||||
message: `Embedding feature is disabled, please contact the administrator to enable it in the workspace settings.`,
|
||||
@@ -828,6 +798,27 @@ export const USER_FRIENDLY_ERRORS = {
|
||||
type: 'action_forbidden',
|
||||
message: `Embedding feature not available, you may need to install pgvector extension to your database`,
|
||||
},
|
||||
copilot_selected_sources_processing: {
|
||||
type: 'bad_request',
|
||||
message: `Selected sources are still processing. Try again shortly.`,
|
||||
},
|
||||
copilot_selected_sources_failed: {
|
||||
type: 'bad_request',
|
||||
message: `Selected sources could not be processed. Remove the failed source or try again.`,
|
||||
},
|
||||
copilot_selected_sources_unavailable: {
|
||||
type: 'action_forbidden',
|
||||
message: `Selected sources are not available for AI retrieval.`,
|
||||
},
|
||||
copilot_selected_sources_limit_exceeded: {
|
||||
type: 'invalid_input',
|
||||
message: `Too many or too much content was selected. Select fewer sources and try again.`,
|
||||
},
|
||||
copilot_failed_to_add_workspace_artifact: {
|
||||
type: 'internal_server_error',
|
||||
args: { message: 'string' },
|
||||
message: ({ message }) => `Failed to add workspace artifact: ${message}`,
|
||||
},
|
||||
copilot_transcription_job_exists: {
|
||||
type: 'bad_request',
|
||||
message: 'Transcription job already exists',
|
||||
@@ -840,13 +831,6 @@ export const USER_FRIENDLY_ERRORS = {
|
||||
type: 'bad_request',
|
||||
message: `Audio not provided.`,
|
||||
},
|
||||
copilot_failed_to_add_workspace_file_embedding: {
|
||||
type: 'internal_server_error',
|
||||
args: { message: 'string' },
|
||||
message: ({ message }) =>
|
||||
`Failed to add workspace file embedding: ${message}`,
|
||||
},
|
||||
|
||||
// Quota & Limit errors
|
||||
blob_quota_exceeded: {
|
||||
type: 'quota_exceeded',
|
||||
|
||||
@@ -868,62 +868,6 @@ export class CopilotProviderSideError extends UserFriendlyError {
|
||||
super('internal_server_error', 'copilot_provider_side_error', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotInvalidContextDataType {
|
||||
@Field() contextId!: string
|
||||
}
|
||||
|
||||
export class CopilotInvalidContext extends UserFriendlyError {
|
||||
constructor(args: CopilotInvalidContextDataType, message?: string | ((args: CopilotInvalidContextDataType) => string)) {
|
||||
super('invalid_input', 'copilot_invalid_context', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotContextFileNotSupportedDataType {
|
||||
@Field() fileName!: string
|
||||
@Field() message!: string
|
||||
}
|
||||
|
||||
export class CopilotContextFileNotSupported extends UserFriendlyError {
|
||||
constructor(args: CopilotContextFileNotSupportedDataType, message?: string | ((args: CopilotContextFileNotSupportedDataType) => string)) {
|
||||
super('bad_request', 'copilot_context_file_not_supported', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotFailedToModifyContextDataType {
|
||||
@Field() contextId!: string
|
||||
@Field() message!: string
|
||||
}
|
||||
|
||||
export class CopilotFailedToModifyContext extends UserFriendlyError {
|
||||
constructor(args: CopilotFailedToModifyContextDataType, message?: string | ((args: CopilotFailedToModifyContextDataType) => string)) {
|
||||
super('internal_server_error', 'copilot_failed_to_modify_context', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotFailedToMatchContextDataType {
|
||||
@Field() contextId!: string
|
||||
@Field() content!: string
|
||||
@Field() message!: string
|
||||
}
|
||||
|
||||
export class CopilotFailedToMatchContext extends UserFriendlyError {
|
||||
constructor(args: CopilotFailedToMatchContextDataType, message?: string | ((args: CopilotFailedToMatchContextDataType) => string)) {
|
||||
super('internal_server_error', 'copilot_failed_to_match_context', message, args);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotFailedToMatchGlobalContextDataType {
|
||||
@Field() workspaceId!: string
|
||||
@Field() content!: string
|
||||
@Field() message!: string
|
||||
}
|
||||
|
||||
export class CopilotFailedToMatchGlobalContext extends UserFriendlyError {
|
||||
constructor(args: CopilotFailedToMatchGlobalContextDataType, message?: string | ((args: CopilotFailedToMatchGlobalContextDataType) => string)) {
|
||||
super('internal_server_error', 'copilot_failed_to_match_global_context', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotEmbeddingDisabled extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
@@ -937,6 +881,40 @@ export class CopilotEmbeddingUnavailable extends UserFriendlyError {
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotSelectedSourcesProcessing extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'copilot_selected_sources_processing', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotSelectedSourcesFailed extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'copilot_selected_sources_failed', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotSelectedSourcesUnavailable extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('action_forbidden', 'copilot_selected_sources_unavailable', message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotSelectedSourcesLimitExceeded extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('invalid_input', 'copilot_selected_sources_limit_exceeded', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotFailedToAddWorkspaceArtifactDataType {
|
||||
@Field() message!: string
|
||||
}
|
||||
|
||||
export class CopilotFailedToAddWorkspaceArtifact extends UserFriendlyError {
|
||||
constructor(args: CopilotFailedToAddWorkspaceArtifactDataType, message?: string | ((args: CopilotFailedToAddWorkspaceArtifactDataType) => string)) {
|
||||
super('internal_server_error', 'copilot_failed_to_add_workspace_artifact', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class CopilotTranscriptionJobExists extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
super('bad_request', 'copilot_transcription_job_exists', message);
|
||||
@@ -954,16 +932,6 @@ export class CopilotTranscriptionAudioNotProvided extends UserFriendlyError {
|
||||
super('bad_request', 'copilot_transcription_audio_not_provided', message);
|
||||
}
|
||||
}
|
||||
@ObjectType()
|
||||
class CopilotFailedToAddWorkspaceFileEmbeddingDataType {
|
||||
@Field() message!: string
|
||||
}
|
||||
|
||||
export class CopilotFailedToAddWorkspaceFileEmbedding extends UserFriendlyError {
|
||||
constructor(args: CopilotFailedToAddWorkspaceFileEmbeddingDataType, message?: string | ((args: CopilotFailedToAddWorkspaceFileEmbeddingDataType) => string)) {
|
||||
super('internal_server_error', 'copilot_failed_to_add_workspace_file_embedding', message, args);
|
||||
}
|
||||
}
|
||||
|
||||
export class BlobQuotaExceeded extends UserFriendlyError {
|
||||
constructor(message?: string) {
|
||||
@@ -1317,17 +1285,16 @@ export enum ErrorNames {
|
||||
COPILOT_PROMPT_INVALID,
|
||||
COPILOT_PROVIDER_NOT_SUPPORTED,
|
||||
COPILOT_PROVIDER_SIDE_ERROR,
|
||||
COPILOT_INVALID_CONTEXT,
|
||||
COPILOT_CONTEXT_FILE_NOT_SUPPORTED,
|
||||
COPILOT_FAILED_TO_MODIFY_CONTEXT,
|
||||
COPILOT_FAILED_TO_MATCH_CONTEXT,
|
||||
COPILOT_FAILED_TO_MATCH_GLOBAL_CONTEXT,
|
||||
COPILOT_EMBEDDING_DISABLED,
|
||||
COPILOT_EMBEDDING_UNAVAILABLE,
|
||||
COPILOT_SELECTED_SOURCES_PROCESSING,
|
||||
COPILOT_SELECTED_SOURCES_FAILED,
|
||||
COPILOT_SELECTED_SOURCES_UNAVAILABLE,
|
||||
COPILOT_SELECTED_SOURCES_LIMIT_EXCEEDED,
|
||||
COPILOT_FAILED_TO_ADD_WORKSPACE_ARTIFACT,
|
||||
COPILOT_TRANSCRIPTION_JOB_EXISTS,
|
||||
COPILOT_TRANSCRIPTION_JOB_NOT_FOUND,
|
||||
COPILOT_TRANSCRIPTION_AUDIO_NOT_PROVIDED,
|
||||
COPILOT_FAILED_TO_ADD_WORKSPACE_FILE_EMBEDDING,
|
||||
BLOB_QUOTA_EXCEEDED,
|
||||
STORAGE_QUOTA_EXCEEDED,
|
||||
MEMBER_QUOTA_EXCEEDED,
|
||||
@@ -1368,5 +1335,5 @@ registerEnumType(ErrorNames, {
|
||||
export const ErrorDataUnionType = createUnionType({
|
||||
name: 'ErrorDataUnion',
|
||||
types: () =>
|
||||
[GraphqlBadRequestDataType, HttpRequestErrorDataType, SsrfBlockedErrorDataType, ResponseTooLargeErrorDataType, ImageFormatNotSupportedDataType, QueryTooLongDataType, ValidationErrorDataType, WrongSignInCredentialsDataType, UnknownOauthProviderDataType, InvalidOauthCallbackCodeDataType, MissingOauthQueryParameterDataType, InvalidOauthResponseDataType, InvalidEmailDataType, InvalidPasswordLengthDataType, WorkspacePermissionNotFoundDataType, SpaceNotFoundDataType, MemberNotFoundInSpaceDataType, NotInSpaceDataType, AlreadyInSpaceDataType, SpaceAccessDeniedDataType, SpaceOwnerNotFoundDataType, SpaceShouldHaveOnlyOneOwnerDataType, DocNotFoundDataType, DocActionDeniedDataType, DocUpdateBlockedDataType, VersionRejectedDataType, InvalidHistoryTimestampDataType, DocHistoryNotFoundDataType, BlobNotFoundDataType, ExpectToGrantDocUserRolesDataType, ExpectToRevokeDocUserRolesDataType, ExpectToUpdateDocUserRoleDataType, NoMoreSeatDataType, UnsupportedSubscriptionPlanDataType, SubscriptionAlreadyExistsDataType, SubscriptionNotExistsDataType, SameSubscriptionRecurringDataType, SubscriptionPlanNotFoundDataType, CalendarProviderRequestErrorDataType, NoCopilotProviderAvailableDataType, CopilotFailedToGenerateEmbeddingDataType, CopilotDocNotFoundDataType, CopilotMessageNotFoundDataType, CopilotPromptNotFoundDataType, CopilotProviderNotSupportedDataType, CopilotProviderSideErrorDataType, CopilotInvalidContextDataType, CopilotContextFileNotSupportedDataType, CopilotFailedToModifyContextDataType, CopilotFailedToMatchContextDataType, CopilotFailedToMatchGlobalContextDataType, CopilotFailedToAddWorkspaceFileEmbeddingDataType, RuntimeConfigNotFoundDataType, InvalidRuntimeConfigTypeDataType, InvalidLicenseToActivateDataType, InvalidLicenseUpdateParamsDataType, UnsupportedClientVersionDataType, UnsupportedServerVersionDataType, MentionUserDocAccessDeniedDataType, InvalidAppConfigDataType, InvalidAppConfigInputDataType, InvalidSearchProviderRequestDataType, InvalidIndexerInputDataType] as const,
|
||||
[GraphqlBadRequestDataType, HttpRequestErrorDataType, SsrfBlockedErrorDataType, ResponseTooLargeErrorDataType, ImageFormatNotSupportedDataType, QueryTooLongDataType, ValidationErrorDataType, WrongSignInCredentialsDataType, UnknownOauthProviderDataType, InvalidOauthCallbackCodeDataType, MissingOauthQueryParameterDataType, InvalidOauthResponseDataType, InvalidEmailDataType, InvalidPasswordLengthDataType, WorkspacePermissionNotFoundDataType, SpaceNotFoundDataType, MemberNotFoundInSpaceDataType, NotInSpaceDataType, AlreadyInSpaceDataType, SpaceAccessDeniedDataType, SpaceOwnerNotFoundDataType, SpaceShouldHaveOnlyOneOwnerDataType, DocNotFoundDataType, DocActionDeniedDataType, DocUpdateBlockedDataType, VersionRejectedDataType, InvalidHistoryTimestampDataType, DocHistoryNotFoundDataType, BlobNotFoundDataType, ExpectToGrantDocUserRolesDataType, ExpectToRevokeDocUserRolesDataType, ExpectToUpdateDocUserRoleDataType, NoMoreSeatDataType, UnsupportedSubscriptionPlanDataType, SubscriptionAlreadyExistsDataType, SubscriptionNotExistsDataType, SameSubscriptionRecurringDataType, SubscriptionPlanNotFoundDataType, CalendarProviderRequestErrorDataType, NoCopilotProviderAvailableDataType, CopilotFailedToGenerateEmbeddingDataType, CopilotDocNotFoundDataType, CopilotMessageNotFoundDataType, CopilotPromptNotFoundDataType, CopilotProviderNotSupportedDataType, CopilotProviderSideErrorDataType, CopilotFailedToAddWorkspaceArtifactDataType, RuntimeConfigNotFoundDataType, InvalidRuntimeConfigTypeDataType, InvalidLicenseToActivateDataType, InvalidLicenseUpdateParamsDataType, UnsupportedClientVersionDataType, UnsupportedServerVersionDataType, MentionUserDocAccessDeniedDataType, InvalidAppConfigDataType, InvalidAppConfigInputDataType, InvalidSearchProviderRequestDataType, InvalidIndexerInputDataType] as const,
|
||||
});
|
||||
|
||||
@@ -10,7 +10,9 @@ export {
|
||||
Config,
|
||||
ConfigFactory,
|
||||
defineModuleConfig,
|
||||
defineNativeModuleConfig,
|
||||
type JSONSchema,
|
||||
type NativeAppConfigDescriptor,
|
||||
} from './config';
|
||||
export * from './cors';
|
||||
export * from './error';
|
||||
|
||||
Reference in New Issue
Block a user