• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 20722720404

05 Jan 2026 04:56PM UTC coverage: 72.047% (+0.08%) from 71.967%
20722720404

push

github

web-flow
[sync] perf(t1554): template image need crop (#978) T1561 (#2391)

* [sync] perf: template image need crop (#978)

Synced from teableio/teable-ee@2230d00

* fix: t1494 keep filter input stable for lookup filters

---------

Co-authored-by: teable-bot <bot@teable.io>
Co-authored-by: nichenqin <nichenqin@hotmail.com>

24547 of 27432 branches covered (89.48%)

78 of 383 new or added lines in 8 files covered. (20.37%)

1 existing line in 1 file now uncovered.

60743 of 84310 relevant lines covered (72.05%)

4538.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

24.04
/apps/nestjs-backend/src/features/setting/open-api/setting-open-api.controller.ts
1
/* eslint-disable sonarjs/no-duplicate-string */
8✔
2
import {
3
  BadRequestException,
4
  Body,
5
  Controller,
6
  Get,
7
  Patch,
8
  Post,
9
  Put,
10
  UploadedFile,
11
  UseInterceptors,
12
} from '@nestjs/common';
13
import { FileInterceptor } from '@nestjs/platform-express';
14
import type {
15
  IPublicSettingVo,
16
  ISetSettingMailTransportConfigVo,
17
  ISettingVo,
18
  ITestLLMVo,
19
  IUploadLogoVo,
20
  IBatchTestLLMVo,
21
} from '@teable/openapi';
22
import {
23
  IUpdateSettingRo,
24
  testLLMRoSchema,
25
  updateSettingRoSchema,
26
  ITestLLMRo,
27
  setSettingMailTransportConfigRoSchema,
28
  ISetSettingMailTransportConfigRo,
29
  SettingKey,
30
  batchTestLLMRoSchema,
31
  IBatchTestLLMRo,
32
} from '@teable/openapi';
33
import { IThresholdConfig, ThresholdConfig } from '../../../configs/threshold.config';
34
import { ZodValidationPipe } from '../../../zod.validation.pipe';
35
import { Permissions } from '../../auth/decorators/permissions.decorator';
36
import { Public } from '../../auth/decorators/public.decorator';
37
import { TurnstileService } from '../../auth/turnstile/turnstile.service';
38
import { SettingOpenApiService } from './setting-open-api.service';
39

40
@Controller('api/admin/setting')
41
export class SettingOpenApiController {
8✔
42
  constructor(
316✔
43
    private readonly settingOpenApiService: SettingOpenApiService,
316✔
44
    private readonly turnstileService: TurnstileService,
316✔
45
    @ThresholdConfig() private readonly thresholdConfig: IThresholdConfig
316✔
46
  ) {}
316✔
47

48
  /**
316✔
49
   * Get the instance settings, now we have config for AI, there are some sensitive fields, we need check the permission before return.
50
   */
316✔
51
  @Permissions('instance|read')
316✔
52
  @Get()
53
  async getSetting(): Promise<ISettingVo> {
×
54
    return await this.settingOpenApiService.getSetting();
×
55
  }
×
56

57
  /**
316✔
58
   * Public endpoint for getting public settings without authentication
59
   */
316✔
60
  @Public()
316✔
61
  @Get('public')
62
  async getPublicSetting(): Promise<IPublicSettingVo> {
×
63
    const setting = await this.settingOpenApiService.getSetting([
×
64
      SettingKey.INSTANCE_ID,
×
65
      SettingKey.BRAND_NAME,
×
66
      SettingKey.BRAND_LOGO,
×
67
      SettingKey.DISALLOW_SIGN_UP,
×
68
      SettingKey.DISALLOW_SPACE_CREATION,
×
69
      SettingKey.DISALLOW_SPACE_INVITATION,
×
70
      SettingKey.DISALLOW_DASHBOARD,
×
71
      SettingKey.ENABLE_EMAIL_VERIFICATION,
×
72
      SettingKey.ENABLE_WAITLIST,
×
73
      SettingKey.AI_CONFIG,
×
74
      SettingKey.APP_CONFIG,
×
75
      SettingKey.WEB_SEARCH_CONFIG,
×
76
    ]);
×
77
    const { aiConfig, appConfig, webSearchConfig, ...rest } = setting;
×
78
    return {
×
79
      ...rest,
×
80
      aiConfig: {
×
81
        enable: aiConfig?.enable ?? false,
×
82
        llmProviders:
×
83
          aiConfig?.llmProviders?.map((provider) => ({
×
84
            type: provider.type,
×
85
            name: provider.name,
×
86
            models: provider.models,
×
87
          })) ?? [],
×
88
        chatModel: aiConfig?.chatModel,
×
89
        capabilities: aiConfig?.capabilities,
×
90
      },
×
91
      appGenerationEnabled: Boolean(appConfig?.apiKey),
×
92
      webSearchEnabled: Boolean(webSearchConfig?.apiKey),
×
93
      turnstileSiteKey: this.turnstileService.getTurnstileSiteKey(),
×
94
      changeEmailSendCodeMailRate: this.thresholdConfig.changeEmailSendCodeMailRate,
×
95
      resetPasswordSendMailRate: this.thresholdConfig.resetPasswordSendMailRate,
×
96
      signupVerificationSendCodeMailRate: this.thresholdConfig.signupVerificationSendCodeMailRate,
×
97
    };
×
98
  }
×
99

100
  @Patch()
316✔
101
  @Permissions('instance|update')
102
  async updateSetting(
1✔
103
    @Body(new ZodValidationPipe(updateSettingRoSchema))
1✔
104
    updateSettingRo: IUpdateSettingRo
1✔
105
  ): Promise<ISettingVo> {
1✔
106
    return await this.settingOpenApiService.updateSetting(updateSettingRo);
1✔
107
  }
1✔
108

109
  @UseInterceptors(
316✔
110
    FileInterceptor('file', {
111
      fileFilter: (_req, file, callback) => {
×
112
        if (file.mimetype.startsWith('image/')) {
×
113
          callback(null, true);
×
114
        } else {
×
115
          callback(new BadRequestException('Invalid file type'), false);
×
116
        }
×
117
      },
×
118
      limits: {
×
119
        fileSize: 500 * 1024, // limit file size is 500KB
×
120
      },
×
121
    })
122
  )
123
  @Patch('logo')
124
  @Permissions('instance|update')
125
  async uploadLogo(@UploadedFile() file: Express.Multer.File): Promise<IUploadLogoVo> {
×
126
    return this.settingOpenApiService.uploadLogo(file);
×
127
  }
×
128

129
  @Permissions('instance|update')
316✔
130
  @Post('test-llm')
131
  async testLLM(
×
132
    @Body(new ZodValidationPipe(testLLMRoSchema)) testLLMRo: ITestLLMRo
×
133
  ): Promise<ITestLLMVo> {
×
134
    return await this.settingOpenApiService.testLLM(testLLMRo);
×
135
  }
×
136

137
  @Permissions('instance|update')
316✔
138
  @Post('batch-test-llm')
NEW
139
  async batchTestLLM(
×
NEW
140
    @Body(new ZodValidationPipe(batchTestLLMRoSchema.optional())) batchTestLLMRo?: IBatchTestLLMRo
×
NEW
141
  ): Promise<IBatchTestLLMVo> {
×
NEW
142
    return await this.settingOpenApiService.batchTestLLM(batchTestLLMRo);
×
NEW
143
  }
×
144

145
  @Permissions('instance|update')
316✔
146
  @Put('set-mail-transport-config')
147
  async setMailTransportConfig(
×
148
    @Body(new ZodValidationPipe(setSettingMailTransportConfigRoSchema))
×
149
    setMailTransportConfigRo: ISetSettingMailTransportConfigRo
×
150
  ): Promise<ISetSettingMailTransportConfigVo> {
×
151
    await this.settingOpenApiService.setMailTransportConfig(setMailTransportConfigRo);
×
152

153
    return {
×
154
      ...setMailTransportConfigRo,
×
155
      transportConfig: {
×
156
        ...setMailTransportConfigRo.transportConfig,
×
157
        auth: {
×
158
          user: setMailTransportConfigRo.transportConfig.auth.user,
×
159
          pass: '',
×
160
        },
×
161
      },
×
162
    };
×
163
  }
×
164
}
316✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc