Full Code of teableio/teable for AI

develop 2435261ac131 cached
6559 files
34.9 MB
4.4M tokens
9517 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (17,330K chars total). Download the full file to get everything.
Repository: teableio/teable
Branch: develop
Commit: 2435261ac131
Files: 6559
Total size: 34.9 MB

Directory structure:
gitextract_74g3z0fs/

├── .codeclimate.yml
├── .dockerignore
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── actions/
│   │   ├── docker-build-push/
│   │   │   └── action.yml
│   │   └── pnpm-install/
│   │       └── action.yml
│   └── workflows/
│       ├── docker-push.yml
│       ├── integration-tests.yml
│       ├── issue-id-check.yml
│       ├── linting.yml
│       ├── manual-preview.yml
│       ├── preview-cleanup.yml
│       ├── templates/
│       │   └── preview-template.yaml
│       ├── trigger-sync-to-ee.yml
│       ├── unit-tests.yml
│       ├── v2-benchmark-tests.yml
│       └── v2-core-tests.yml
├── .gitignore
├── .gitpod.yml
├── .husky/
│   ├── commit-msg
│   ├── install.mjs
│   └── pre-commit
├── .idea/
│   ├── modules.xml
│   └── teable.iml
├── .ncurc.yml
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── .vscode/
│   ├── extensions.json
│   ├── launch.json
│   └── settings.json
├── AGPL_LICENSE
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── agents.md
├── apps/
│   ├── nestjs-backend/
│   │   ├── .eslintrc.js
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── nestjs-backend.iml
│   │   ├── README.md
│   │   ├── nest-cli.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── app.module.ts
│   │   │   ├── bootstrap.ts
│   │   │   ├── cache/
│   │   │   │   ├── cache.module.ts
│   │   │   │   ├── cache.provider.ts
│   │   │   │   ├── cache.service.ts
│   │   │   │   └── types.ts
│   │   │   ├── configs/
│   │   │   │   ├── auth.config.ts
│   │   │   │   ├── base.config.ts
│   │   │   │   ├── bootstrap.config.ts
│   │   │   │   ├── cache.config.ts
│   │   │   │   ├── config.module.ts
│   │   │   │   ├── config.spec.ts
│   │   │   │   ├── env.validation.schema.ts
│   │   │   │   ├── logger.config.ts
│   │   │   │   ├── mail.config.ts
│   │   │   │   ├── oauth.config.ts
│   │   │   │   ├── storage.ts
│   │   │   │   ├── threshold.config.ts
│   │   │   │   └── trash.config.ts
│   │   │   ├── const.ts
│   │   │   ├── custom.exception.ts
│   │   │   ├── db-provider/
│   │   │   │   ├── aggregation-query/
│   │   │   │   │   ├── aggregation-function.abstract.ts
│   │   │   │   │   ├── aggregation-function.interface.ts
│   │   │   │   │   ├── aggregation-query.abstract.ts
│   │   │   │   │   ├── aggregation-query.interface.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── multiple-value-aggregation.adapter.spec.ts
│   │   │   │   │   │   ├── aggregation-function.postgres.ts
│   │   │   │   │   │   ├── aggregation-query.postgres.ts
│   │   │   │   │   │   ├── multiple-value/
│   │   │   │   │   │   │   └── multiple-value-aggregation.adapter.ts
│   │   │   │   │   │   └── single-value/
│   │   │   │   │   │       └── single-value-aggregation.adapter.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── aggregation-function.sqlite.ts
│   │   │   │   │       ├── aggregation-query.sqlite.ts
│   │   │   │   │       ├── multiple-value/
│   │   │   │   │       │   └── multiple-value-aggregation.adapter.ts
│   │   │   │   │       └── single-value/
│   │   │   │   │           └── single-value-aggregation.adapter.ts
│   │   │   │   ├── base-query/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── base-query.postgres.ts
│   │   │   │   │   └── base-query.sqlite.ts
│   │   │   │   ├── create-database-column-query/
│   │   │   │   │   ├── create-database-column-field-visitor.interface.ts
│   │   │   │   │   ├── create-database-column-field-visitor.postgres.ts
│   │   │   │   │   ├── create-database-column-field-visitor.sqlite.ts
│   │   │   │   │   ├── create-database-column-field.util.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── db.provider.interface.ts
│   │   │   │   ├── db.provider.ts
│   │   │   │   ├── drop-database-column-query/
│   │   │   │   │   ├── drop-database-column-field-visitor.interface.ts
│   │   │   │   │   ├── drop-database-column-field-visitor.postgres.ts
│   │   │   │   │   ├── drop-database-column-field-visitor.sqlite.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── duplicate-table/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── duplicate-attachment-table-query.abstract.ts
│   │   │   │   │   ├── duplicate-attachment-table-query.postgres.ts
│   │   │   │   │   ├── duplicate-attachment-table-query.sqlite.ts
│   │   │   │   │   ├── duplicate-query.postgres.ts
│   │   │   │   │   └── duplicate-query.sqlite.ts
│   │   │   │   ├── filter-query/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── field-reference.spec.ts
│   │   │   │   │   ├── cell-value-filter.abstract.ts
│   │   │   │   │   ├── cell-value-filter.interface.ts
│   │   │   │   │   ├── filter-query.abstract.ts
│   │   │   │   │   ├── filter-query.interface.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── cell-value-filter/
│   │   │   │   │   │   │   ├── cell-value-filter.postgres.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── multiple-value/
│   │   │   │   │   │   │   │   ├── multiple-boolean-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   ├── multiple-datetime-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   ├── multiple-json-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   ├── multiple-number-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   └── multiple-string-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   └── single-value/
│   │   │   │   │   │   │       ├── boolean-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       ├── datetime-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       ├── json-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       ├── number-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       └── string-cell-value-filter.adapter.ts
│   │   │   │   │   │   └── filter-query.postgres.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── cell-value-filter/
│   │   │   │   │       │   ├── cell-value-filter.sqlite.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── multiple-value/
│   │   │   │   │       │   │   ├── multiple-boolean-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   ├── multiple-datetime-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   ├── multiple-json-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   ├── multiple-number-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   └── multiple-string-cell-value-filter.adapter.ts
│   │   │   │   │       │   └── single-value/
│   │   │   │   │       │       ├── boolean-cell-value-filter.adapter.ts
│   │   │   │   │       │       ├── datetime-cell-value-filter.adapter.ts
│   │   │   │   │       │       ├── json-cell-value-filter.adapter.ts
│   │   │   │   │       │       ├── number-cell-value-filter.adapter.ts
│   │   │   │   │       │       └── string-cell-value-filter.adapter.ts
│   │   │   │   │       └── filter-query.sqlite.ts
│   │   │   │   ├── generated-column-query/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   ├── formula-query.spec.ts.snap
│   │   │   │   │   │   ├── generated-column-query.spec.ts.snap
│   │   │   │   │   │   └── sql-conversion.spec.ts.snap
│   │   │   │   │   ├── generated-column-query-support-validator.spec.ts
│   │   │   │   │   ├── generated-column-query.abstract.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── generated-column-query-support-validator.postgres.ts
│   │   │   │   │   │   ├── generated-column-query.postgres.spec.ts
│   │   │   │   │   │   └── generated-column-query.postgres.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── generated-column-query-support-validator.sqlite.ts
│   │   │   │   │       ├── generated-column-query.sqlite.spec.ts
│   │   │   │   │       └── generated-column-query.sqlite.ts
│   │   │   │   ├── group-query/
│   │   │   │   │   ├── format-string.ts
│   │   │   │   │   ├── group-query.abstract.ts
│   │   │   │   │   ├── group-query.interface.ts
│   │   │   │   │   ├── group-query.postgres.ts
│   │   │   │   │   └── group-query.sqlite.ts
│   │   │   │   ├── index-query/
│   │   │   │   │   └── index-abstract-builder.ts
│   │   │   │   ├── integrity-query/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── integrity-query.postgres.ts
│   │   │   │   │   └── integrity-query.sqlite.ts
│   │   │   │   ├── postgres.provider.ts
│   │   │   │   ├── search-query/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── get-offset.ts
│   │   │   │   │   ├── search-index-builder.postgres.ts
│   │   │   │   │   ├── search-index-builder.sqlite.ts
│   │   │   │   │   ├── search-query.postgres.ts
│   │   │   │   │   ├── search-query.sqlite.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── select-query/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── select-query.postgres.spec.ts
│   │   │   │   │   │   └── select-query.postgres.ts
│   │   │   │   │   ├── select-query.abstract.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── select-query.sqlite.spec.ts
│   │   │   │   │       └── select-query.sqlite.ts
│   │   │   │   ├── sort-query/
│   │   │   │   │   ├── function/
│   │   │   │   │   │   ├── sort-function.abstract.ts
│   │   │   │   │   │   └── sort-function.interface.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── multiple-value/
│   │   │   │   │   │   │   ├── multiple-datetime-sort.adapter.ts
│   │   │   │   │   │   │   ├── multiple-json-sort.adapter.ts
│   │   │   │   │   │   │   └── multiple-number-sort.adapter.ts
│   │   │   │   │   │   ├── single-value/
│   │   │   │   │   │   │   ├── date-sort.adapter.ts
│   │   │   │   │   │   │   ├── json-sort.adapter.ts
│   │   │   │   │   │   │   └── string-sort.adapter.ts
│   │   │   │   │   │   ├── sort-query.function.ts
│   │   │   │   │   │   └── sort-query.postgres.ts
│   │   │   │   │   ├── sort-query.abstract.ts
│   │   │   │   │   ├── sort-query.interface.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── multiple-value/
│   │   │   │   │       │   ├── multiple-datetime-sort.adapter.ts
│   │   │   │   │       │   ├── multiple-json-sort.adapter.ts
│   │   │   │   │       │   └── multiple-number-sort.adapter.ts
│   │   │   │   │       ├── single-value/
│   │   │   │   │       │   ├── date-sort.adapter.ts
│   │   │   │   │       │   ├── json-sort.adapter.ts
│   │   │   │   │       │   └── string-sort.adapter.ts
│   │   │   │   │       ├── sort-query.function.ts
│   │   │   │   │       └── sort-query.sqlite.ts
│   │   │   │   ├── sqlite.provider.ts
│   │   │   │   └── utils/
│   │   │   │       ├── datetime-format.util.ts
│   │   │   │       ├── default-datetime-parse-pattern.spec.ts
│   │   │   │       ├── default-datetime-parse-pattern.ts
│   │   │   │       └── formula-param-metadata.util.ts
│   │   │   ├── event-emitter/
│   │   │   │   ├── decorators/
│   │   │   │   │   └── emit-controller-event.decorator.ts
│   │   │   │   ├── event-emitter.module.ts
│   │   │   │   ├── event-emitter.service.ts
│   │   │   │   ├── event-job/
│   │   │   │   │   ├── event-job.module.ts
│   │   │   │   │   └── fallback/
│   │   │   │   │       ├── event-emitter.ts
│   │   │   │   │       ├── fallback-queue.module.ts
│   │   │   │   │       ├── fallback-queue.service.ts
│   │   │   │   │       └── local-queue.provider.ts
│   │   │   │   ├── events/
│   │   │   │   │   ├── app/
│   │   │   │   │   │   └── app.event.ts
│   │   │   │   │   ├── base/
│   │   │   │   │   │   ├── base-node.event.ts
│   │   │   │   │   │   ├── base.event.ts
│   │   │   │   │   │   └── folder/
│   │   │   │   │   │       └── base.folder.event.ts
│   │   │   │   │   ├── core-event.ts
│   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   └── dashboard.event.ts
│   │   │   │   │   ├── event.enum.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── last-visit/
│   │   │   │   │   │   └── last-visit.event.ts
│   │   │   │   │   ├── op-event.ts
│   │   │   │   │   ├── space/
│   │   │   │   │   │   ├── collaborator.event.ts
│   │   │   │   │   │   └── space.event.ts
│   │   │   │   │   ├── table/
│   │   │   │   │   │   ├── button.event.ts
│   │   │   │   │   │   ├── field.event.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── record.event.ts
│   │   │   │   │   │   ├── table.event.ts
│   │   │   │   │   │   └── view.event.ts
│   │   │   │   │   ├── user/
│   │   │   │   │   │   └── user.event.ts
│   │   │   │   │   └── workflow/
│   │   │   │   │       └── workflow.event.ts
│   │   │   │   ├── interceptor/
│   │   │   │   │   └── event.Interceptor.ts
│   │   │   │   └── listeners/
│   │   │   │       ├── action-trigger.listener.ts
│   │   │   │       ├── attachment.listener.ts
│   │   │   │       ├── base-permission-update.listener.ts
│   │   │   │       ├── collaborator-notification.listener.ts
│   │   │   │       ├── pin.listener.ts
│   │   │   │       ├── record-history.listener.ts
│   │   │   │       └── trash.listener.ts
│   │   │   ├── features/
│   │   │   │   ├── access-token/
│   │   │   │   │   ├── access-token.controller.spec.ts
│   │   │   │   │   ├── access-token.controller.ts
│   │   │   │   │   ├── access-token.encryptor.ts
│   │   │   │   │   ├── access-token.module.ts
│   │   │   │   │   ├── access-token.service.spec.ts
│   │   │   │   │   └── access-token.service.ts
│   │   │   │   ├── aggregation/
│   │   │   │   │   ├── aggregation.module.ts
│   │   │   │   │   ├── aggregation.service.interface.ts
│   │   │   │   │   ├── aggregation.service.provider.ts
│   │   │   │   │   ├── aggregation.service.spec.ts
│   │   │   │   │   ├── aggregation.service.symbol.ts
│   │   │   │   │   ├── aggregation.service.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── open-api/
│   │   │   │   │       ├── aggregation-open-api.controller.spec.ts
│   │   │   │   │       ├── aggregation-open-api.controller.ts
│   │   │   │   │       ├── aggregation-open-api.module.ts
│   │   │   │   │       ├── aggregation-open-api.service.spec.ts
│   │   │   │   │       └── aggregation-open-api.service.ts
│   │   │   │   ├── ai/
│   │   │   │   │   ├── ai.controller.ts
│   │   │   │   │   ├── ai.module.ts
│   │   │   │   │   ├── ai.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   └── util.ts
│   │   │   │   ├── attachments/
│   │   │   │   │   ├── attachments-crop.module.ts
│   │   │   │   │   ├── attachments-crop.processor.ts
│   │   │   │   │   ├── attachments-storage.module.ts
│   │   │   │   │   ├── attachments-storage.service.ts
│   │   │   │   │   ├── attachments-table.module.ts
│   │   │   │   │   ├── attachments-table.service.spec.ts
│   │   │   │   │   ├── attachments-table.service.ts
│   │   │   │   │   ├── attachments.controller.spec.ts
│   │   │   │   │   ├── attachments.controller.ts
│   │   │   │   │   ├── attachments.module.ts
│   │   │   │   │   ├── attachments.service.spec.ts
│   │   │   │   │   ├── attachments.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   └── auth.guard.ts
│   │   │   │   │   ├── plugins/
│   │   │   │   │   │   ├── adapter.ts
│   │   │   │   │   │   ├── aliyun.ts
│   │   │   │   │   │   ├── local.spec.ts
│   │   │   │   │   │   ├── local.ts
│   │   │   │   │   │   ├── minio.ts
│   │   │   │   │   │   ├── s3.ts
│   │   │   │   │   │   ├── storage.module.ts
│   │   │   │   │   │   ├── storage.ts
│   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── auth/
│   │   │   │   │   ├── auth.controller.spec.ts
│   │   │   │   │   ├── auth.controller.ts
│   │   │   │   │   ├── auth.module.ts
│   │   │   │   │   ├── auth.service.spec.ts
│   │   │   │   │   ├── auth.service.ts
│   │   │   │   │   ├── decorators/
│   │   │   │   │   │   ├── allow-anonymous.decorator.ts
│   │   │   │   │   │   ├── base-node-permissions.decorator.ts
│   │   │   │   │   │   ├── disabled-permission.decorator.ts
│   │   │   │   │   │   ├── ensure-login.decorator.ts
│   │   │   │   │   │   ├── permissions.decorator.ts
│   │   │   │   │   │   ├── public.decorator.ts
│   │   │   │   │   │   ├── resource_meta.decorator.ts
│   │   │   │   │   │   └── token.decorator.ts
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   ├── auth.guard.ts
│   │   │   │   │   │   ├── base-node-permission.guard.ts
│   │   │   │   │   │   ├── github.guard.ts
│   │   │   │   │   │   ├── google.guard.ts
│   │   │   │   │   │   ├── local-auth.guard.ts
│   │   │   │   │   │   ├── oidc.guard.ts
│   │   │   │   │   │   ├── permission.guard.ts
│   │   │   │   │   │   └── social.guard.ts
│   │   │   │   │   ├── local-auth/
│   │   │   │   │   │   ├── local-auth.controller.ts
│   │   │   │   │   │   ├── local-auth.module.ts
│   │   │   │   │   │   └── local-auth.service.ts
│   │   │   │   │   ├── oauth/
│   │   │   │   │   │   └── oauth.store.ts
│   │   │   │   │   ├── permission.module.ts
│   │   │   │   │   ├── permission.service.spec.ts
│   │   │   │   │   ├── permission.service.ts
│   │   │   │   │   ├── session/
│   │   │   │   │   │   ├── session-handle.module.ts
│   │   │   │   │   │   ├── session-handle.service.ts
│   │   │   │   │   │   ├── session-store.service.spec.ts
│   │   │   │   │   │   ├── session-store.service.ts
│   │   │   │   │   │   ├── session.module.ts
│   │   │   │   │   │   ├── session.serializer.ts
│   │   │   │   │   │   └── session.service.ts
│   │   │   │   │   ├── social/
│   │   │   │   │   │   ├── controller.adapter.ts
│   │   │   │   │   │   ├── github/
│   │   │   │   │   │   │   ├── github.controller.ts
│   │   │   │   │   │   │   └── github.module.ts
│   │   │   │   │   │   ├── google/
│   │   │   │   │   │   │   ├── google.controller.ts
│   │   │   │   │   │   │   └── google.module.ts
│   │   │   │   │   │   ├── oidc/
│   │   │   │   │   │   │   ├── oidc.controller.ts
│   │   │   │   │   │   │   └── oidc.module.ts
│   │   │   │   │   │   └── social.module.ts
│   │   │   │   │   ├── strategies/
│   │   │   │   │   │   ├── access-token.passport.ts
│   │   │   │   │   │   ├── access-token.strategy.ts
│   │   │   │   │   │   ├── anonymous/
│   │   │   │   │   │   │   ├── anonymous.passport.ts
│   │   │   │   │   │   │   └── anonymous.strategy.ts
│   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   ├── github.strategy.ts
│   │   │   │   │   │   ├── google.strategy.ts
│   │   │   │   │   │   ├── jwt.strategy.ts
│   │   │   │   │   │   ├── local.strategy.spec.ts
│   │   │   │   │   │   ├── local.strategy.ts
│   │   │   │   │   │   ├── oidc.strategy.ts
│   │   │   │   │   │   ├── session.passport.ts
│   │   │   │   │   │   ├── session.strategy.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── turnstile/
│   │   │   │   │   │   ├── turnstile.module.ts
│   │   │   │   │   │   └── turnstile.service.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── base/
│   │   │   │   │   ├── BatchProcessor.class.ts
│   │   │   │   │   ├── base-duplicate.service.spec.ts
│   │   │   │   │   ├── base-duplicate.service.ts
│   │   │   │   │   ├── base-export.service.ts
│   │   │   │   │   ├── base-import-processor/
│   │   │   │   │   │   ├── base-import-attachments-csv.module.ts
│   │   │   │   │   │   ├── base-import-attachments-csv.processor.ts
│   │   │   │   │   │   ├── base-import-attachments.module.ts
│   │   │   │   │   │   ├── base-import-attachments.processor.ts
│   │   │   │   │   │   ├── base-import-csv.module.ts
│   │   │   │   │   │   ├── base-import-csv.processor.ts
│   │   │   │   │   │   ├── base-import-junction-csv.module.ts
│   │   │   │   │   │   └── base-import-junction.processor.ts
│   │   │   │   │   ├── base-import.service.ts
│   │   │   │   │   ├── base-query/
│   │   │   │   │   │   ├── base-query.service.ts
│   │   │   │   │   │   └── parse/
│   │   │   │   │   │       ├── aggregation.ts
│   │   │   │   │   │       ├── filter.ts
│   │   │   │   │   │       ├── group.ts
│   │   │   │   │   │       ├── order.ts
│   │   │   │   │   │       ├── select.ts
│   │   │   │   │   │       └── utils.ts
│   │   │   │   │   ├── base.controller.ts
│   │   │   │   │   ├── base.module.ts
│   │   │   │   │   ├── base.service.spec.ts
│   │   │   │   │   ├── base.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── db-connection.service.spec.ts
│   │   │   │   │   ├── db-connection.service.ts
│   │   │   │   │   ├── utils.spec.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── base-node/
│   │   │   │   │   ├── base-node.controller.ts
│   │   │   │   │   ├── base-node.listener.ts
│   │   │   │   │   ├── base-node.module.ts
│   │   │   │   │   ├── base-node.permission.helper.ts
│   │   │   │   │   ├── base-node.service.spec.ts
│   │   │   │   │   ├── base-node.service.ts
│   │   │   │   │   ├── folder/
│   │   │   │   │   │   ├── base-node-folder.controller.ts
│   │   │   │   │   │   ├── base-node-folder.module.ts
│   │   │   │   │   │   └── base-node-folder.service.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── base-share/
│   │   │   │   │   ├── base-share-auth.service.ts
│   │   │   │   │   ├── base-share-open.controller.ts
│   │   │   │   │   ├── base-share.controller.ts
│   │   │   │   │   ├── base-share.module.ts
│   │   │   │   │   ├── base-share.service.ts
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   ├── base-share-auth-local.guard.ts
│   │   │   │   │   │   ├── base-share-auth.guard.ts
│   │   │   │   │   │   └── constant.ts
│   │   │   │   │   └── strategies/
│   │   │   │   │       └── jwt.strategy.ts
│   │   │   │   ├── base-sql-executor/
│   │   │   │   │   ├── base-sql-executor.module.ts
│   │   │   │   │   ├── base-sql-executor.service.ts
│   │   │   │   │   ├── const.ts
│   │   │   │   │   ├── utils.spec.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── builtin-assets-init/
│   │   │   │   │   ├── builtin-assets-init.module.ts
│   │   │   │   │   ├── builtin-assets-init.service.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── calculation/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── batch.service.spec.ts
│   │   │   │   │   ├── batch.service.ts
│   │   │   │   │   ├── calculation.module.ts
│   │   │   │   │   ├── field-calculation.service.spec.ts
│   │   │   │   │   ├── field-calculation.service.ts
│   │   │   │   │   ├── link.service.spec.ts
│   │   │   │   │   ├── link.service.ts
│   │   │   │   │   ├── reference.service.ts
│   │   │   │   │   ├── system-field.service.ts
│   │   │   │   │   └── utils/
│   │   │   │   │       ├── changes.spec.ts
│   │   │   │   │       ├── changes.ts
│   │   │   │   │       ├── compose-maps.spec.ts
│   │   │   │   │       ├── compose-maps.ts
│   │   │   │   │       ├── detect-link.spec.ts
│   │   │   │   │       ├── detect-link.ts
│   │   │   │   │       ├── dfs.spec.ts
│   │   │   │   │       ├── dfs.ts
│   │   │   │   │       └── name-console.ts
│   │   │   │   ├── canary/
│   │   │   │   │   ├── canary.module.ts
│   │   │   │   │   ├── canary.service.ts
│   │   │   │   │   ├── decorators/
│   │   │   │   │   │   └── use-v2-feature.decorator.ts
│   │   │   │   │   ├── guards/
│   │   │   │   │   │   └── v2-feature.guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── interceptors/
│   │   │   │   │       └── v2-indicator.interceptor.ts
│   │   │   │   ├── chat/
│   │   │   │   │   ├── chart-completion.ro.ts
│   │   │   │   │   ├── chat.controller.spec.ts
│   │   │   │   │   ├── chat.controller.ts
│   │   │   │   │   ├── chat.module.ts
│   │   │   │   │   ├── chat.service.spec.ts
│   │   │   │   │   └── chat.service.ts
│   │   │   │   ├── collaborator/
│   │   │   │   │   ├── collaborator.controller.spec.ts
│   │   │   │   │   ├── collaborator.controller.ts
│   │   │   │   │   ├── collaborator.module.ts
│   │   │   │   │   ├── collaborator.service.spec.ts
│   │   │   │   │   └── collaborator.service.ts
│   │   │   │   ├── comment/
│   │   │   │   │   ├── comment-open-api.controller.spec.ts
│   │   │   │   │   ├── comment-open-api.controller.ts
│   │   │   │   │   ├── comment-open-api.module.ts
│   │   │   │   │   └── comment-open-api.service.ts
│   │   │   │   ├── dashboard/
│   │   │   │   │   ├── dashboard.controller.spec.ts
│   │   │   │   │   ├── dashboard.controller.ts
│   │   │   │   │   ├── dashboard.module.ts
│   │   │   │   │   ├── dashboard.service.spec.ts
│   │   │   │   │   └── dashboard.service.ts
│   │   │   │   ├── data-loader/
│   │   │   │   │   ├── data-loader.module.ts
│   │   │   │   │   ├── data-loader.service.ts
│   │   │   │   │   └── resource/
│   │   │   │   │       ├── field-loader.service.ts
│   │   │   │   │       ├── table-common-loader.ts
│   │   │   │   │       ├── table-loader.service.ts
│   │   │   │   │       ├── utils.ts
│   │   │   │   │       └── view-loader.service.ts
│   │   │   │   ├── database-view/
│   │   │   │   │   ├── database-view.interface.ts
│   │   │   │   │   ├── database-view.module.ts
│   │   │   │   │   └── database-view.service.ts
│   │   │   │   ├── export/
│   │   │   │   │   ├── metrics/
│   │   │   │   │   │   ├── export-metrics.module.ts
│   │   │   │   │   │   ├── export-metrics.service.ts
│   │   │   │   │   │   └── export-tracing.service.ts
│   │   │   │   │   └── open-api/
│   │   │   │   │       ├── export-open-api.controller.ts
│   │   │   │   │       ├── export-open-api.module.ts
│   │   │   │   │       └── export-open-api.service.ts
│   │   │   │   ├── field/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── field-calculate/
│   │   │   │   │   │   ├── field-calculate.module.ts
│   │   │   │   │   │   ├── field-converting-link.service.spec.ts
│   │   │   │   │   │   ├── field-converting-link.service.ts
│   │   │   │   │   │   ├── field-converting.service.spec.ts
│   │   │   │   │   │   ├── field-converting.service.ts
│   │   │   │   │   │   ├── field-creating.service.spec.ts
│   │   │   │   │   │   ├── field-creating.service.ts
│   │   │   │   │   │   ├── field-deleting.service.spec.ts
│   │   │   │   │   │   ├── field-deleting.service.ts
│   │   │   │   │   │   ├── field-supplement.service.ts
│   │   │   │   │   │   ├── field-view-sync.service.ts
│   │   │   │   │   │   ├── formula-field.service.spec.ts
│   │   │   │   │   │   ├── formula-field.service.ts
│   │   │   │   │   │   └── link-field-query.service.ts
│   │   │   │   │   ├── field-duplicate/
│   │   │   │   │   │   ├── field-duplicate.module.ts
│   │   │   │   │   │   └── field-duplicate.service.ts
│   │   │   │   │   ├── field.module.ts
│   │   │   │   │   ├── field.service.spec.ts
│   │   │   │   │   ├── field.service.ts
│   │   │   │   │   ├── fields-utils.ts
│   │   │   │   │   ├── model/
│   │   │   │   │   │   ├── factory.spec.ts
│   │   │   │   │   │   ├── factory.ts
│   │   │   │   │   │   ├── field-base.ts
│   │   │   │   │   │   └── field-dto/
│   │   │   │   │   │       ├── attachment-field.dto.ts
│   │   │   │   │   │       ├── auto-number-field.dto.ts
│   │   │   │   │   │       ├── button-field.dto.ts
│   │   │   │   │   │       ├── checkbox-field.dto.ts
│   │   │   │   │   │       ├── conditional-rollup-field.dto.ts
│   │   │   │   │   │       ├── created-by-field.dto.ts
│   │   │   │   │   │       ├── created-time-field.dto.ts
│   │   │   │   │   │       ├── date-field.dto.ts
│   │   │   │   │   │       ├── formula-field.dto.ts
│   │   │   │   │   │       ├── last-modified-by-field.dto.ts
│   │   │   │   │   │       ├── last-modified-time-field.dto.ts
│   │   │   │   │   │       ├── link-field.dto.ts
│   │   │   │   │   │       ├── long-text-field.dto.ts
│   │   │   │   │   │       ├── multiple-select-field.dto.ts
│   │   │   │   │   │       ├── number-field.dto.ts
│   │   │   │   │   │       ├── rating-field.dto.ts
│   │   │   │   │   │       ├── rollup-field.dto.ts
│   │   │   │   │   │       ├── single-line-text-field.dto.ts
│   │   │   │   │   │       ├── single-select-field.dto.ts
│   │   │   │   │   │       └── user-field.dto.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── field-open-api-v2.service.spec.ts
│   │   │   │   │   │   ├── field-open-api-v2.service.ts
│   │   │   │   │   │   ├── field-open-api.controller.ts
│   │   │   │   │   │   ├── field-open-api.module.ts
│   │   │   │   │   │   ├── field-open-api.service.spec.ts
│   │   │   │   │   │   └── field-open-api.service.ts
│   │   │   │   │   └── util.ts
│   │   │   │   ├── graph/
│   │   │   │   │   ├── graph.module.ts
│   │   │   │   │   ├── graph.service.spec.ts
│   │   │   │   │   └── graph.service.ts
│   │   │   │   ├── health/
│   │   │   │   │   ├── health.controller.spec.ts
│   │   │   │   │   ├── health.controller.ts
│   │   │   │   │   ├── health.module.ts
│   │   │   │   │   └── health.service.ts
│   │   │   │   ├── import/
│   │   │   │   │   ├── metrics/
│   │   │   │   │   │   ├── import-metrics.module.ts
│   │   │   │   │   │   ├── import-metrics.service.ts
│   │   │   │   │   │   └── import-tracing.service.ts
│   │   │   │   │   └── open-api/
│   │   │   │   │       ├── NOTICE.md
│   │   │   │   │       ├── delimiter-stream.ts
│   │   │   │   │       ├── import-csv-chunk.module.ts
│   │   │   │   │       ├── import-csv-chunk.processor.ts
│   │   │   │   │       ├── import-csv.module.ts
│   │   │   │   │       ├── import-csv.processor.ts
│   │   │   │   │       ├── import-error-classifier.ts
│   │   │   │   │       ├── import-error-collector.ts
│   │   │   │   │       ├── import-open-api-v2.service.ts
│   │   │   │   │       ├── import-open-api.controller.ts
│   │   │   │   │       ├── import-open-api.module.ts
│   │   │   │   │       ├── import-open-api.service.ts
│   │   │   │   │       ├── import-result-manifest.ts
│   │   │   │   │       ├── import-result.processor.ts
│   │   │   │   │       └── import.class.ts
│   │   │   │   ├── integrity/
│   │   │   │   │   ├── foreign-key.service.ts
│   │   │   │   │   ├── integrity.controller.ts
│   │   │   │   │   ├── integrity.module.ts
│   │   │   │   │   ├── link-field.service.ts
│   │   │   │   │   ├── link-integrity.service.ts
│   │   │   │   │   └── unique-index.service.ts
│   │   │   │   ├── invitation/
│   │   │   │   │   ├── invitation.controller.spec.ts
│   │   │   │   │   ├── invitation.controller.ts
│   │   │   │   │   ├── invitation.module.ts
│   │   │   │   │   ├── invitation.service.spec.ts
│   │   │   │   │   └── invitation.service.ts
│   │   │   │   ├── mail-sender/
│   │   │   │   │   ├── mail-helpers.ts
│   │   │   │   │   ├── mail-sender.module.ts
│   │   │   │   │   ├── mail-sender.service.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── mail-sender-open-api.controller.ts
│   │   │   │   │   │   ├── mail-sender-open-api.module.ts
│   │   │   │   │   │   ├── mail-sender-open-api.service.ts
│   │   │   │   │   │   ├── mail-sender.merge.module.ts
│   │   │   │   │   │   └── mail-sender.merge.processor.ts
│   │   │   │   │   └── templates/
│   │   │   │   │       ├── pages/
│   │   │   │   │       │   └── normal.hbs
│   │   │   │   │       └── partials/
│   │   │   │   │           ├── collaborator-cell-tag.hbs
│   │   │   │   │           ├── collaborator-multi-row-tag.hbs
│   │   │   │   │           ├── common-body.hbs
│   │   │   │   │           ├── email-verify-code.hbs
│   │   │   │   │           ├── footer.hbs
│   │   │   │   │           ├── header.hbs
│   │   │   │   │           ├── html-body.hbs
│   │   │   │   │           ├── invite.hbs
│   │   │   │   │           ├── notify-merge-body.hbs
│   │   │   │   │           └── reset-password.hbs
│   │   │   │   ├── model/
│   │   │   │   │   ├── access-token.ts
│   │   │   │   │   ├── collaborator.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── model.module.ts
│   │   │   │   │   ├── setting.ts
│   │   │   │   │   ├── template.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── next/
│   │   │   │   │   ├── next.controller.ts
│   │   │   │   │   ├── next.module.ts
│   │   │   │   │   ├── next.service.ts
│   │   │   │   │   └── plugin/
│   │   │   │   │       ├── plugin-proxy.middleware.ts
│   │   │   │   │       ├── plugin-proxy.module.ts
│   │   │   │   │       └── plugin.module.ts
│   │   │   │   ├── notification/
│   │   │   │   │   ├── notification.controller.ts
│   │   │   │   │   ├── notification.module.ts
│   │   │   │   │   └── notification.service.ts
│   │   │   │   ├── oauth/
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   └── oauth2-client.guard.ts
│   │   │   │   │   ├── oauth-server.controller.ts
│   │   │   │   │   ├── oauth-server.service.spec.ts
│   │   │   │   │   ├── oauth-server.service.ts
│   │   │   │   │   ├── oauth-tx-store.ts
│   │   │   │   │   ├── oauth.controller.spec.ts
│   │   │   │   │   ├── oauth.controller.ts
│   │   │   │   │   ├── oauth.module.ts
│   │   │   │   │   ├── oauth.service.spec.ts
│   │   │   │   │   ├── oauth.service.ts
│   │   │   │   │   ├── pkce.service.ts
│   │   │   │   │   ├── strategies/
│   │   │   │   │   │   ├── oauth2-client.strategies.ts
│   │   │   │   │   │   └── oauth2-pkce-client.strategy.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── organization/
│   │   │   │   │   ├── organization.controller.ts
│   │   │   │   │   └── organization.module.ts
│   │   │   │   ├── pin/
│   │   │   │   │   ├── pin.controller.ts
│   │   │   │   │   ├── pin.module.ts
│   │   │   │   │   └── pin.service.ts
│   │   │   │   ├── plugin/
│   │   │   │   │   ├── official/
│   │   │   │   │   │   ├── chart/
│   │   │   │   │   │   │   ├── plugin-chart.controller.ts
│   │   │   │   │   │   │   ├── plugin-chart.module.ts
│   │   │   │   │   │   │   └── plugin-chart.service.ts
│   │   │   │   │   │   ├── config/
│   │   │   │   │   │   │   ├── chart.ts
│   │   │   │   │   │   │   ├── sheet-form-view.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   └── official-plugin-init.service.ts
│   │   │   │   │   ├── plugin-auth.service.ts
│   │   │   │   │   ├── plugin.controller.spec.ts
│   │   │   │   │   ├── plugin.controller.ts
│   │   │   │   │   ├── plugin.module.ts
│   │   │   │   │   ├── plugin.service.spec.ts
│   │   │   │   │   ├── plugin.service.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── plugin-context-menu/
│   │   │   │   │   ├── plugin-context-menu.controller.ts
│   │   │   │   │   ├── plugin-context-menu.module.ts
│   │   │   │   │   └── plugin-context-menu.service.ts
│   │   │   │   ├── plugin-panel/
│   │   │   │   │   ├── plugin-panel.controller.ts
│   │   │   │   │   ├── plugin-panel.module.ts
│   │   │   │   │   └── plugin-panel.service.ts
│   │   │   │   ├── record/
│   │   │   │   │   ├── computed/
│   │   │   │   │   │   ├── computed.module.ts
│   │   │   │   │   │   └── services/
│   │   │   │   │   │       ├── computed-dependency-collector.service.ts
│   │   │   │   │   │       ├── computed-evaluator.service.ts
│   │   │   │   │   │       ├── computed-orchestrator.service.ts
│   │   │   │   │   │       ├── computed-pagination.strategy.ts
│   │   │   │   │   │       ├── computed-utils.ts
│   │   │   │   │   │       ├── link-cascade-resolver.ts
│   │   │   │   │   │       └── record-computed-update.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── field-key.pipe.ts
│   │   │   │   │   │   ├── record-open-api-v2.service.spec.ts
│   │   │   │   │   │   ├── record-open-api-v2.service.ts
│   │   │   │   │   │   ├── record-open-api.controller.ts
│   │   │   │   │   │   ├── record-open-api.module.ts
│   │   │   │   │   │   ├── record-open-api.service.spec.ts
│   │   │   │   │   │   ├── record-open-api.service.ts
│   │   │   │   │   │   ├── record-undo-redo-service.ts
│   │   │   │   │   │   └── tql.pipe.ts
│   │   │   │   │   ├── query-builder/
│   │   │   │   │   │   ├── field-cte-visitor.ts
│   │   │   │   │   │   ├── field-formatting-visitor.ts
│   │   │   │   │   │   ├── field-select-visitor.ts
│   │   │   │   │   │   ├── field-select.type.ts
│   │   │   │   │   │   ├── formula-support-generated-column-validator.spec.ts
│   │   │   │   │   │   ├── formula-support-generated-column-validator.ts
│   │   │   │   │   │   ├── formula-validation.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── providers/
│   │   │   │   │   │   │   ├── pg-record-query-dialect.spec.ts
│   │   │   │   │   │   │   ├── pg-record-query-dialect.ts
│   │   │   │   │   │   │   └── sqlite-record-query-dialect.ts
│   │   │   │   │   │   ├── record-query-builder.interface.ts
│   │   │   │   │   │   ├── record-query-builder.manager.ts
│   │   │   │   │   │   ├── record-query-builder.module.ts
│   │   │   │   │   │   ├── record-query-builder.provider.ts
│   │   │   │   │   │   ├── record-query-builder.service.ts
│   │   │   │   │   │   ├── record-query-builder.symbol.ts
│   │   │   │   │   │   ├── record-query-builder.util.ts
│   │   │   │   │   │   ├── record-query-dialect.interface.ts
│   │   │   │   │   │   └── sql-conversion.visitor.ts
│   │   │   │   │   ├── record-modify/
│   │   │   │   │   │   ├── record-create.service.ts
│   │   │   │   │   │   ├── record-delete.service.ts
│   │   │   │   │   │   ├── record-duplicate.service.ts
│   │   │   │   │   │   ├── record-modify.module.ts
│   │   │   │   │   │   ├── record-modify.service.ts
│   │   │   │   │   │   ├── record-modify.shared.service.ts
│   │   │   │   │   │   └── record-update.service.ts
│   │   │   │   │   ├── record-permission.service.ts
│   │   │   │   │   ├── record-query.service.ts
│   │   │   │   │   ├── record.module.ts
│   │   │   │   │   ├── record.service.spec.ts
│   │   │   │   │   ├── record.service.ts
│   │   │   │   │   ├── type.ts
│   │   │   │   │   ├── typecast.validate.spec.ts
│   │   │   │   │   ├── typecast.validate.ts
│   │   │   │   │   └── user-name.listener.service.ts
│   │   │   │   ├── selection/
│   │   │   │   │   ├── selection.controller.spec.ts
│   │   │   │   │   ├── selection.controller.ts
│   │   │   │   │   ├── selection.module.ts
│   │   │   │   │   ├── selection.service.spec.ts
│   │   │   │   │   └── selection.service.ts
│   │   │   │   ├── setting/
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── admin-open-api.controller.ts
│   │   │   │   │   │   ├── admin-open-api.module.ts
│   │   │   │   │   │   ├── admin-open-api.service.ts
│   │   │   │   │   │   ├── setting-open-api.controller.ts
│   │   │   │   │   │   ├── setting-open-api.module.ts
│   │   │   │   │   │   └── setting-open-api.service.ts
│   │   │   │   │   ├── setting.module.ts
│   │   │   │   │   └── setting.service.ts
│   │   │   │   ├── share/
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   ├── auth.guard.ts
│   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   ├── link-view.decorator.ts
│   │   │   │   │   │   ├── share-auth-local.guard.ts
│   │   │   │   │   │   └── submit.decorator.ts
│   │   │   │   │   ├── share-auth.module.ts
│   │   │   │   │   ├── share-auth.service.ts
│   │   │   │   │   ├── share-socket.service.ts
│   │   │   │   │   ├── share.controller.spec.ts
│   │   │   │   │   ├── share.controller.ts
│   │   │   │   │   ├── share.module.ts
│   │   │   │   │   ├── share.service.spec.ts
│   │   │   │   │   ├── share.service.ts
│   │   │   │   │   └── strategies/
│   │   │   │   │       └── jwt.strategy.ts
│   │   │   │   ├── space/
│   │   │   │   │   ├── space.controller.spec.ts
│   │   │   │   │   ├── space.controller.ts
│   │   │   │   │   ├── space.module.ts
│   │   │   │   │   ├── space.service.spec.ts
│   │   │   │   │   ├── space.service.ts
│   │   │   │   │   └── template-space-init/
│   │   │   │   │       └── template-space.init.service.ts
│   │   │   │   ├── table/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── table-open-api-v2.mapper.spec.ts
│   │   │   │   │   │   ├── table-open-api-v2.mapper.ts
│   │   │   │   │   │   ├── table-open-api-v2.service.spec.ts
│   │   │   │   │   │   ├── table-open-api-v2.service.ts
│   │   │   │   │   │   ├── table-open-api.controller.ts
│   │   │   │   │   │   ├── table-open-api.module.ts
│   │   │   │   │   │   ├── table-open-api.server.spec.ts
│   │   │   │   │   │   ├── table-open-api.service.spec.ts
│   │   │   │   │   │   ├── table-open-api.service.ts
│   │   │   │   │   │   ├── table.pipe.helper.ts
│   │   │   │   │   │   └── table.pipe.ts
│   │   │   │   │   ├── table-duplicate.service.ts
│   │   │   │   │   ├── table-index.service.ts
│   │   │   │   │   ├── table-permission.service.ts
│   │   │   │   │   ├── table.module.ts
│   │   │   │   │   ├── table.service.spec.ts
│   │   │   │   │   └── table.service.ts
│   │   │   │   ├── table-domain/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── table-domain-query.module.ts
│   │   │   │   │   └── table-domain-query.service.ts
│   │   │   │   ├── template/
│   │   │   │   │   ├── template-open-api.controller.spec.ts
│   │   │   │   │   ├── template-open-api.controller.ts
│   │   │   │   │   ├── template-open-api.module.ts
│   │   │   │   │   ├── template-open-api.service.ts
│   │   │   │   │   └── template-permalink.service.ts
│   │   │   │   ├── trash/
│   │   │   │   │   ├── listener/
│   │   │   │   │   │   └── table-trash.listener.ts
│   │   │   │   │   ├── trash.controller.ts
│   │   │   │   │   ├── trash.module.ts
│   │   │   │   │   ├── trash.service.ts
│   │   │   │   │   ├── v2-table-trash.service.spec.ts
│   │   │   │   │   ├── v2-table-trash.service.ts
│   │   │   │   │   └── v2-trash-record-name.ts
│   │   │   │   ├── undo-redo/
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── undo-redo.controller.ts
│   │   │   │   │   │   ├── undo-redo.module.ts
│   │   │   │   │   │   └── undo-redo.service.ts
│   │   │   │   │   ├── operations/
│   │   │   │   │   │   ├── convert-field-v2.operation.ts
│   │   │   │   │   │   ├── convert-field.operation.ts
│   │   │   │   │   │   ├── create-fields.operation.ts
│   │   │   │   │   │   ├── create-records.operation.ts
│   │   │   │   │   │   ├── create-view.operation.ts
│   │   │   │   │   │   ├── delete-fields.operation.ts
│   │   │   │   │   │   ├── delete-records.operation.ts
│   │   │   │   │   │   ├── delete-view.operation.ts
│   │   │   │   │   │   ├── paste-selection.operation.ts
│   │   │   │   │   │   ├── update-records-order.operation.ts
│   │   │   │   │   │   ├── update-records.operation.ts
│   │   │   │   │   │   └── update-view.operation.ts
│   │   │   │   │   └── stack/
│   │   │   │   │       ├── undo-redo-operation.service.ts
│   │   │   │   │       ├── undo-redo-stack.module.ts
│   │   │   │   │       └── undo-redo-stack.service.ts
│   │   │   │   ├── user/
│   │   │   │   │   ├── delete-user/
│   │   │   │   │   │   ├── delete-user.module.ts
│   │   │   │   │   │   └── delete-user.service.ts
│   │   │   │   │   ├── last-visit/
│   │   │   │   │   │   ├── last-visit.controller.ts
│   │   │   │   │   │   ├── last-visit.module.ts
│   │   │   │   │   │   └── last-visit.service.ts
│   │   │   │   │   ├── user.controller.spec.ts
│   │   │   │   │   ├── user.controller.ts
│   │   │   │   │   ├── user.module.ts
│   │   │   │   │   ├── user.service.spec.ts
│   │   │   │   │   └── user.service.ts
│   │   │   │   ├── v2/
│   │   │   │   │   ├── v2-action-trigger.service.spec.ts
│   │   │   │   │   ├── v2-action-trigger.service.ts
│   │   │   │   │   ├── v2-audit-log.constants.ts
│   │   │   │   │   ├── v2-command-bus-tracing.middleware.ts
│   │   │   │   │   ├── v2-container.service.ts
│   │   │   │   │   ├── v2-create-table-compat.constants.ts
│   │   │   │   │   ├── v2-execution-context.factory.ts
│   │   │   │   │   ├── v2-field-delete-compat.constants.ts
│   │   │   │   │   ├── v2-field-delete-compat.service.ts
│   │   │   │   │   ├── v2-logger.adapter.ts
│   │   │   │   │   ├── v2-openapi.controller.ts
│   │   │   │   │   ├── v2-projection-registrar.ts
│   │   │   │   │   ├── v2-query-bus-tracing.middleware.ts
│   │   │   │   │   ├── v2-record-history.service.ts
│   │   │   │   │   ├── v2-tracer.adapter.ts
│   │   │   │   │   ├── v2-undo-redo.constants.ts
│   │   │   │   │   ├── v2-user-rename-propagation.service.spec.ts
│   │   │   │   │   ├── v2-user-rename-propagation.service.ts
│   │   │   │   │   ├── v2.controller.ts
│   │   │   │   │   └── v2.module.ts
│   │   │   │   └── view/
│   │   │   │       ├── constant.ts
│   │   │   │       ├── model/
│   │   │   │       │   ├── calendar-view.dto.ts
│   │   │   │       │   ├── factory.ts
│   │   │   │       │   ├── form-view.dto.ts
│   │   │   │       │   ├── gallery-view.dto.ts
│   │   │   │       │   ├── grid-view.dto.ts
│   │   │   │       │   ├── kanban-view.dto.ts
│   │   │   │       │   └── plugin-view.dto.ts
│   │   │   │       ├── open-api/
│   │   │   │       │   ├── view-open-api-v2.service.ts
│   │   │   │       │   ├── view-open-api.controller.ts
│   │   │   │       │   ├── view-open-api.module.ts
│   │   │   │       │   ├── view-open-api.service.spec.ts
│   │   │   │       │   └── view-open-api.service.ts
│   │   │   │       ├── utils/
│   │   │   │       │   └── derive-frozen-fields.ts
│   │   │   │       ├── view.module.ts
│   │   │   │       ├── view.service.spec.ts
│   │   │   │       └── view.service.ts
│   │   │   ├── filter/
│   │   │   │   └── global-exception.filter.ts
│   │   │   ├── global/
│   │   │   │   ├── global.module.ts
│   │   │   │   ├── init-bootstrap.provider.ts
│   │   │   │   ├── init-bootstrap.service.ts
│   │   │   │   └── knex/
│   │   │   │       ├── index.ts
│   │   │   │       ├── knex.extend.ts
│   │   │   │       └── knex.module.ts
│   │   │   ├── index.ts
│   │   │   ├── instrument.ts
│   │   │   ├── logger/
│   │   │   │   └── logger.module.ts
│   │   │   ├── middleware/
│   │   │   │   └── request-info.middleware.ts
│   │   │   ├── observability/
│   │   │   │   ├── observability.module.ts
│   │   │   │   └── profiling/
│   │   │   │       ├── profiler.module.ts
│   │   │   │       └── profiler.service.ts
│   │   │   ├── performance-cache/
│   │   │   │   ├── cache-metrics/
│   │   │   │   │   ├── metrics.module.ts
│   │   │   │   │   └── metrics.service.ts
│   │   │   │   ├── decorator.ts
│   │   │   │   ├── generate-keys.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── module.ts
│   │   │   │   ├── performance-cache.decorator.spec.ts
│   │   │   │   ├── service.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── utils.ts
│   │   │   ├── share-db/
│   │   │   │   ├── auth.middleware.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── metrics/
│   │   │   │   │   ├── realtime-metrics.module.ts
│   │   │   │   │   └── realtime-metrics.service.ts
│   │   │   │   ├── readonly/
│   │   │   │   │   ├── field-readonly.service.ts
│   │   │   │   │   ├── readonly.module.ts
│   │   │   │   │   ├── readonly.service.ts
│   │   │   │   │   ├── record-readonly.service.ts
│   │   │   │   │   ├── table-readonly.service.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── view-readonly.service.ts
│   │   │   │   ├── repair-attachment-op/
│   │   │   │   │   ├── repair-attachment-op.module.ts
│   │   │   │   │   └── repair-attachment-op.service.ts
│   │   │   │   ├── share-db.adapter.ts
│   │   │   │   ├── share-db.module.ts
│   │   │   │   ├── share-db.service.ts
│   │   │   │   ├── share-db.spec.ts
│   │   │   │   ├── sharedb-redis.pubsub.ts
│   │   │   │   └── utils.ts
│   │   │   ├── swagger.ts
│   │   │   ├── tracing/
│   │   │   │   ├── base-tracing.service.ts
│   │   │   │   ├── decorators/
│   │   │   │   │   └── span.ts
│   │   │   │   └── route-tracing.interceptor.ts
│   │   │   ├── tracing.ts
│   │   │   ├── types/
│   │   │   │   ├── cls.ts
│   │   │   │   ├── data-loader.ts
│   │   │   │   ├── i18n.generated.ts
│   │   │   │   ├── redlock.d.ts
│   │   │   │   └── session.ts
│   │   │   ├── utils/
│   │   │   │   ├── code-generate.ts
│   │   │   │   ├── convert-view-vo-attachment-url.ts
│   │   │   │   ├── date-to-iso.ts
│   │   │   │   ├── db-helpers.ts
│   │   │   │   ├── db-validation-error.ts
│   │   │   │   ├── encryptor.ts
│   │   │   │   ├── exception-parse.ts
│   │   │   │   ├── extract-field-reference.ts
│   │   │   │   ├── file-utils.spec.ts
│   │   │   │   ├── file-utils.ts
│   │   │   │   ├── filter-has-me.ts
│   │   │   │   ├── filter.spec.ts
│   │   │   │   ├── filter.ts
│   │   │   │   ├── generate-thumbnail-path.ts
│   │   │   │   ├── get-max-level-role.ts
│   │   │   │   ├── i18n.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── is-not-hidden-field.ts
│   │   │   │   ├── is-user-or-link.ts
│   │   │   │   ├── major-field-keys-changed.spec.ts
│   │   │   │   ├── major-field-keys-changed.ts
│   │   │   │   ├── metadata.ts
│   │   │   │   ├── name-conversion.ts
│   │   │   │   ├── postgres-regex-escape.ts
│   │   │   │   ├── retry-decorator.spec.ts
│   │   │   │   ├── retry-decorator.ts
│   │   │   │   ├── second.ts
│   │   │   │   ├── sql-like-escape.ts
│   │   │   │   ├── string-hash.ts
│   │   │   │   ├── timing.ts
│   │   │   │   ├── update-order.spec.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   └── value-convert.ts
│   │   │   ├── worker/
│   │   │   │   └── parse.ts
│   │   │   ├── ws/
│   │   │   │   ├── ws.gateway.dev.spec.ts
│   │   │   │   ├── ws.gateway.dev.ts
│   │   │   │   ├── ws.gateway.spec.ts
│   │   │   │   ├── ws.gateway.ts
│   │   │   │   ├── ws.module.ts
│   │   │   │   ├── ws.service.spec.ts
│   │   │   │   └── ws.service.ts
│   │   │   ├── zod.validation.pipe.spec.ts
│   │   │   └── zod.validation.pipe.ts
│   │   ├── test/
│   │   │   ├── access-token.e2e-spec.ts
│   │   │   ├── aggregation-search-count-question-mark.e2e-spec.ts
│   │   │   ├── aggregation-search.e2e-spec.ts
│   │   │   ├── aggregation.e2e-spec.ts
│   │   │   ├── attachment.e2e-spec.ts
│   │   │   ├── audit-user-fields.e2e-spec.ts
│   │   │   ├── auth.e2e-spec.ts
│   │   │   ├── auto-number.e2e-spec.ts
│   │   │   ├── base-duplicate.e2e-spec.ts
│   │   │   ├── base-export-sentry.e2e-spec.ts
│   │   │   ├── base-node-folder.e2e-spec.ts
│   │   │   ├── base-node.e2e-spec.ts
│   │   │   ├── base-query.e2e-spec.ts
│   │   │   ├── base-share.e2e-spec.ts
│   │   │   ├── base-sql-executor.e2e-spec.ts
│   │   │   ├── base.e2e-spec.ts
│   │   │   ├── basic-link.e2e-spec.ts
│   │   │   ├── bidirectional-formula-link.e2e-spec.ts
│   │   │   ├── canary.e2e-spec.ts
│   │   │   ├── collaboration.e2e-spec.ts
│   │   │   ├── comment-count-collapsed-group.e2e-spec.ts
│   │   │   ├── comment.e2e-spec.ts
│   │   │   ├── comprehensive-aggregation.e2e-spec.ts
│   │   │   ├── comprehensive-field-filter.e2e-spec.ts
│   │   │   ├── comprehensive-field-sort.e2e-spec.ts
│   │   │   ├── computed-orchestrator.e2e-spec.ts
│   │   │   ├── computed-user-field.e2e-spec.ts
│   │   │   ├── computed-version-regression.e2e-spec.ts
│   │   │   ├── conditional-lookup.e2e-spec.ts
│   │   │   ├── conditional-rollup.e2e-spec.ts
│   │   │   ├── convert-field-transaction.e2e-spec.ts
│   │   │   ├── credit.e2e-spec.ts
│   │   │   ├── dashboard.e2e-spec.ts
│   │   │   ├── data-helpers/
│   │   │   │   ├── 20x-link.ts
│   │   │   │   ├── 20x.ts
│   │   │   │   └── caces/
│   │   │   │       ├── aggregation-query/
│   │   │   │       │   ├── checkbox-field.ts
│   │   │   │       │   ├── date-field.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── multiple-select-field.ts
│   │   │   │       │   ├── number-field.ts
│   │   │   │       │   ├── single-select-field.ts
│   │   │   │       │   ├── text-field.ts
│   │   │   │       │   └── user-field.ts
│   │   │   │       ├── record-filter-query/
│   │   │   │       │   ├── checkbox-field.ts
│   │   │   │       │   ├── date-field/
│   │   │   │       │   │   ├── date-field.ts
│   │   │   │       │   │   ├── date-range-sets.ts
│   │   │   │       │   │   ├── index.ts
│   │   │   │       │   │   ├── is-after-sets.ts
│   │   │   │       │   │   ├── is-before-sets.ts
│   │   │   │       │   │   ├── is-not-sets.ts
│   │   │   │       │   │   ├── is-on-or-after-sets.ts
│   │   │   │       │   │   ├── is-on-or-before-sets.ts
│   │   │   │       │   │   ├── is-sets.ts
│   │   │   │       │   │   ├── is-with-in-sets.ts
│   │   │   │       │   │   └── utils.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── multiple-select-field.ts
│   │   │   │       │   ├── number-field.ts
│   │   │   │       │   ├── single-select-field.ts
│   │   │   │       │   ├── text-field.ts
│   │   │   │       │   └── user-field.ts
│   │   │   │       └── view-default-share-meta.ts
│   │   │   ├── db-connection.e2e-spec.ts
│   │   │   ├── dead-lock.e2e-spec.ts
│   │   │   ├── delete-field.e2e-spec.ts
│   │   │   ├── duplicate-field-transaction.e2e-spec.ts
│   │   │   ├── field-calculation.e2e-spec.ts
│   │   │   ├── field-converting.e2e-spec.ts
│   │   │   ├── field-delete-references.e2e-spec.ts
│   │   │   ├── field-duplicate.e2e-spec.ts
│   │   │   ├── field-physical-columns.e2e-spec.ts
│   │   │   ├── field-reference.e2e-spec.ts
│   │   │   ├── field-view-sync.e2e-spec.ts
│   │   │   ├── field.e2e-spec.ts
│   │   │   ├── filter.e2e-spec.ts
│   │   │   ├── formula-boolean-numeric-coercion.e2e-spec.ts
│   │   │   ├── formula-conditional-lookup-numeric-if.e2e-spec.ts
│   │   │   ├── formula-conditional-numeric-cast-regression.e2e-spec.ts
│   │   │   ├── formula-counta-lookup-ancestry.e2e-spec.ts
│   │   │   ├── formula-countall-user-link-lookup.e2e-spec.ts
│   │   │   ├── formula-datetime-format.e2e-spec.ts
│   │   │   ├── formula-datetime-parse-update.e2e-spec.ts
│   │   │   ├── formula-delete-chain.e2e-spec.ts
│   │   │   ├── formula-field.e2e-spec.ts
│   │   │   ├── formula-fromnow-tonow.e2e-spec.ts
│   │   │   ├── formula-int-search-link-regression.e2e-spec.ts
│   │   │   ├── formula-left-array-flatten.e2e-spec.ts
│   │   │   ├── formula-lookup-sum-regression.e2e-spec.ts
│   │   │   ├── formula-meta.e2e-spec.ts
│   │   │   ├── formula-metadata-coercion.e2e-spec.ts
│   │   │   ├── formula-numeric-blank-regression.e2e-spec.ts
│   │   │   ├── formula-single-select-regression.e2e-spec.ts
│   │   │   ├── formula-timezone-convert.e2e-spec.ts
│   │   │   ├── formula.e2e-spec.ts
│   │   │   ├── generated-column-blank-if.e2e-spec.ts
│   │   │   ├── generated-column-numeric-coercion.e2e-spec.ts
│   │   │   ├── graph.e2e-spec.ts
│   │   │   ├── group.e2e-spec.ts
│   │   │   ├── import-base.e2e-spec.ts
│   │   │   ├── integrity.e2e-spec.ts
│   │   │   ├── invitation.e2e-spec.ts
│   │   │   ├── large-table-operations.e2e-spec.ts
│   │   │   ├── legacy-created-time-create.e2e-spec.ts
│   │   │   ├── lin-field-not-null.e2e-spec.ts
│   │   │   ├── link-api.e2e-spec.ts
│   │   │   ├── link-bulk-conversion.e2e-spec.ts
│   │   │   ├── link-events.e2e-spec.ts
│   │   │   ├── link-field-null-handling.e2e-spec.ts
│   │   │   ├── link-formula-if-boolean-context.e2e-spec.ts
│   │   │   ├── link-formula-recursion.e2e-spec.ts
│   │   │   ├── link-multi-config-toggle-collaboration.e2e-spec.ts
│   │   │   ├── link-multi-config-toggle.e2e-spec.ts
│   │   │   ├── link-view-user-filter.e2e-spec.ts
│   │   │   ├── lookup-cross-base-tiering.e2e-spec.ts
│   │   │   ├── lookup-nested-link-lookup.e2e-spec.ts
│   │   │   ├── lookup-to-link.e2e-spec.ts
│   │   │   ├── lookup.e2e-spec.ts
│   │   │   ├── mail.e2e-spec.ts
│   │   │   ├── nested-lookup-formula.e2e-spec.ts
│   │   │   ├── nested-lookup.e2e-spec.ts
│   │   │   ├── not-null-validation.e2e-spec.ts
│   │   │   ├── number-precision.e2e-spec.ts
│   │   │   ├── oauth-server.e2e-spec.ts
│   │   │   ├── oauth.e2e-spec.ts
│   │   │   ├── one-many-formula-symmetric-link.e2e-spec.ts
│   │   │   ├── opportunity-rollup-regression.e2e-spec.ts
│   │   │   ├── order-update.e2e-spec.ts
│   │   │   ├── performance.e2e-spec.ts
│   │   │   ├── personal-income-tax.e2e-spec.ts
│   │   │   ├── pin.e2e-spec.ts
│   │   │   ├── plugin-chart.e2e-spec.ts
│   │   │   ├── plugin-context-menu.e2e-spec.ts
│   │   │   ├── plugin-panel.e2e-spec.ts
│   │   │   ├── plugin.e2e-spec.ts
│   │   │   ├── record-bulk-delete.e2e-spec.ts
│   │   │   ├── record-delete-link-cleanup.e2e-spec.ts
│   │   │   ├── record-field-key.e2e-spec.ts
│   │   │   ├── record-filter-lookup-number-param.e2e-spec.ts
│   │   │   ├── record-filter-lookup-string-question-mark.e2e-spec.ts
│   │   │   ├── record-filter-query-issues.e2e-spec.ts
│   │   │   ├── record-filter-query.e2e-spec.ts
│   │   │   ├── record-group-datetime-timezone.e2e-spec.ts
│   │   │   ├── record-history.e2e-spec.ts
│   │   │   ├── record-link-select-query.e2e-spec.ts
│   │   │   ├── record-query-builder.e2e-spec.ts
│   │   │   ├── record-search-query.e2e-spec.ts
│   │   │   ├── record-search-question-mark.e2e-spec.ts
│   │   │   ├── record-typecast.e2e-spec.ts
│   │   │   ├── record-unary-filter.e2e-spec.ts
│   │   │   ├── record.e2e-spec.ts
│   │   │   ├── rollup.e2e-spec.ts
│   │   │   ├── scheduled-computing.e2e-spec.ts
│   │   │   ├── select-formula-numeric-coercion.e2e-spec.ts
│   │   │   ├── selection.e2e-spec.ts
│   │   │   ├── set-column-meta.e2e-spec.ts
│   │   │   ├── share-socket.e2e-spec.ts
│   │   │   ├── share.e2e-spec.ts
│   │   │   ├── sort.e2e-spec.ts
│   │   │   ├── space.e2e-spec.ts
│   │   │   ├── table-concurrency.e2e-spec.ts
│   │   │   ├── table-duplicate.e2e-spec.ts
│   │   │   ├── table-export.e2e-spec.ts
│   │   │   ├── table-import.e2e-spec.ts
│   │   │   ├── table-lifecycle-full.e2e-spec.ts
│   │   │   ├── table-trash.e2e-spec.ts
│   │   │   ├── table.e2e-spec.ts
│   │   │   ├── template-cover-crop.e2e-spec.ts
│   │   │   ├── template-preview.e2e-spec.ts
│   │   │   ├── template.e2e-spec.ts
│   │   │   ├── trash.e2e-spec.ts
│   │   │   ├── undo-redo.e2e-spec.ts
│   │   │   ├── user-last-visit.e2e-spec.ts
│   │   │   ├── utils/
│   │   │   │   ├── axios-instance/
│   │   │   │   │   ├── anonymous-user.ts
│   │   │   │   │   └── new-user.ts
│   │   │   │   ├── data.generator.ts
│   │   │   │   ├── event-promise.ts
│   │   │   │   ├── field-mock.ts
│   │   │   │   ├── get-error.ts
│   │   │   │   ├── init-app.ts
│   │   │   │   ├── record-mock.ts
│   │   │   │   ├── seed.ts
│   │   │   │   ├── testing-logger.ts
│   │   │   │   └── wait.ts
│   │   │   ├── v2-action-trigger-field-conversion.e2e-spec.ts
│   │   │   ├── v2-update-records.e2e-spec.ts
│   │   │   ├── view-option.e2e-spec.ts
│   │   │   ├── view.e2e-spec.ts
│   │   │   └── waitlist.e2e-spec.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── vitest-bench.config.ts
│   │   ├── vitest-e2e.config.ts
│   │   ├── vitest-e2e.setup.ts
│   │   ├── vitest.config.ts
│   │   ├── webpack.config.js
│   │   ├── webpack.dev.js
│   │   └── webpack.swc.js
│   ├── nextjs-app/
│   │   ├── .escheckrc
│   │   ├── .eslintrc.js
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── nextjs-app.iml
│   │   ├── .size-limit.js
│   │   ├── README.md
│   │   ├── babel.config.backup.js
│   │   ├── components.json
│   │   ├── config/
│   │   │   └── tests/
│   │   │       ├── AppTestProviders.tsx
│   │   │       ├── I18nextTestStubProvider.tsx
│   │   │       ├── ReactSvgrMock.tsx
│   │   │       ├── setupVitest.ts
│   │   │       └── test-utils.tsx
│   │   ├── e2e/
│   │   │   └── pages/
│   │   │       ├── index/
│   │   │       │   ├── index-chinese.spec.ts
│   │   │       │   └── index.spec.ts
│   │   │       └── system/
│   │   │           └── 404.spec.ts
│   │   ├── instrumentation.ts
│   │   ├── lint-staged.config.js
│   │   ├── next-i18next.config.js
│   │   ├── next.config.js
│   │   ├── package.json
│   │   ├── playwright.config.ts
│   │   ├── postcss.config.js
│   │   ├── public/
│   │   │   ├── images/
│   │   │   │   └── favicon/
│   │   │   │       ├── .readme
│   │   │   │       ├── browserconfig.xml
│   │   │   │       └── site.webmanifest
│   │   │   ├── robots.txt
│   │   │   └── streamsaver/
│   │   │       ├── mitm.html
│   │   │       └── sw.js
│   │   ├── sentry.client.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── AppProviders.tsx
│   │   │   ├── backend/
│   │   │   │   └── api/
│   │   │   │       └── rest/
│   │   │   │           ├── axios.ts
│   │   │   │           ├── get-user.ts
│   │   │   │           └── ssr-api.ts
│   │   │   ├── components/
│   │   │   │   ├── Banner.tsx
│   │   │   │   ├── Guide.tsx
│   │   │   │   ├── Metrics.tsx
│   │   │   │   ├── RouterProgress.tsx
│   │   │   │   ├── Selector.tsx
│   │   │   │   ├── TeableLogo.tsx
│   │   │   │   ├── changelog/
│   │   │   │   │   ├── ChangelogNotification.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── google-ads.tsx
│   │   │   │   ├── layout/
│   │   │   │   │   ├── MainFooter.tsx
│   │   │   │   │   ├── MainLayout.tsx
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── MainLayout.test.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   └── store/
│   │   │   │       ├── guide.ts
│   │   │   │       └── index.ts
│   │   │   ├── features/
│   │   │   │   ├── app/
│   │   │   │   │   ├── automation/
│   │   │   │   │   │   ├── Pages.tsx
│   │   │   │   │   │   └── workflow-panel/
│   │   │   │   │   │       ├── WorkFlowPanel.tsx
│   │   │   │   │   │       ├── WorkFlowPanelModal.tsx
│   │   │   │   │   │       └── useWorkFlowPaneStore.ts
│   │   │   │   │   ├── base/
│   │   │   │   │   │   └── CommunityPage.tsx
│   │   │   │   │   ├── base-node/
│   │   │   │   │   │   ├── BasePage.tsx
│   │   │   │   │   │   ├── DashBoardPage.tsx
│   │   │   │   │   │   ├── TablePage.tsx
│   │   │   │   │   │   ├── WorkflowPage.tsx
│   │   │   │   │   │   ├── helper.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── blocks/
│   │   │   │   │   │   ├── App.tsx
│   │   │   │   │   │   ├── AuthorityMatrix.tsx
│   │   │   │   │   │   ├── Error.tsx
│   │   │   │   │   │   ├── admin/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── setting/
│   │   │   │   │   │   │   │   ├── SettingPage.tsx
│   │   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   │   ├── Branding.tsx
│   │   │   │   │   │   │   │   │   ├── BrandingLogo.tsx
│   │   │   │   │   │   │   │   │   ├── ConfigurationList.tsx
│   │   │   │   │   │   │   │   │   ├── CopyInstance.tsx
│   │   │   │   │   │   │   │   │   ├── ai-config/
│   │   │   │   │   │   │   │   │   │   ├── AIConfigurationStatus.tsx
│   │   │   │   │   │   │   │   │   │   ├── AIControlCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AIModelPreferencesCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AIProviderCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AISetupWizard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AiFormWizard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AiModelSelect.tsx
│   │   │   │   │   │   │   │   │   │   ├── BatchTestModels.tsx
│   │   │   │   │   │   │   │   │   │   ├── CodingModels.tsx
│   │   │   │   │   │   │   │   │   │   ├── DefaultModelsStep.tsx
│   │   │   │   │   │   │   │   │   │   ├── GatewayModelPickerDialog.tsx
│   │   │   │   │   │   │   │   │   │   ├── GatewayModelsStep.tsx
│   │   │   │   │   │   │   │   │   │   ├── LLMApiConfigStep.tsx
│   │   │   │   │   │   │   │   │   │   ├── LlmProviderForm.tsx
│   │   │   │   │   │   │   │   │   │   ├── LlmproviderManage.tsx
│   │   │   │   │   │   │   │   │   │   ├── SetupStepCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── TestButton.tsx
│   │   │   │   │   │   │   │   │   │   ├── ai-model-select/
│   │   │   │   │   │   │   │   │   │   │   ├── GatewayModelOption.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ModelSelectTrigger.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ProviderModelOption.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   │   │   │   │   ├── useGatewayModels.ts
│   │   │   │   │   │   │   │   │   │   │   ├── useModelCategories.ts
│   │   │   │   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   │   │   │   │   ├── gateway-models-step/
│   │   │   │   │   │   │   │   │   │   │   ├── AddModelDialog.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ModelCard.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ModelSearchPopover.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── PricingSection.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── QuickAddButtons.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   │   │   │   └── utils.tsx
│   │   │   │   │   │   │   │   │   ├── canary/
│   │   │   │   │   │   │   │   │   │   ├── CanarySettings.tsx
│   │   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   ├── mail-config/
│   │   │   │   │   │   │   │   │   │   ├── MailConfig.tsx
│   │   │   │   │   │   │   │   │   │   └── MailConfigForm.tsx
│   │   │   │   │   │   │   │   │   └── waitlist/
│   │   │   │   │   │   │   │   │       ├── InviteCodeManage.tsx
│   │   │   │   │   │   │   │   │       └── WaitlistManage.tsx
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   └── template/
│   │   │   │   │   │   │       ├── TemplatePage.tsx
│   │   │   │   │   │   │       ├── components/
│   │   │   │   │   │   │       │   ├── BaseSelectPanel.tsx
│   │   │   │   │   │   │       │   ├── CategorySettingDialog.tsx
│   │   │   │   │   │   │       │   ├── MarkdownEditor.tsx
│   │   │   │   │   │   │       │   ├── MarkdownPreviewButton.tsx
│   │   │   │   │   │   │       │   ├── TemplateCategorySelect.tsx
│   │   │   │   │   │   │       │   ├── TemplateCover.tsx
│   │   │   │   │   │   │       │   ├── TemplateTable.tsx
│   │   │   │   │   │   │       │   ├── TemplateTooltips.tsx
│   │   │   │   │   │   │       │   ├── TextEditor.tsx
│   │   │   │   │   │   │       │   ├── TextEditorDialog.tsx
│   │   │   │   │   │   │       │   ├── index.ts
│   │   │   │   │   │   │       │   └── upload-panel/
│   │   │   │   │   │   │       │       ├── Process.tsx
│   │   │   │   │   │   │       │       ├── TemplateCoverPreview.tsx
│   │   │   │   │   │   │       │       ├── Trigger.tsx
│   │   │   │   │   │   │       │       ├── UploadPanel.tsx
│   │   │   │   │   │   │       │       └── index.ts
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── base/
│   │   │   │   │   │   │   ├── BasePermissionListener.tsx
│   │   │   │   │   │   │   ├── base-node/
│   │   │   │   │   │   │   │   ├── BaseNodeContext.ts
│   │   │   │   │   │   │   │   ├── BaseNodeProvider.tsx
│   │   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │   │       ├── helper.spec.ts
│   │   │   │   │   │   │   │       ├── helper.ts
│   │   │   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │   │   │       ├── useBaseNode.ts
│   │   │   │   │   │   │   │       ├── useBaseNodeContext.ts
│   │   │   │   │   │   │   │       └── useBaseNodeCrud.ts
│   │   │   │   │   │   │   ├── base-side-bar/
│   │   │   │   │   │   │   │   ├── BaseNodeAddResourceButton.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeMore.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeShareIndicator.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeStarButton.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeTree.tsx
│   │   │   │   │   │   │   │   ├── BasePageRouter.tsx
│   │   │   │   │   │   │   │   ├── BaseSideBar.tsx
│   │   │   │   │   │   │   │   ├── BaseSidebarHeaderLeft.tsx
│   │   │   │   │   │   │   │   ├── NodeShareContent.tsx
│   │   │   │   │   │   │   │   ├── NodeShareDialog.tsx
│   │   │   │   │   │   │   │   └── QuickAction.tsx
│   │   │   │   │   │   │   ├── duplicate/
│   │   │   │   │   │   │   │   ├── DuplicateBaseModal.tsx
│   │   │   │   │   │   │   │   ├── TemplateCreateBaseModal.tsx
│   │   │   │   │   │   │   │   ├── useDuplicateBaseStore.ts
│   │   │   │   │   │   │   │   ├── useTemplateCreateBaseStore.ts
│   │   │   │   │   │   │   │   └── useTemplateMonitor.ts
│   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │   │       └── useLastVisitBase.ts
│   │   │   │   │   │   ├── billing/
│   │   │   │   │   │   │   ├── SpaceSubscriptionModal.tsx
│   │   │   │   │   │   │   ├── useSpaceSubscriptionMonitor.ts
│   │   │   │   │   │   │   └── useSpaceSubscriptionStore.ts
│   │   │   │   │   │   ├── chart/
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── Chart.tsx
│   │   │   │   │   │   │   │   ├── ChartProvider.tsx
│   │   │   │   │   │   │   │   ├── EnvProvider.tsx
│   │   │   │   │   │   │   │   └── chart/
│   │   │   │   │   │   │   │       ├── ChartLayout.tsx
│   │   │   │   │   │   │   │       ├── ChartPage.tsx
│   │   │   │   │   │   │   │       ├── ChartQuery.tsx
│   │   │   │   │   │   │   │       ├── chart-config/
│   │   │   │   │   │   │   │       │   ├── ChartForm.tsx
│   │   │   │   │   │   │   │       │   ├── ChartSetting.tsx
│   │   │   │   │   │   │   │       │   ├── QueryStatus.tsx
│   │   │   │   │   │   │   │       │   ├── TypeSelector.tsx
│   │   │   │   │   │   │   │       │   ├── common/
│   │   │   │   │   │   │   │       │   │   ├── AxisDisplayBaseContent.tsx
│   │   │   │   │   │   │   │       │   │   ├── ColumnSelector.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboLineStyleEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboTypeEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboXAxisDisplayEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboYAisxDisplayEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ConfigItem.tsx
│   │   │   │   │   │   │   │       │   │   ├── GoalLineEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── NumberInput.tsx
│   │   │   │   │   │   │   │       │   │   ├── PaddingEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── SwitchEditor.tsx
│   │   │   │   │   │   │   │       │   │   └── YAxisPositionEditor.tsx
│   │   │   │   │   │   │   │       │   └── form/
│   │   │   │   │   │   │   │       │       ├── AreaForm.tsx
│   │   │   │   │   │   │   │       │       ├── BarForm.tsx
│   │   │   │   │   │   │   │       │       ├── ComboForm.tsx
│   │   │   │   │   │   │   │       │       ├── ComboXAxisEditor.tsx
│   │   │   │   │   │   │   │       │       ├── ComboYAxisEditor.tsx
│   │   │   │   │   │   │   │       │       ├── LineForm.tsx
│   │   │   │   │   │   │   │       │       ├── PieForm.tsx
│   │   │   │   │   │   │   │       │       ├── TableForm.tsx
│   │   │   │   │   │   │   │       │       └── utils.ts
│   │   │   │   │   │   │   │       ├── chart-show/
│   │   │   │   │   │   │   │       │   ├── ChartDisplay.tsx
│   │   │   │   │   │   │   │       │   ├── combo/
│   │   │   │   │   │   │   │       │   │   ├── Combo.tsx
│   │   │   │   │   │   │   │       │   │   ├── TooltipItem.tsx
│   │   │   │   │   │   │   │       │   │   └── useComboConfig.ts
│   │   │   │   │   │   │   │       │   ├── pie/
│   │   │   │   │   │   │   │       │   │   ├── Pie.tsx
│   │   │   │   │   │   │   │       │   │   ├── PieLegendContent.tsx
│   │   │   │   │   │   │   │       │   │   ├── usePieConfig.tsx
│   │   │   │   │   │   │   │       │   │   └── useRefObserve.ts
│   │   │   │   │   │   │   │       │   ├── table/
│   │   │   │   │   │   │   │       │   │   └── ChartTable.tsx
│   │   │   │   │   │   │   │       │   ├── types.ts
│   │   │   │   │   │   │   │       │   └── utils.ts
│   │   │   │   │   │   │   │       └── utils.ts
│   │   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   │   ├── globals.css
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── useBaseQueryData.ts
│   │   │   │   │   │   │   │   ├── useEnv.ts
│   │   │   │   │   │   │   │   ├── useFilterNumberColumns.ts
│   │   │   │   │   │   │   │   ├── usePluginInstall.ts
│   │   │   │   │   │   │   │   └── useUIConfig.ts
│   │   │   │   │   │   │   ├── query.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   │   └── Dashboard.tsx
│   │   │   │   │   │   ├── db-connection/
│   │   │   │   │   │   │   ├── Panel.tsx
│   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │   │       └── useDbConnection.ts
│   │   │   │   │   │   ├── design/
│   │   │   │   │   │   │   ├── BaseDetail.tsx
│   │   │   │   │   │   │   ├── Design.tsx
│   │   │   │   │   │   │   ├── TableDetail.tsx
│   │   │   │   │   │   │   ├── TableTabs.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── Actions.tsx
│   │   │   │   │   │   │   │   ├── FieldPropertyEditor.tsx
│   │   │   │   │   │   │   │   └── Integrity.tsx
│   │   │   │   │   │   │   └── data-table/
│   │   │   │   │   │   │       ├── DataTable.tsx
│   │   │   │   │   │   │       ├── FieldGraph.tsx
│   │   │   │   │   │   │       └── useDataColumns.tsx
│   │   │   │   │   │   ├── erd/
│   │   │   │   │   │   │   ├── BaseErd.tsx
│   │   │   │   │   │   │   ├── BaseErdTableNode.tsx
│   │   │   │   │   │   │   ├── CustomMakers.tsx
│   │   │   │   │   │   │   ├── DynamicBaseErd.tsx
│   │   │   │   │   │   │   └── SelfConnectingEdge.tsx
│   │   │   │   │   │   ├── graph/
│   │   │   │   │   │   │   ├── DynamicFieldGraph.tsx
│   │   │   │   │   │   │   ├── FieldGraph.tsx
│   │   │   │   │   │   │   ├── ProgressBar.tsx
│   │   │   │   │   │   │   └── usePlan.ts
│   │   │   │   │   │   ├── import-table/
│   │   │   │   │   │   │   ├── TableImport.tsx
│   │   │   │   │   │   │   ├── UrlPanel.tsx
│   │   │   │   │   │   │   ├── field-config-panel/
│   │   │   │   │   │   │   │   ├── CollapsePanel.tsx
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   ├── inplace-panel/
│   │   │   │   │   │   │   │   │   ├── FieldSelector.tsx
│   │   │   │   │   │   │   │   │   ├── InplaceFieldConfigPanel.tsx
│   │   │   │   │   │   │   │   │   └── InplacePreviewColumn.tsx
│   │   │   │   │   │   │   │   └── new-create-panel/
│   │   │   │   │   │   │   │       ├── FieldConfigPanel.tsx
│   │   │   │   │   │   │   │       └── PreviewColumn.tsx
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── upload-panel/
│   │   │   │   │   │   │       ├── Process.tsx
│   │   │   │   │   │   │       ├── Trigger.tsx
│   │   │   │   │   │   │       ├── UploadPanel.tsx
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── setting/
│   │   │   │   │   │   │   ├── SettingRight.tsx
│   │   │   │   │   │   │   ├── SettingRightTitle.tsx
│   │   │   │   │   │   │   ├── access-token/
│   │   │   │   │   │   │   │   ├── AccessTokenList.tsx
│   │   │   │   │   │   │   │   ├── PersonAccessTokenForm.tsx
│   │   │   │   │   │   │   │   ├── PersonAccessTokenPage.tsx
│   │   │   │   │   │   │   │   └── form/
│   │   │   │   │   │   │   │       ├── AccessList.tsx
│   │   │   │   │   │   │   │       ├── AccessSelect.tsx
│   │   │   │   │   │   │   │       ├── AccessTokenForm.tsx
│   │   │   │   │   │   │   │       ├── AccessTokenFormEdit.tsx
│   │   │   │   │   │   │   │       ├── ExpirationSelect.tsx
│   │   │   │   │   │   │   │       └── RefreshToken.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── FormItem.tsx
│   │   │   │   │   │   │   │   ├── FormPageLayout.tsx
│   │   │   │   │   │   │   │   ├── RequireCom.tsx
│   │   │   │   │   │   │   │   └── ScopesSelect.tsx
│   │   │   │   │   │   │   ├── oauth-app/
│   │   │   │   │   │   │   │   ├── OAuthAppDecisionPage.tsx
│   │   │   │   │   │   │   │   ├── OAuthAppPage.tsx
│   │   │   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   │   │   └── manage/
│   │   │   │   │   │   │   │       ├── CallbackEditor.tsx
│   │   │   │   │   │   │   │       ├── List.tsx
│   │   │   │   │   │   │   │       ├── OAuthAppEdit.tsx
│   │   │   │   │   │   │   │       ├── OAuthAppForm.tsx
│   │   │   │   │   │   │   │       └── OAuthAppNew.tsx
│   │   │   │   │   │   │   ├── plugin/
│   │   │   │   │   │   │   │   ├── MarkDownEditor.tsx
│   │   │   │   │   │   │   │   ├── PluginEdit.tsx
│   │   │   │   │   │   │   │   ├── PluginList.tsx
│   │   │   │   │   │   │   │   ├── PluginNew.tsx
│   │   │   │   │   │   │   │   ├── PluginPage.tsx
│   │   │   │   │   │   │   │   ├── component/
│   │   │   │   │   │   │   │   │   ├── JsonEditor.tsx
│   │   │   │   │   │   │   │   │   ├── LogoEditor.tsx
│   │   │   │   │   │   │   │   │   ├── NewSecret.tsx
│   │   │   │   │   │   │   │   │   ├── PositionSelector.tsx
│   │   │   │   │   │   │   │   │   ├── StatusBadge.tsx
│   │   │   │   │   │   │   │   │   └── StatusDot.tsx
│   │   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │   │       └── useStatusStatic.ts
│   │   │   │   │   │   │   └── query-builder/
│   │   │   │   │   │   │       ├── AIContextPanel.tsx
│   │   │   │   │   │   │       ├── FilterBuilder.tsx
│   │   │   │   │   │   │       ├── PreviewScript.tsx
│   │   │   │   │   │   │       ├── PreviewTable.tsx
│   │   │   │   │   │   │       ├── QueryBuilder.tsx
│   │   │   │   │   │   │       ├── SearchBuilder.tsx
│   │   │   │   │   │   │       ├── SortBuilder.tsx
│   │   │   │   │   │   │       ├── ViewBuilder.tsx
│   │   │   │   │   │   │       └── useTransformFieldKey.ts
│   │   │   │   │   │   ├── share/
│   │   │   │   │   │   │   ├── base/
│   │   │   │   │   │   │   │   ├── BaseShareAuthPage.tsx
│   │   │   │   │   │   │   │   └── share-base-ssr.ts
│   │   │   │   │   │   │   └── view/
│   │   │   │   │   │   │       ├── AuthPage.tsx
│   │   │   │   │   │   │       ├── EmbedFooter.tsx
│   │   │   │   │   │   │       ├── ShareTablePermissionProvider.tsx
│   │   │   │   │   │   │       ├── ShareView.tsx
│   │   │   │   │   │   │       ├── ShareViewPage.tsx
│   │   │   │   │   │   │       └── component/
│   │   │   │   │   │   │           ├── calendar/
│   │   │   │   │   │   │           │   ├── CalendarView.tsx
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── form/
│   │   │   │   │   │   │           │   ├── FormView.tsx
│   │   │   │   │   │   │           │   └── FormViewBase.tsx
│   │   │   │   │   │   │           ├── gallery/
│   │   │   │   │   │   │           │   ├── GalleryView.tsx
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── grid/
│   │   │   │   │   │   │           │   ├── GridView.tsx
│   │   │   │   │   │   │           │   ├── GridViewBase.tsx
│   │   │   │   │   │   │           │   ├── aggregation/
│   │   │   │   │   │   │           │   │   ├── AggregationProvider.tsx
│   │   │   │   │   │   │           │   │   ├── GroupPointProvider.tsx
│   │   │   │   │   │   │           │   │   └── index.ts
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Sort.tsx
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── kanban/
│   │   │   │   │   │   │           │   ├── KanbanView.tsx
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── plugin/
│   │   │   │   │   │   │           │   └── SharePluginView.tsx
│   │   │   │   │   │   │           └── share-view-filter/
│   │   │   │   │   │   │               ├── FilterUser.tsx
│   │   │   │   │   │   │               ├── ShareViewFilter.tsx
│   │   │   │   │   │   │               ├── filter-link/
│   │   │   │   │   │   │               │   ├── FilterLink.tsx
│   │   │   │   │   │   │               │   ├── FilterLinkSelectList.tsx
│   │   │   │   │   │   │               │   ├── FilterLinkSelectTrigger.tsx
│   │   │   │   │   │   │               │   └── index.ts
│   │   │   │   │   │   │               └── index.ts
│   │   │   │   │   │   ├── space/
│   │   │   │   │   │   │   ├── BaseCard.tsx
│   │   │   │   │   │   │   ├── BaseItem.tsx
│   │   │   │   │   │   │   ├── BaseList.tsx
│   │   │   │   │   │   │   ├── ColorBg.tsx
│   │   │   │   │   │   │   ├── DraggableBaseGrid.tsx
│   │   │   │   │   │   │   ├── DraggableBaseRows.tsx
│   │   │   │   │   │   │   ├── FreshSettingGuideDialog.tsx
│   │   │   │   │   │   │   ├── NoBasesPlaceholder.tsx
│   │   │   │   │   │   │   ├── NoSpacesPlaceholder.tsx
│   │   │   │   │   │   │   ├── RecentlyBase.tsx
│   │   │   │   │   │   │   ├── SharedBasePage.tsx
│   │   │   │   │   │   │   ├── SpaceCard.tsx
│   │   │   │   │   │   │   ├── SpaceInnerPage.tsx
│   │   │   │   │   │   │   ├── SpacePage.tsx
│   │   │   │   │   │   │   ├── component/
│   │   │   │   │   │   │   │   ├── BaseActionTrigger.tsx
│   │   │   │   │   │   │   │   ├── EditableSpaceSelect.tsx
│   │   │   │   │   │   │   │   ├── SpaceActionTrigger.tsx
│   │   │   │   │   │   │   │   └── upload-panel/
│   │   │   │   │   │   │   │       ├── ImportLogPanel.tsx
│   │   │   │   │   │   │   │       ├── Process.tsx
│   │   │   │   │   │   │   │       ├── Trigger.tsx
│   │   │   │   │   │   │   │       ├── UploadPanel.tsx
│   │   │   │   │   │   │   │       ├── UploadPanelDialog.tsx
│   │   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   └── useSpaceList.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── space-side-bar/
│   │   │   │   │   │   │   │   ├── ItemButton.tsx
│   │   │   │   │   │   │   │   ├── PinItem.tsx
│   │   │   │   │   │   │   │   ├── PinList.tsx
│   │   │   │   │   │   │   │   ├── SpaceInnerSideBar.tsx
│   │   │   │   │   │   │   │   ├── SpaceItem.tsx
│   │   │   │   │   │   │   │   ├── SpaceList.tsx
│   │   │   │   │   │   │   │   ├── SpaceOperation.tsx
│   │   │   │   │   │   │   │   ├── SpaceQuickSearch.tsx
│   │   │   │   │   │   │   │   ├── SpaceSideBar.tsx
│   │   │   │   │   │   │   │   ├── SpaceSwitcher.tsx
│   │   │   │   │   │   │   │   └── StarButton.tsx
│   │   │   │   │   │   │   ├── useBaseList.tsx
│   │   │   │   │   │   │   ├── usePinMap.ts
│   │   │   │   │   │   │   └── useSpaceListOrdered.tsx
│   │   │   │   │   │   ├── space-setting/
│   │   │   │   │   │   │   ├── SpaceInnerSettingModal.tsx
│   │   │   │   │   │   │   ├── collaborator/
│   │   │   │   │   │   │   │   ├── CollaboratorPage.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── general/
│   │   │   │   │   │   │   │   ├── GeneralPage.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── integration/
│   │   │   │   │   │   │       └── components/
│   │   │   │   │   │   │           ├── AiConfig.tsx
│   │   │   │   │   │   │           ├── IntegrationCard.tsx
│   │   │   │   │   │   │           └── index.ts
│   │   │   │   │   │   ├── table/
│   │   │   │   │   │   │   ├── FailAlert.tsx
│   │   │   │   │   │   │   ├── Table.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── use-aggregations-query.ts
│   │   │   │   │   │   │   │   ├── use-import-status.ts
│   │   │   │   │   │   │   │   ├── use-row-count-query.ts
│   │   │   │   │   │   │   │   └── use-view-error-handler.tsx
│   │   │   │   │   │   │   ├── store/
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   └── use-locked-view-tip-store.ts
│   │   │   │   │   │   │   └── table-header/
│   │   │   │   │   │   │       ├── AddPluginView.tsx
│   │   │   │   │   │   │       ├── AddView.tsx
│   │   │   │   │   │   │       ├── BaseShare.tsx
│   │   │   │   │   │   │       ├── Collaborators.tsx
│   │   │   │   │   │   │       ├── LockedViewTip.tsx
│   │   │   │   │   │   │       ├── TableHeader.tsx
│   │   │   │   │   │   │       ├── TableInfo.tsx
│   │   │   │   │   │   │       └── publish-base/
│   │   │   │   │   │   │           ├── AppPublishContext.tsx
│   │   │   │   │   │   │           ├── NodeSelect.tsx
│   │   │   │   │   │   │           ├── NodeTreeSelect.tsx
│   │   │   │   │   │   │           ├── PublishBaseDialog.tsx
│   │   │   │   │   │   │           └── UnpublishedAppsDialog.tsx
│   │   │   │   │   │   ├── table-list/
│   │   │   │   │   │   │   ├── DraggableList.tsx
│   │   │   │   │   │   │   ├── NoDraggableList.tsx
│   │   │   │   │   │   │   ├── TableList.tsx
│   │   │   │   │   │   │   ├── TableListItem.tsx
│   │   │   │   │   │   │   ├── TableOperation.tsx
│   │   │   │   │   │   │   ├── useAddTable.ts
│   │   │   │   │   │   │   └── useTableHref.tsx
│   │   │   │   │   │   ├── trash/
│   │   │   │   │   │   │   ├── BaseTrashPage.tsx
│   │   │   │   │   │   │   ├── SpaceInnerTrashModal.tsx
│   │   │   │   │   │   │   ├── SpaceTrashPage.tsx
│   │   │   │   │   │   │   └── components/
│   │   │   │   │   │   │       ├── TableTrash.tsx
│   │   │   │   │   │   │       └── TableTrashDialog.tsx
│   │   │   │   │   │   └── view/
│   │   │   │   │   │       ├── View.tsx
│   │   │   │   │   │       ├── calendar/
│   │   │   │   │   │       │   ├── CalendarView.tsx
│   │   │   │   │   │       │   ├── CalendarViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── AddDateFieldDialog.tsx
│   │   │   │   │   │       │   │   ├── AddEventButton.tsx
│   │   │   │   │   │       │   │   ├── Calendar.tsx
│   │   │   │   │   │       │   │   ├── CalendarConfig.tsx
│   │   │   │   │   │       │   │   ├── EventList.tsx
│   │   │   │   │   │       │   │   ├── EventListContainer.tsx
│   │   │   │   │   │       │   │   └── EventMenu.tsx
│   │   │   │   │   │       │   ├── context/
│   │   │   │   │   │       │   │   ├── CalendarContext.ts
│   │   │   │   │   │       │   │   ├── CalendarProvider.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useCalendar.ts
│   │   │   │   │   │       │   │   ├── useCalendarFields.ts
│   │   │   │   │   │       │   │   └── useEventMenuStore.ts
│   │   │   │   │   │       │   ├── type.ts
│   │   │   │   │   │       │   └── util.ts
│   │   │   │   │   │       ├── constant.ts
│   │   │   │   │   │       ├── field/
│   │   │   │   │   │       │   ├── FieldSetting.tsx
│   │   │   │   │   │       │   └── useFieldSettingStore.ts
│   │   │   │   │   │       ├── form/
│   │   │   │   │   │       │   ├── FormView.tsx
│   │   │   │   │   │       │   ├── FormViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── BrandFooter.tsx
│   │   │   │   │   │       │   │   ├── Drag.tsx
│   │   │   │   │   │       │   │   ├── FormCellEditor.tsx
│   │   │   │   │   │       │   │   ├── FormEditor.tsx
│   │   │   │   │   │       │   │   ├── FormEditorMain.tsx
│   │   │   │   │   │       │   │   ├── FormField.tsx
│   │   │   │   │   │       │   │   ├── FormFieldEditor.tsx
│   │   │   │   │   │       │   │   ├── FormPreviewer.tsx
│   │   │   │   │   │       │   │   ├── FormSidebar.tsx
│   │   │   │   │   │       │   │   ├── FromBody.tsx
│   │   │   │   │   │       │   │   ├── ShareUserEditor.tsx
│   │   │   │   │   │       │   │   ├── SortableItem.tsx
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── share-link-editor/
│   │   │   │   │   │       │   │       ├── FormLinkEditor.tsx
│   │   │   │   │   │       │   │       └── LinkRecordList.tsx
│   │   │   │   │   │       │   ├── constant.ts
│   │   │   │   │   │       │   └── util.ts
│   │   │   │   │   │       ├── gallery/
│   │   │   │   │   │       │   ├── GalleryView.tsx
│   │   │   │   │   │       │   ├── GalleryViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── Card.tsx
│   │   │   │   │   │       │   │   ├── CardCarousel.tsx
│   │   │   │   │   │       │   │   ├── SortableItem.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── context/
│   │   │   │   │   │       │   │   ├── GalleryContext.ts
│   │   │   │   │   │       │   │   ├── GalleryProvider.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useCacheRecords.ts
│   │   │   │   │   │       │   │   └── useGallery.ts
│   │   │   │   │   │       │   ├── type.ts
│   │   │   │   │   │       │   └── utils/
│   │   │   │   │   │       │       ├── card.ts
│   │   │   │   │   │       │       ├── columns.ts
│   │   │   │   │   │       │       └── index.ts
│   │   │   │   │   │       ├── grid/
│   │   │   │   │   │       │   ├── DomBox.tsx
│   │   │   │   │   │       │   ├── GridView.tsx
│   │   │   │   │   │       │   ├── GridViewBase.tsx
│   │   │   │   │   │       │   ├── GridViewBaseInner.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── AiAutoFillDialogContainer.tsx
│   │   │   │   │   │       │   │   ├── AiGenerateButton.tsx
│   │   │   │   │   │       │   │   ├── ConfirmNewRecords.tsx
│   │   │   │   │   │       │   │   ├── FieldMenu.tsx
│   │   │   │   │   │       │   │   ├── GroupHeaderMenu.tsx
│   │   │   │   │   │       │   │   ├── PluginMenu.tsx
│   │   │   │   │   │       │   │   ├── PrefillingRowContainer.tsx
│   │   │   │   │   │       │   │   ├── PresortRowContainer.tsx
│   │   │   │   │   │       │   │   ├── RecordMenu.tsx
│   │   │   │   │   │       │   │   ├── ResetClickCountButton.tsx
│   │   │   │   │   │       │   │   ├── StatisticMenu.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── const.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useCollaborate.ts
│   │   │   │   │   │       │   │   ├── useIsSelectionLoaded.ts
│   │   │   │   │   │       │   │   ├── useSelectionOperation.ts
│   │   │   │   │   │       │   │   └── useSelectionStore.ts
│   │   │   │   │   │       │   ├── useGridSearchStore.ts
│   │   │   │   │   │       │   └── utils/
│   │   │   │   │   │       │       ├── computeFrozenFields.ts
│   │   │   │   │   │       │       ├── copyAndPaste.ts
│   │   │   │   │   │       │       ├── fill.ts
│   │   │   │   │   │       │       ├── getSyncCopyData.ts
│   │   │   │   │   │       │       ├── index.ts
│   │   │   │   │   │       │       ├── selection.ts
│   │   │   │   │   │       │       ├── selectionViewQuery.spec.ts
│   │   │   │   │   │       │       └── selectionViewQuery.ts
│   │   │   │   │   │       ├── hooks/
│   │   │   │   │   │       │   ├── useContextMenu.ts
│   │   │   │   │   │       │   └── useToolbarChange.ts
│   │   │   │   │   │       ├── kanban/
│   │   │   │   │   │       │   ├── KanbanView.tsx
│   │   │   │   │   │       │   ├── KanbanViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── KanbanCard.tsx
│   │   │   │   │   │       │   │   ├── KanbanContainer.tsx
│   │   │   │   │   │       │   │   ├── KanbanStack.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackContainer.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackCreator.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackHeader.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackTitle.tsx
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── interface.ts
│   │   │   │   │   │       │   ├── constant.ts
│   │   │   │   │   │       │   ├── context/
│   │   │   │   │   │       │   │   ├── KanbanContext.ts
│   │   │   │   │   │       │   │   ├── KanbanProvider.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useInView.ts
│   │   │   │   │   │       │   │   └── useKanban.ts
│   │   │   │   │   │       │   ├── store/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useKanbanStackCollapsed.ts
│   │   │   │   │   │       │   ├── type.ts
│   │   │   │   │   │       │   └── utils/
│   │   │   │   │   │       │       ├── card.ts
│   │   │   │   │   │       │       ├── drag.ts
│   │   │   │   │   │       │       ├── filter.ts
│   │   │   │   │   │       │       └── index.ts
│   │   │   │   │   │       ├── list/
│   │   │   │   │   │       │   ├── DraggableWrapper.tsx
│   │   │   │   │   │       │   ├── ExpandViewList.tsx
│   │   │   │   │   │       │   ├── PinViewItem.tsx
│   │   │   │   │   │       │   ├── ViewList.tsx
│   │   │   │   │   │       │   ├── ViewListItem.tsx
│   │   │   │   │   │       │   ├── useAddView.ts
│   │   │   │   │   │       │   └── useDeleteView.ts
│   │   │   │   │   │       ├── plugin/
│   │   │   │   │   │       │   └── PluginView.tsx
│   │   │   │   │   │       ├── search/
│   │   │   │   │   │       │   ├── SearchButton.tsx
│   │   │   │   │   │       │   ├── SearchCommand.tsx
│   │   │   │   │   │       │   └── SearchCountPagination.tsx
│   │   │   │   │   │       ├── tool-bar/
│   │   │   │   │   │       │   ├── APIDialog.tsx
│   │   │   │   │   │       │   ├── APIDialogContent.tsx
│   │   │   │   │   │       │   ├── CalendarToolBar.tsx
│   │   │   │   │   │       │   ├── FormToolBar.tsx
│   │   │   │   │   │       │   ├── GalleryToolBar.tsx
│   │   │   │   │   │       │   ├── GridToolBar.tsx
│   │   │   │   │   │       │   ├── KanbanToolBar.tsx
│   │   │   │   │   │       │   ├── Others.tsx
│   │   │   │   │   │       │   ├── SharePopover.tsx
│   │   │   │   │   │       │   ├── ShareViewContent.tsx
│   │   │   │   │   │       │   ├── ToolBarButton.tsx
│   │   │   │   │   │       │   ├── UnifiedShareDialog.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── CalendarViewOperators.tsx
│   │   │   │   │   │       │   │   ├── CoverFieldSelect.tsx
│   │   │   │   │   │       │   │   ├── GalleryViewOperators.tsx
│   │   │   │   │   │       │   │   ├── GridViewOperators.tsx
│   │   │   │   │   │       │   │   ├── KanbanViewOperators.tsx
│   │   │   │   │   │       │   │   ├── PersonalViewSwitch.tsx
│   │   │   │   │   │       │   │   ├── UndoRedoButtons.tsx
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useToolBarStore.tsx
│   │   │   │   │   │       │   ├── hook/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useViewConfigurable.ts
│   │   │   │   │   │       │   ├── store/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useFormModeStore.ts
│   │   │   │   │   │       │   └── useViewFilterLinkContext.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── Chart/
│   │   │   │   │   │   │   ├── Chart.tsx
│   │   │   │   │   │   │   ├── bar.ts
│   │   │   │   │   │   │   ├── base.ts
│   │   │   │   │   │   │   ├── createChart.ts
│   │   │   │   │   │   │   ├── line.tsx
│   │   │   │   │   │   │   ├── pie.tsx
│   │   │   │   │   │   │   └── type.ts
│   │   │   │   │   │   ├── CopyButton.tsx
│   │   │   │   │   │   ├── DownloadProgressToast.tsx
│   │   │   │   │   │   ├── LanguagePicker.tsx
│   │   │   │   │   │   ├── LicenseExpiryBanner.tsx
│   │   │   │   │   │   ├── MenuDeleteItem.tsx
│   │   │   │   │   │   ├── PublicOperateButton.tsx
│   │   │   │   │   │   ├── ShareSelectSpaceDialog.tsx
│   │   │   │   │   │   ├── SideBarFooter.tsx
│   │   │   │   │   │   ├── SpaceSettingContainer.tsx
│   │   │   │   │   │   ├── TemplateSelectSpaceDialog.tsx
│   │   │   │   │   │   ├── ThemePicker.tsx
│   │   │   │   │   │   ├── Welcom.tsx
│   │   │   │   │   │   ├── billing/
│   │   │   │   │   │   │   ├── Level.tsx
│   │   │   │   │   │   │   ├── LevelWithUpgrade.tsx
│   │   │   │   │   │   │   ├── Status.tsx
│   │   │   │   │   │   │   ├── UpgradeWrapper.tsx
│   │   │   │   │   │   │   └── UsageLimitModal.tsx
│   │   │   │   │   │   ├── collaborator/
│   │   │   │   │   │   │   ├── share/
│   │   │   │   │   │   │   │   ├── CollaboratorsDialog.tsx
│   │   │   │   │   │   │   │   ├── ShareBaseContent.tsx
│   │   │   │   │   │   │   │   ├── ShareBaseDialog.tsx
│   │   │   │   │   │   │   │   ├── ShareBasePopover.tsx
│   │   │   │   │   │   │   │   └── common/
│   │   │   │   │   │   │   │       ├── AuthorityTips.tsx
│   │   │   │   │   │   │   │       ├── CollaboratorButton.tsx
│   │   │   │   │   │   │   │       ├── CollaboratorTable.tsx
│   │   │   │   │   │   │   │       ├── DebounceInput.tsx
│   │   │   │   │   │   │   │       ├── EmailContent.tsx
│   │   │   │   │   │   │   │       ├── Header.tsx
│   │   │   │   │   │   │   │       ├── InviteEmailButton.tsx
│   │   │   │   │   │   │   │       ├── InviteLinkButton.tsx
│   │   │   │   │   │   │   │       ├── InviteOrgButton.tsx
│   │   │   │   │   │   │   │       ├── LinkContent.tsx
│   │   │   │   │   │   │   │       ├── OrgContent.tsx
│   │   │   │   │   │   │   │       └── PreviewCollaborators.tsx
│   │   │   │   │   │   │   └── space/
│   │   │   │   │   │   │       ├── InviteSpaceContent.tsx
│   │   │   │   │   │   │       └── InviteSpacePopover.tsx
│   │   │   │   │   │   ├── collaborator-manage/
│   │   │   │   │   │   │   ├── base/
│   │   │   │   │   │   │   │   ├── BaseInvite.tsx
│   │   │   │   │   │   │   │   ├── BaseInviteLink.tsx
│   │   │   │   │   │   │   │   └── useFilteredRoleStatic.ts
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── Collaborator.tsx
│   │   │   │   │   │   │   │   ├── CollaboratorAdd.tsx
│   │   │   │   │   │   │   │   ├── CollaboratorItem.tsx
│   │   │   │   │   │   │   │   ├── CollaboratorList.tsx
│   │   │   │   │   │   │   │   ├── Invite.tsx
│   │   │   │   │   │   │   │   ├── InviteLinkItem.tsx
│   │   │   │   │   │   │   │   └── RoleSelect.tsx
│   │   │   │   │   │   │   ├── space/
│   │   │   │   │   │   │   │   ├── Collaborators.tsx
│   │   │   │   │   │   │   │   ├── SpaceInvite.tsx
│   │   │   │   │   │   │   │   ├── SpaceInviteLink.tsx
│   │   │   │   │   │   │   │   └── useFilteredRoleStatic.ts
│   │   │   │   │   │   │   ├── space-inner/
│   │   │   │   │   │   │   │   └── Collaborators.tsx
│   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   ├── useRoleStatic.ts
│   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   ├── download-attachments/
│   │   │   │   │   │   │   ├── CellDownloadHandler.tsx
│   │   │   │   │   │   │   ├── DownloadAllAttachmentsDialog.tsx
│   │   │   │   │   │   │   ├── DownloadContent.tsx
│   │   │   │   │   │   │   ├── DynamicDownloadContent.tsx
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── useDownloadAttachmentsStore.ts
│   │   │   │   │   │   ├── emoji/
│   │   │   │   │   │   │   ├── Emoji.tsx
│   │   │   │   │   │   │   └── EmojiPicker.tsx
│   │   │   │   │   │   ├── expand-record-container/
│   │   │   │   │   │   │   ├── ExpandRecordContainer.tsx
│   │   │   │   │   │   │   ├── ExpandRecordContainerBase.tsx
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── field-setting/
│   │   │   │   │   │   │   ├── DefaultValue.tsx
│   │   │   │   │   │   │   ├── DynamicFieldEditor.tsx
│   │   │   │   │   │   │   ├── FieldEditor.spec.tsx
│   │   │   │   │   │   │   ├── FieldEditor.tsx
│   │   │   │   │   │   │   ├── FieldOptions.tsx
│   │   │   │   │   │   │   ├── FieldSetting.tsx
│   │   │   │   │   │   │   ├── SelectFieldType.tsx
│   │   │   │   │   │   │   ├── SelectTable.tsx
│   │   │   │   │   │   │   ├── SystemInfo.tsx
│   │   │   │   │   │   │   ├── dialog/
│   │   │   │   │   │   │   │   └── AiAutoFillDialog.tsx
│   │   │   │   │   │   │   ├── field-ai-config/
│   │   │   │   │   │   │   │   ├── AttachmentFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── DateFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── FieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── MultipleSelectFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── RatingFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── SingleSelectFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── TextFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   │   ├── field-select/
│   │   │   │   │   │   │   │   │   │   ├── FieldSelect.tsx
│   │   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   └── prompt-editor/
│   │   │   │   │   │   │   │   │       ├── PromptEditor.tsx
│   │   │   │   │   │   │   │   │       ├── PromptEditorContainer.tsx
│   │   │   │   │   │   │   │   │       ├── extensions/
│   │   │   │   │   │   │   │   │       │   ├── index.ts
│   │   │   │   │   │   │   │   │       │   ├── theme.ts
│   │   │   │   │   │   │   │   │       │   └── variable.ts
│   │   │   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── field-delete-confirm-dialog/
│   │   │   │   │   │   │   │   ├── AffectedFieldsList.tsx
│   │   │   │   │   │   │   │   ├── FieldDeleteConfirmDialog.tsx
│   │   │   │   │   │   │   │   ├── FieldSelectionList.tsx
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   │   └── useDeleteAnalysis.ts
│   │   │   │   │   │   │   ├── field-validation/
│   │   │   │   │   │   │   │   └── FieldValidation.tsx
│   │   │   │   │   │   │   ├── formatting/
│   │   │   │   │   │   │   │   ├── DatetimeFormatting.tsx
│   │   │   │   │   │   │   │   ├── NumberFormatting.tsx
│   │   │   │   │   │   │   │   ├── TimeZoneFormatting.tsx
│   │   │   │   │   │   │   │   └── UnionFormatting.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── useDefaultFieldName.ts
│   │   │   │   │   │   │   │   ├── useUpdateConditionalLookupOptions.ts
│   │   │   │   │   │   │   │   ├── useUpdateLookupOptions.spec.ts
│   │   │   │   │   │   │   │   └── useUpdateLookupOptions.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── lookup-options/
│   │   │   │   │   │   │   │   ├── LookupFilterOptions.tsx
│   │   │   │   │   │   │   │   └── LookupOptions.tsx
│   │   │   │   │   │   │   ├── options/
│   │   │   │   │   │   │   │   ├── ButtonOptions.tsx
│   │   │   │   │   │   │   │   ├── CheckboxOptions.tsx
│   │   │   │   │   │   │   │   ├── ConditionalLookupOptions.tsx
│   │   │   │   │   │   │   │   ├── ConditionalRollupOptions.tsx
│   │   │   │   │   │   │   │   ├── CreatedTimeOptions.tsx
│   │   │   │   │   │   │   │   ├── DateOptions.tsx
│   │   │   │   │   │   │   │   ├── FormulaOptions.tsx
│   │   │   │   │   │   │   │   ├── LastModifiedByOptions.tsx
│   │   │   │   │   │   │   │   ├── LastModifiedTimeOptions.tsx
│   │   │   │   │   │   │   │   ├── LinkOptions/
│   │   │   │   │   │   │   │   │   ├── LinkOptions.tsx
│   │   │   │   │   │   │   │   │   ├── MoreLinkOptions.tsx
│   │   │   │   │   │   │   │   │   ├── SelectTable.tsx
│   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   ├── LinkedRecordSortLimitConfig.tsx
│   │   │   │   │   │   │   │   ├── LongTextOptions.tsx
│   │   │   │   │   │   │   │   ├── NumberOptions.tsx
│   │   │   │   │   │   │   │   ├── RatingOptions.tsx
│   │   │   │   │   │   │   │   ├── RollupOptions.tsx
│   │   │   │   │   │   │   │   ├── SelectOptions/
│   │   │   │   │   │   │   │   │   ├── ChoiceItem.tsx
│   │   │   │   │   │   │   │   │   ├── ColorPicker.tsx
│   │   │   │   │   │   │   │   │   ├── SelectDefaultValue.tsx
│   │   │   │   │   │   │   │   │   ├── SelectOptions.tsx
│   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   ├── SingleLineTextOptions.tsx
│   │   │   │   │   │   │   │   └── UserOptions.tsx
│   │   │   │   │   │   │   ├── show-as/
│   │   │   │   │   │   │   │   ├── MultiNumberShowAs.tsx
│   │   │   │   │   │   │   │   ├── SingleLineTextShowAs.tsx
│   │   │   │   │   │   │   │   ├── SingleNumberShowAs.tsx
│   │   │   │   │   │   │   │   └── UnionShowAs.tsx
│   │   │   │   │   │   │   ├── type.ts
│   │   │   │   │   │   │   └── useFieldTypeSubtitle.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── notifications/
│   │   │   │   │   │   │   ├── NotificationActionBar.tsx
│   │   │   │   │   │   │   ├── NotificationIcon.tsx
│   │   │   │   │   │   │   ├── NotificationItem.tsx
│   │   │   │   │   │   │   ├── NotificationList.tsx
│   │   │   │   │   │   │   ├── NotificationsManage.tsx
│   │   │   │   │   │   │   └── notification-component/
│   │   │   │   │   │   │       ├── LinkNotification.tsx
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── oauth/
│   │   │   │   │   │   │   ├── OAuthLogo.tsx
│   │   │   │   │   │   │   └── OAuthScope.tsx
│   │   │   │   │   │   ├── plugin/
│   │   │   │   │   │   │   ├── ComponentPluginRender.tsx
│   │   │   │   │   │   │   ├── IframePluginRender.tsx
│   │   │   │   │   │   │   ├── PluginCenterDialog.tsx
│   │   │   │   │   │   │   ├── PluginContent.tsx
│   │   │   │   │   │   │   ├── PluginDetail.tsx
│   │   │   │   │   │   │   ├── PluginHeader.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── iframe-url/
│   │   │   │   │   │   │   │   │   ├── useIframeUrl.tsx
│   │   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   │   ├── useIframeSize.tsx
│   │   │   │   │   │   │   │   ├── useSelection.ts
│   │   │   │   │   │   │   │   ├── useSyncBasePermissions.ts
│   │   │   │   │   │   │   │   ├── useSyncSelection.ts
│   │   │   │   │   │   │   │   ├── useSyncUIConfig.ts
│   │   │   │   │   │   │   │   ├── useSyncUrlParams.tsx
│   │   │   │   │   │   │   │   ├── useUIConfig.ts
│   │   │   │   │   │   │   │   ├── useUIEvent.ts
│   │   │   │   │   │   │   │   ├── useUrlParams.ts
│   │   │   │   │   │   │   │   ├── useUtilsEvent.ts
│   │   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │   │       └── getSelectionRecords.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── plugin-context-menu/
│   │   │   │   │   │   │   ├── PluginContextMenu.tsx
│   │   │   │   │   │   │   ├── PluginContextMenuManageDialog.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── FloatPlugin.tsx
│   │   │   │   │   │   │   │   ├── useFloatPluginPosition.tsx
│   │   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │   │       └── position.ts
│   │   │   │   │   │   │   └── useActiveMenuPlugin.ts
│   │   │   │   │   │   ├── plugin-panel/
│   │   │   │   │   │   │   ├── PluginLayout.tsx
│   │   │   │   │   │   │   ├── PluginPanel.tsx
│   │   │   │   │   │   │   ├── PluginPanelContainer.tsx
│   │   │   │   │   │   │   ├── PluginPanelEmpty.tsx
│   │   │   │   │   │   │   ├── PluginPanelHeader.tsx
│   │   │   │   │   │   │   ├── PluginPanelSelector.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── CreatePluginDialog.tsx
│   │   │   │   │   │   │   │   ├── CreatePluginPanelDialog.tsx
│   │   │   │   │   │   │   │   └── PluginItem.tsx
│   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │       ├── useActivePluginPanelId.tsx
│   │   │   │   │   │   │       ├── usePluginPanelStorage.ts
│   │   │   │   │   │   │       └── usePluginPanelStore.ts
│   │   │   │   │   │   ├── setting/
│   │   │   │   │   │   │   ├── Account.tsx
│   │   │   │   │   │   │   ├── InteractionSelect.tsx
│   │   │   │   │   │   │   ├── Notifications.tsx
│   │   │   │   │   │   │   ├── SettingDialog.tsx
│   │   │   │   │   │   │   ├── SettingTabShell.tsx
│   │   │   │   │   │   │   ├── System.tsx
│   │   │   │   │   │   │   ├── account/
│   │   │   │   │   │   │   │   ├── AddPassword.tsx
│   │   │   │   │   │   │   │   ├── ChangeEmailDialog.tsx
│   │   │   │   │   │   │   │   ├── ChangePasswordDialog.tsx
│   │   │   │   │   │   │   │   └── DeleteAccountDialog.tsx
│   │   │   │   │   │   │   ├── integration/
│   │   │   │   │   │   │   │   ├── Integration.tsx
│   │   │   │   │   │   │   │   ├── common/
│   │   │   │   │   │   │   │   │   ├── Container.tsx
│   │   │   │   │   │   │   │   │   └── Header.tsx
│   │   │   │   │   │   │   │   ├── third-party-integrations/
│   │   │   │   │   │   │   │   │   ├── Content.tsx
│   │   │   │   │   │   │   │   │   ├── Detail.tsx
│   │   │   │   │   │   │   │   │   ├── List.tsx
│   │   │   │   │   │   │   │   │   └── RevokeButton.tsx
│   │   │   │   │   │   │   │   └── user-integration/
│   │   │   │   │   │   │   │       ├── ActionMenu.tsx
│   │   │   │   │   │   │   │       ├── Content.tsx
│   │   │   │   │   │   │   │       ├── List.tsx
│   │   │   │   │   │   │   │       ├── NewIntegration.tsx
│   │   │   │   │   │   │   │       ├── Rename.tsx
│   │   │   │   │   │   │   │       └── provider/
│   │   │   │   │   │   │   │           ├── EmailItem.tsx
│   │   │   │   │   │   │   │           └── SlackItem.tsx
│   │   │   │   │   │   │   ├── oauth-app/
│   │   │   │   │   │   │   │   ├── OAuthAppSection.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── personal-access-token/
│   │   │   │   │   │   │   │   ├── PersonalAccessTokenSection.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   └── useSettingStore.ts
│   │   │   │   │   │   ├── sidebar/
│   │   │   │   │   │   │   ├── SideBarScript.tsx
│   │   │   │   │   │   │   ├── Sidebar.tsx
│   │   │   │   │   │   │   ├── SidebarContent.tsx
│   │   │   │   │   │   │   ├── SidebarHeader.tsx
│   │   │   │   │   │   │   ├── SidebarHeaderLeft.tsx
│   │   │   │   │   │   │   ├── useChatPanelStore.ts
│   │   │   │   │   │   │   └── useSidebarStore.ts
│   │   │   │   │   │   ├── space/
│   │   │   │   │   │   │   ├── CollaboratorAvatars.tsx
│   │   │   │   │   │   │   ├── CreateBaseModal.tsx
│   │   │   │   │   │   │   ├── DeleteSpaceConfirm.tsx
│   │   │   │   │   │   │   ├── SpaceActionBar.tsx
│   │   │   │   │   │   │   ├── SpaceAvatar.tsx
│   │   │   │   │   │   │   ├── SpaceRenaming.tsx
│   │   │   │   │   │   │   └── template/
│   │   │   │   │   │   │       ├── CategoryMenu.tsx
│   │   │   │   │   │   │       ├── CategoryMenuItem.tsx
│   │   │   │   │   │   │       ├── RecommendTemplate.tsx
│   │   │   │   │   │   │       ├── TemplateCard.tsx
│   │   │   │   │   │   │       ├── TemplateDetail.tsx
│   │   │   │   │   │   │       ├── TemplateList.tsx
│   │   │   │   │   │   │       ├── TemplateMain.tsx
│   │   │   │   │   │   │       ├── TemplateModal.tsx
│   │   │   │   │   │   │       ├── TemplatePreview.tsx
│   │   │   │   │   │   │       ├── TemplatePreviewSheet.tsx
│   │   │   │   │   │   │       ├── TemplateSheet.tsx
│   │   │   │   │   │   │       ├── context.ts
│   │   │   │   │   │   │       ├── hooks/
│   │   │   │   │   │   │       │   └── use-space-id.ts
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── toggle-side-bar/
│   │   │   │   │   │   │   ├── HoverWrapper.tsx
│   │   │   │   │   │   │   ├── SheetWrapper.tsx
│   │   │   │   │   │   │   └── constant.ts
│   │   │   │   │   │   ├── upload-progress-panel/
│   │   │   │   │   │   │   ├── TaskItem.tsx
│   │   │   │   │   │   │   ├── UploadProgressBubble.tsx
│   │   │   │   │   │   │   ├── UploadProgressPanel.tsx
│   │   │   │   │   │   │   ├── UploadTaskList.tsx
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── user/
│   │   │   │   │   │   │   ├── UserAvatar.tsx
│   │   │   │   │   │   │   └── UserNav.tsx
│   │   │   │   │   │   └── user-integration/
│   │   │   │   │   │       ├── ProviderLogo.tsx
│   │   │   │   │   │       └── utils.ts
│   │   │   │   │   ├── context/
│   │   │   │   │   │   ├── ShareContext.tsx
│   │   │   │   │   │   └── StaticTextRegistryProvider.tsx
│   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   ├── DashboardGrid.tsx
│   │   │   │   │   │   ├── DashboardHeader.tsx
│   │   │   │   │   │   ├── DashboardMain.tsx
│   │   │   │   │   │   ├── EmptyDashboard.tsx
│   │   │   │   │   │   ├── Pages.tsx
│   │   │   │   │   │   ├── TestBaseQuery.tsx
│   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   ├── AddPluginDialog.tsx
│   │   │   │   │   │   │   ├── CreateDashboardDialog.tsx
│   │   │   │   │   │   │   ├── DashboardSwitcher.tsx
│   │   │   │   │   │   │   └── PluginItem.tsx
│   │   │   │   │   │   └── hooks/
│   │   │   │   │   │       └── useIsExpandPlugin.ts
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── useAI.ts
│   │   │   │   │   │   ├── useAutoFavicon.tsx
│   │   │   │   │   │   ├── useBaseResource.ts
│   │   │   │   │   │   ├── useBaseUsage.ts
│   │   │   │   │   │   ├── useBillingLevel.ts
│   │   │   │   │   │   ├── useBillingLevelConfig.ts
│   │   │   │   │   │   ├── useBrand.tsx
│   │   │   │   │   │   ├── useCutDown.ts
│   │   │   │   │   │   ├── useDisableAIAction.ts
│   │   │   │   │   │   ├── useDownLoad.ts
│   │   │   │   │   │   ├── useEnv.ts
│   │   │   │   │   │   ├── useInitializationZodI18n.ts
│   │   │   │   │   │   ├── useIsCloud.ts
│   │   │   │   │   │   ├── useIsCommunity.ts
│   │   │   │   │   │   ├── useIsEE.ts
│   │   │   │   │   │   ├── useIsInIframe.ts
│   │   │   │   │   │   ├── usePreviewUrl.ts
│   │   │   │   │   │   ├── useSdkLocale.ts
│   │   │   │   │   │   └── useSetting.ts
│   │   │   │   │   ├── layouts/
│   │   │   │   │   │   ├── AdminLayout.tsx
│   │   │   │   │   │   ├── AppLayout.tsx
│   │   │   │   │   │   ├── BaseLayout.tsx
│   │   │   │   │   │   ├── SettingLayout.tsx
│   │   │   │   │   │   ├── ShareBaseLayout.tsx
│   │   │   │   │   │   ├── SharedBaseLayout.tsx
│   │   │   │   │   │   ├── SpaceInnerLayout.tsx
│   │   │   │   │   │   ├── SpaceLayout.tsx
│   │   │   │   │   │   ├── SpacePageTitle.tsx
│   │   │   │   │   │   ├── SpaceSettingLayout.tsx
│   │   │   │   │   │   ├── SpaceTrashLayout.tsx
│   │   │   │   │   │   ├── TemplateBaseLayout.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── useSettingRoute.tsx
│   │   │   │   │   ├── utils/
│   │   │   │   │   │   ├── clipboard.spec.ts
│   │   │   │   │   │   ├── clipboard.ts
│   │   │   │   │   │   ├── download-all-attachments.ts
│   │   │   │   │   │   ├── file.ts
│   │   │   │   │   │   ├── get-mod-key-str.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── init-axios.ts
│   │   │   │   │   │   ├── is-https.ts
│   │   │   │   │   │   ├── is-local.ts
│   │   │   │   │   │   └── uploadFile.ts
│   │   │   │   │   └── waitlist/
│   │   │   │   │       └── WaitlistPage.tsx
│   │   │   │   ├── auth/
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── DescContent.tsx
│   │   │   │   │   │   ├── LayoutMain.tsx
│   │   │   │   │   │   ├── Rectangles.tsx
│   │   │   │   │   │   ├── SendVerificationButton.tsx
│   │   │   │   │   │   ├── SignForm.tsx
│   │   │   │   │   │   ├── SocialAuth.tsx
│   │   │   │   │   │   ├── TeableFooter.tsx
│   │   │   │   │   │   ├── Terms.tsx
│   │   │   │   │   │   └── TurnstileWidget.tsx
│   │   │   │   │   ├── pages/
│   │   │   │   │   │   ├── ForgetPasswordPage.tsx
│   │   │   │   │   │   ├── LoginPage.tsx
│   │   │   │   │   │   └── ResetPasswordPage.tsx
│   │   │   │   │   └── useDisallowSignUp.ts
│   │   │   │   ├── i18n/
│   │   │   │   │   ├── auth.config.ts
│   │   │   │   │   ├── automation.tsx
│   │   │   │   │   ├── base-all.config.ts
│   │   │   │   │   ├── base.config.ts
│   │   │   │   │   ├── dashboard.config.ts
│   │   │   │   │   ├── developer.config.ts
│   │   │   │   │   ├── oauth-app.config.ts
│   │   │   │   │   ├── personal-access-token.config.ts
│   │   │   │   │   ├── setting-plugin.config.ts
│   │   │   │   │   ├── setting.config.ts
│   │   │   │   │   ├── share.config.ts
│   │   │   │   │   ├── space.config.ts
│   │   │   │   │   ├── system.config.ts
│   │   │   │   │   └── table.config.ts
│   │   │   │   └── system/
│   │   │   │       └── pages/
│   │   │   │           ├── ErrorPage.tsx
│   │   │   │           ├── ForbiddenPage.tsx
│   │   │   │           ├── HttpErrorPage.tsx
│   │   │   │           ├── IllustrationPage.tsx
│   │   │   │           ├── NotFoundPage.tsx
│   │   │   │           ├── PaymentRequired.tsx
│   │   │   │           ├── __tests__/
│   │   │   │           │   ├── ErrorPage.test.tsx
│   │   │   │           │   └── NotFoundPage.test.tsx
│   │   │   │           └── index.ts
│   │   │   ├── lib/
│   │   │   │   ├── emoji-color.ts
│   │   │   │   ├── ensureLogin.ts
│   │   │   │   ├── get-brand.ts
│   │   │   │   ├── handleBase.ts
│   │   │   │   ├── i18n/
│   │   │   │   │   ├── I18nNamespace.types.ts
│   │   │   │   │   ├── acceptHeader.ts
│   │   │   │   │   ├── getLocale.ts
│   │   │   │   │   ├── getServerSideTranslations.ts
│   │   │   │   │   ├── getTranslationsProps.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── staticPageLocale.ts
│   │   │   │   ├── server-env.ts
│   │   │   │   ├── space-role-checker.ts
│   │   │   │   ├── type.ts
│   │   │   │   ├── view-pages-data.ts
│   │   │   │   ├── withAuthSSR.ts
│   │   │   │   └── withEnv.ts
│   │   │   ├── pages/
│   │   │   │   ├── 402.tsx
│   │   │   │   ├── 403.tsx
│   │   │   │   ├── 404.tsx
│   │   │   │   ├── _app.tsx
│   │   │   │   ├── _document.tsx
│   │   │   │   ├── _error.tsx
│   │   │   │   ├── _monitor/
│   │   │   │   │   ├── preview/
│   │   │   │   │   │   └── error-page.tsx
│   │   │   │   │   └── sentry/
│   │   │   │   │       ├── csr-page.tsx
│   │   │   │   │       └── ssr-page.tsx
│   │   │   │   ├── admin/
│   │   │   │   │   ├── setting.tsx
│   │   │   │   │   └── template.tsx
│   │   │   │   ├── api/
│   │   │   │   │   └── _monitor/
│   │   │   │   │       ├── healthcheck.ts
│   │   │   │   │       └── sentry.ts
│   │   │   │   ├── auth/
│   │   │   │   │   ├── forget-password.tsx
│   │   │   │   │   ├── login.tsx
│   │   │   │   │   ├── reset-password.tsx
│   │   │   │   │   └── signup.tsx
│   │   │   │   ├── base/
│   │   │   │   │   └── [baseId]/
│   │   │   │   │       ├── [[...slug]].tsx
│   │   │   │   │       ├── authority-matrix.tsx
│   │   │   │   │       ├── design.tsx
│   │   │   │   │       └── trash.tsx
│   │   │   │   ├── developer/
│   │   │   │   │   └── tool/
│   │   │   │   │       └── query-builder.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   ├── invite/
│   │   │   │   │   └── index.tsx
│   │   │   │   ├── oauth/
│   │   │   │   │   └── decision.tsx
│   │   │   │   ├── setting/
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── oauth-app.tsx
│   │   │   │   │   ├── personal-access-token.tsx
│   │   │   │   │   └── plugin.tsx
│   │   │   │   ├── share/
│   │   │   │   │   └── [shareId]/
│   │   │   │   │       ├── base/
│   │   │   │   │       │   ├── [baseId]/
│   │   │   │   │       │   │   └── [[...slug]].tsx
│   │   │   │   │       │   ├── auth.tsx
│   │   │   │   │       │   └── index.tsx
│   │   │   │   │       └── view/
│   │   │   │   │           ├── auth.tsx
│   │   │   │   │           └── index.tsx
│   │   │   │   ├── space/
│   │   │   │   │   ├── [spaceId]/
│   │   │   │   │   │   └── setting/
│   │   │   │   │   │       ├── collaborator.tsx
│   │   │   │   │   │       └── general.tsx
│   │   │   │   │   ├── [spaceId].tsx
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── shared-base.tsx
│   │   │   │   │   └── trash.tsx
│   │   │   │   ├── t/
│   │   │   │   │   └── [identifier].tsx
│   │   │   │   └── waitlist/
│   │   │   │       └── index.tsx
│   │   │   ├── proxy.ts
│   │   │   ├── store/
│   │   │   │   ├── message.ts
│   │   │   │   └── user.ts
│   │   │   ├── styles/
│   │   │   │   ├── github-markdown.css
│   │   │   │   └── global.css
│   │   │   ├── themes/
│   │   │   │   ├── colors/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── shared/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── colors.test.ts
│   │   │   │   │   ├── browser-fonts.js
│   │   │   │   │   └── colors.js
│   │   │   │   ├── tailwind/
│   │   │   │   │   └── tailwind.theme.js
│   │   │   │   ├── type.ts
│   │   │   │   └── utils.ts
│   │   │   └── types.d/
│   │   │       ├── i18next.d.ts
│   │   │       ├── next-i18next.d.ts
│   │   │       ├── react-svgr.d.ts
│   │   │       └── umami.d.ts
│   │   ├── tailwind.config.js
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.scripts.json
│   │   ├── turbopack-empty-stub.js
│   │   └── vitest.config.ts
│   └── playground/
│       ├── .cta.json
│       ├── .cursorrules
│       ├── .gitignore
│       ├── .vscode/
│       │   └── settings.json
│       ├── README.md
│       ├── components.json
│       ├── package.json
│       ├── src/
│       │   ├── components/
│       │   │   ├── playground/
│       │   │   │   ├── ComputedTasksPanel.tsx
│       │   │   │   ├── CreateTableDropdown.tsx
│       │   │   │   ├── ExplainResultPanel.tsx
│       │   │   │   ├── FieldCreateDialog.tsx
│       │   │   │   ├── FieldForm.tsx
│       │   │   │   ├── FieldFormOptions.tsx
│       │   │   │   ├── ImportCsvDialog.tsx
│       │   │   │   ├── LinkFieldLabel.tsx
│       │   │   │   ├── LogPanel.tsx
│       │   │   │   ├── MetaCheckPanel.tsx
│       │   │   │   ├── PlaygroundRecordRoute.tsx
│       │   │   │   ├── PlaygroundShell.tsx
│       │   │   │   ├── PlaygroundTableRoute.tsx
│       │   │   │   ├── RecordCreateDialog.tsx
│       │   │   │   ├── RecordDeleteDialog.tsx
│       │   │   │   ├── RecordUpdateDialog.tsx
│       │   │   │   ├── SchemaCheckPanel.tsx
│       │   │   │   ├── TableMetaPage.tsx
│       │   │   │   ├── UnderlyingDataPanel.tsx
│       │   │   │   ├── field-inputs/
│       │   │   │   │   ├── CheckboxFieldInput.tsx
│       │   │   │   │   ├── DateFieldInput.tsx
│       │   │   │   │   ├── DisabledFieldInput.tsx
│       │   │   │   │   ├── LinkFieldInput.tsx
│       │   │   │   │   ├── NumberFieldInput.tsx
│       │   │   │   │   ├── RatingFieldInput.tsx
│       │   │   │   │   ├── SelectFieldInput.tsx
│       │   │   │   │   ├── TextFieldInput.tsx
│       │   │   │   │   ├── index.tsx
│       │   │   │   │   └── types.ts
│       │   │   │   ├── field-options/
│       │   │   │   │   ├── ButtonOptions.tsx
│       │   │   │   │   ├── CheckboxOptions.tsx
│       │   │   │   │   ├── ConditionBuilder.tsx
│       │   │   │   │   ├── ConditionalLookupOptions.tsx
│       │   │   │   │   ├── ConditionalRollupOptions.tsx
│       │   │   │   │   ├── DateOptions.tsx
│       │   │   │   │   ├── FormulaOptions.tsx
│       │   │   │   │   ├── LinkOptions.tsx
│       │   │   │   │   ├── LookupOptions.tsx
│       │   │   │   │   ├── NumberOptions.tsx
│       │   │   │   │   ├── RatingOptions.tsx
│       │   │   │   │   ├── RollupOptions.tsx
│       │   │   │   │   ├── SelectOptions.tsx
│       │   │   │   │   ├── SingleLineTextOptions.tsx
│       │   │   │   │   └── UserOptions.tsx
│       │   │   │   ├── fieldOptionsVisitor.tsx
│       │   │   │   └── recordValueVisitor.tsx
│       │   │   └── ui/
│       │   │       ├── alert-dialog.tsx
│       │   │       ├── badge.tsx
│       │   │       ├── button.tsx
│       │   │       ├── calendar.tsx
│       │   │       ├── card.tsx
│       │   │       ├── checkbox.tsx
│       │   │       ├── command.tsx
│       │   │       ├── context-menu.tsx
│       │   │       ├── data-table.tsx
│       │   │       ├── date-picker.tsx
│       │   │       ├── dialog.tsx
│       │   │       ├── dropdown-menu.tsx
│       │   │       ├── form.tsx
│       │   │       ├── input.tsx
│       │   │       ├── label.tsx
│       │   │       ├── popover.tsx
│       │   │       ├── radio-group.tsx
│       │   │       ├── scroll-area.tsx
│       │   │       ├── select.tsx
│       │   │       ├── separator.tsx
│       │   │       ├── sheet.tsx
│       │   │       ├── sidebar.tsx
│       │   │       ├── skeleton.tsx
│       │   │       ├── slider.tsx
│       │   │       ├── switch.tsx
│       │   │       ├── table.tsx
│       │   │       ├── tabs.tsx
│       │   │       ├── textarea.tsx
│       │   │       └── tooltip.tsx
│       │   ├── hooks/
│       │   │   ├── use-mobile.ts
│       │   │   ├── useLogStream.ts
│       │   │   ├── useRecord.ts
│       │   │   └── useRecords.ts
│       │   ├── integrations/
│       │   │   ├── otel/
│       │   │   │   └── client.ts
│       │   │   └── tanstack-query/
│       │   │       ├── devtools.tsx
│       │   │       └── root-provider.tsx
│       │   ├── lib/
│       │   │   ├── broadcastChannel.ts
│       │   │   ├── fieldTypeIcons.ts
│       │   │   ├── nuqs/
│       │   │   │   └── tanstackRouterAdapter.tsx
│       │   │   ├── orpc/
│       │   │   │   ├── OrpcClientContext.tsx
│       │   │   │   ├── RemoteOrpcProvider.tsx
│       │   │   │   └── SandboxOrpcProvider.tsx
│       │   │   ├── orpcClient.ts
│       │   │   ├── playground/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── databaseUrl.ts
│       │   │   │   └── environment.ts
│       │   │   ├── sandboxContainer.ts
│       │   │   ├── sandboxOrpcClient.ts
│       │   │   ├── shareDb.ts
│       │   │   └── utils.ts
│       │   ├── polyfill.ts
│       │   ├── router.tsx
│       │   ├── routes/
│       │   │   ├── $baseId.$tableId.$recordId.tsx
│       │   │   ├── $baseId.$tableId.tsx
│       │   │   ├── $baseId.tsx
│       │   │   ├── __root.tsx
│       │   │   ├── api.computed-tasks.$taskId.retry-now.ts
│       │   │   ├── api.computed-tasks.dead-letters.$taskId.replay.ts
│       │   │   ├── api.computed-tasks.dead-letters.$taskId.ts
│       │   │   ├── api.computed-tasks.dead-letters.ts
│       │   │   ├── api.computed-tasks.outbox.ts
│       │   │   ├── api.db.check.ts
│       │   │   ├── api.logs.stream.ts
│       │   │   ├── api.meta.$tableId.check.stream.ts
│       │   │   ├── api.rpc.$.ts
│       │   │   ├── api.schema.$tableId.check.stream.ts
│       │   │   ├── api.underlying.$tableId.ts
│       │   │   ├── computed-tasks.tsx
│       │   │   ├── index.tsx
│       │   │   └── sandbox/
│       │   │       ├── $baseId.$tableId.$recordId.tsx
│       │   │       ├── $baseId.$tableId.tsx
│       │   │       ├── $baseId.tsx
│       │   │       └── index.tsx
│       │   ├── server/
│       │   │   ├── otel.ts
│       │   │   ├── playgroundContainer.ts
│       │   │   ├── playgroundDbContext.ts
│       │   │   ├── playgroundLogger.ts
│       │   │   ├── shareDbServer.ts
│       │   │   ├── traceContext.ts
│       │   │   ├── traceResponseHeaders.ts
│       │   │   └── v2OrpcRouter.ts
│       │   ├── server.ts
│       │   ├── styles.css
│       │   └── types/
│       │       └── sharedb-pubsub.d.ts
│       ├── tsconfig.json
│       └── vite.config.ts
├── commitlint.config.js
├── crowdin.yml
├── docker-bake.hcl
├── dockers/
│   ├── cache-redis.yml
│   ├── database-postgres.yml
│   ├── examples/
│   │   ├── cluster/
│   │   │   ├── README.md
│   │   │   ├── docker-compose.yaml
│   │   │   └── gateway/
│   │   │       └── conf.d/
│   │   │           ├── default.conf
│   │   │           └── minio.conf
│   │   ├── docker-swarm/
│   │   │   ├── README.md
│   │   │   ├── deploy.sh
│   │   │   ├── docker-compose.app.yml
│   │   │   ├── docker-compose.default.yml
│   │   │   ├── docker-compose.gateway.yml
│   │   │   ├── docker-compose.kit.yml
│   │   │   └── gateway/
│   │   │       └── conf.d/
│   │   │           ├── default.conf
│   │   │           └── minio.conf
│   │   └── standalone/
│   │       ├── README.md
│   │       └── docker-compose.yaml
│   ├── integration-test.yml
│   ├── networks.yml
│   ├── storage-minio.yml
│   └── teable/
│       ├── Dockerfile
│       └── Dockerfile.db-migrate
├── dottea/
│   └── .gitignore
├── lint-staged.common.js
├── lint-staged.config.js
├── monorepo.code-workspace
├── package.json
├── packages/
│   ├── common-i18n/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── common-i18n.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── I18nNamespaces.ts
│   │   │   ├── index.ts
│   │   │   └── locales/
│   │   │       ├── de/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── en/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── es/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── fr/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── it/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── ja/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── ru/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── tr/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── uk/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       └── zh/
│   │   │           ├── auth.json
│   │   │           ├── chart.json
│   │   │           ├── common.json
│   │   │           ├── dashboard.json
│   │   │           ├── developer.json
│   │   │           ├── oauth.json
│   │   │           ├── plugin.json
│   │   │           ├── sdk.json
│   │   │           ├── setting.json
│   │   │           ├── share.json
│   │   │           ├── space.json
│   │   │           ├── table.json
│   │   │           ├── token.json
│   │   │           └── zod.json
│   │   └── tsconfig.json
│   ├── core/
│   │   ├── .escheckrc
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── core.iml
│   │   │   └── modules.xml
│   │   ├── .size-limit.cjs
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── array/
│   │   │   │   ├── ArrayUtils.spec.ts
│   │   │   │   ├── ArrayUtils.ts
│   │   │   │   └── index.ts
│   │   │   ├── asserts/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── asserts.test.ts
│   │   │   │   ├── asserts.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── lang.ts
│   │   │   ├── auth/
│   │   │   │   ├── actions.ts
│   │   │   │   ├── anonymous.ts
│   │   │   │   ├── app-robot.ts
│   │   │   │   ├── automation-robot.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── me-tag.ts
│   │   │   │   ├── oauth.ts
│   │   │   │   ├── permission.ts
│   │   │   │   ├── role/
│   │   │   │   │   ├── base.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── share.ts
│   │   │   │   │   ├── space.ts
│   │   │   │   │   ├── table.ts
│   │   │   │   │   ├── template.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── system.ts
│   │   │   │   └── types.ts
│   │   │   ├── convert/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── string-convert.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── nulls-to-undefined.ts
│   │   │   │   └── string-convert.ts
│   │   │   ├── errors/
│   │   │   │   ├── extract-error-message.ts
│   │   │   │   ├── http/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── http-response.types.ts
│   │   │   │   │   ├── http.error.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── formula/
│   │   │   │   ├── errors/
│   │   │   │   │   ├── circular-reference.error.spec.ts
│   │   │   │   │   ├── circular-reference.error.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── evaluate.ts
│   │   │   │   ├── function-aliases.ts
│   │   │   │   ├── function-convertor.interface.ts
│   │   │   │   ├── functions/
│   │   │   │   │   ├── array.spec.ts
│   │   │   │   │   ├── array.ts
│   │   │   │   │   ├── common.ts
│   │   │   │   │   ├── date-time.spec.ts
│   │   │   │   │   ├── date-time.ts
│   │   │   │   │   ├── factory.ts
│   │   │   │   │   ├── logical.spec.ts
│   │   │   │   │   ├── logical.ts
│   │   │   │   │   ├── numeric.spec.ts
│   │   │   │   │   ├── numeric.ts
│   │   │   │   │   ├── system.spec.ts
│   │   │   │   │   ├── system.ts
│   │   │   │   │   ├── text.spec.ts
│   │   │   │   │   └── text.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── typed-value-converter.spec.ts
│   │   │   │   ├── typed-value-converter.ts
│   │   │   │   ├── typed-value.ts
│   │   │   │   ├── visitor.spec.ts
│   │   │   │   └── visitor.ts
│   │   │   ├── index.ts
│   │   │   ├── models/
│   │   │   │   ├── aggregation/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── statistic.spec.ts
│   │   │   │   │   ├── statistic.ts
│   │   │   │   │   └── statistics-func.enum.ts
│   │   │   │   ├── channel.ts
│   │   │   │   ├── field/
│   │   │   │   │   ├── ai-config/
│   │   │   │   │   │   ├── attachment.ts
│   │   │   │   │   │   ├── date.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── multiple-select.ts
│   │   │   │   │   │   ├── rating.ts
│   │   │   │   │   │   ├── single-select.ts
│   │   │   │   │   │   └── text.ts
│   │   │   │   │   ├── button-utils.ts
│   │   │   │   │   ├── cell-value-validation.ts
│   │   │   │   │   ├── color-utils.spec.ts
│   │   │   │   │   ├── color-utils.ts
│   │   │   │   │   ├── colors.ts
│   │   │   │   │   ├── conditional.constants.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── derivate/
│   │   │   │   │   │   ├── abstract/
│   │   │   │   │   │   │   ├── formula.field.abstract.ts
│   │   │   │   │   │   │   ├── select-option.schema.ts
│   │   │   │   │   │   │   ├── select.field.abstract.spec.ts
│   │   │   │   │   │   │   ├── select.field.abstract.ts
│   │   │   │   │   │   │   └── user.field.abstract.ts
│   │   │   │   │   │   ├── attachment-option.schema.ts
│   │   │   │   │   │   ├── attachment.field.spec.ts
│   │   │   │   │   │   ├── attachment.field.ts
│   │   │   │   │   │   ├── auto-number-option.schema.ts
│   │   │   │   │   │   ├── auto-number.field.spec.ts
│   │   │   │   │   │   ├── auto-number.field.ts
│   │   │   │   │   │   ├── button-option.schema.ts
│   │   │   │   │   │   ├── button.field.spec.ts
│   │   │   │   │   │   ├── button.field.ts
│   │   │   │   │   │   ├── checkbox-option.schema.ts
│   │   │   │   │   │   ├── checkbox.field.spec.ts
│   │   │   │   │   │   ├── checkbox.field.ts
│   │   │   │   │   │   ├── conditional-rollup-option.schema.ts
│   │   │   │   │   │   ├── conditional-rollup.field.ts
│   │   │   │   │   │   ├── created-by-option.schema.ts
│   │   │   │   │   │   ├── created-by.field.ts
│   │   │   │   │   │   ├── created-time-option.schema.ts
│   │   │   │   │   │   ├── created-time.field.spec.ts
│   │   │   │   │   │   ├── created-time.field.ts
│   │   │   │   │   │   ├── date-option.schema.ts
│   │   │   │   │   │   ├── date.field.spec.ts
│   │   │   │   │   │   ├── date.field.ts
│   │   │   │   │   │   ├── formula-option.schema.ts
│   │   │   │   │   │   ├── formula.field.spec.ts
│   │   │   │   │   │   ├── formula.field.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── last-modified-by-option.schema.ts
│   │   │   │   │   │   ├── last-modified-by.field.ts
│   │   │   │   │   │   ├── last-modified-time-option.schema.ts
│   │   │   │   │   │   ├── last-modified-time.field.spec.ts
│   │   │   │   │   │   ├── last-modified-time.field.ts
│   │   │   │   │   │   ├── link-option.schema.ts
│   │   │   │   │   │   ├── link.field.spec.ts
│   │   │   │   │   │   ├── link.field.ts
│   │   │   │   │   │   ├── long-text-option.schema.ts
│   │   │   │   │   │   ├── long-text.field.spec.ts
│   │   │   │   │   │   ├── long-text.field.ts
│   │   │   │   │   │   ├── multiple-select.field.spec.ts
│   │   │   │   │   │   ├── multiple-select.field.ts
│   │   │   │   │   │   ├── number-option.schema.ts
│   │   │   │   │   │   ├── number.field.spec.ts
│   │   │   │   │   │   ├── number.field.ts
│   │   │   │   │   │   ├── rating-option.schema.ts
│   │   │   │   │   │   ├── rating.field.spec.ts
│   │   │   │   │   │   ├── rating.field.ts
│   │   │   │   │   │   ├── rollup-option.schema.ts
│   │   │   │   │   │   ├── rollup.field.spec.ts
│   │   │   │   │   │   ├── rollup.field.ts
│   │   │   │   │   │   ├── single-line-text-option.schema.ts
│   │   │   │   │   │   ├── single-line-text.field.spec.ts
│   │   │   │   │   │   ├── single-line-text.field.ts
│   │   │   │   │   │   ├── single-select.field.spec.ts
│   │   │   │   │   │   ├── single-select.field.ts
│   │   │   │   │   │   ├── user-option.schema.ts
│   │   │   │   │   │   ├── user.field.spec.ts
│   │   │   │   │   │   └── user.field.ts
│   │   │   │   │   ├── field-options-validation.spec.ts
│   │   │   │   │   ├── field-unions.schema.ts
│   │   │   │   │   ├── field-validation.ts
│   │   │   │   │   ├── field-visitor.interface.ts
│   │   │   │   │   ├── field.schema.spec.ts
│   │   │   │   │   ├── field.schema.ts
│   │   │   │   │   ├── field.ts
│   │   │   │   │   ├── field.type.ts
│   │   │   │   │   ├── field.util.spec.ts
│   │   │   │   │   ├── field.util.ts
│   │   │   │   │   ├── formatting/
│   │   │   │   │   │   ├── datetime.spec.ts
│   │   │   │   │   │   ├── datetime.ts
│   │   │   │   │   │   ├── index.spec.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── number.spec.ts
│   │   │   │   │   │   ├── number.ts
│   │   │   │   │   │   └── time-zone.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── lookup-options-base.schema.spec.ts
│   │   │   │   │   ├── lookup-options-base.schema.ts
│   │   │   │   │   ├── options.schema.ts
│   │   │   │   │   ├── show-as/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── number.ts
│   │   │   │   │   │   └── text.ts
│   │   │   │   │   ├── utils/
│   │   │   │   │   │   └── get-db-field-type.ts
│   │   │   │   │   ├── zod-error.spec.ts
│   │   │   │   │   └── zod-error.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── notification/
│   │   │   │   │   ├── action-trigger.schema.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── notification.enum.ts
│   │   │   │   │   └── notification.schema.ts
│   │   │   │   ├── op.ts
│   │   │   │   ├── record/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── record.ts
│   │   │   │   ├── table/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── table-domain.spec.ts
│   │   │   │   │   ├── table-domain.ts
│   │   │   │   │   ├── table-fields.spec.ts
│   │   │   │   │   ├── table-fields.ts
│   │   │   │   │   ├── table.ts
│   │   │   │   │   ├── tables.spec.ts
│   │   │   │   │   └── tables.ts
│   │   │   │   └── view/
│   │   │   │       ├── column-meta.schema.ts
│   │   │   │       ├── constant.ts
│   │   │   │       ├── derivate/
│   │   │   │       │   ├── calendar-view-option.schema.ts
│   │   │   │       │   ├── calendar.view.ts
│   │   │   │       │   ├── form-view-option.schema.ts
│   │   │   │       │   ├── form.view.ts
│   │   │   │       │   ├── gallery-view-option.schema.ts
│   │   │   │       │   ├── gallery.view.ts
│   │   │   │       │   ├── grid-view-option.schema.ts
│   │   │   │       │   ├── grid.view.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── kanban-view-option.schema.ts
│   │   │   │       │   ├── kanban.view.ts
│   │   │   │       │   ├── plugin-view-option.schema.ts
│   │   │   │       │   └── plugin.view.ts
│   │   │   │       ├── filter/
│   │   │   │       │   ├── conjunction.ts
│   │   │   │       │   ├── field-reference.spec.ts
│   │   │   │       │   ├── field-reference.ts
│   │   │   │       │   ├── filter-item.ts
│   │   │   │       │   ├── filter.spec.ts
│   │   │   │       │   ├── filter.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── operator.spec.ts
│   │   │   │       │   └── operator.ts
│   │   │   │       ├── group/
│   │   │   │       │   ├── group.ts
│   │   │   │       │   └── index.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── option.schema.spec.ts
│   │   │   │       ├── option.schema.ts
│   │   │   │       ├── query.replace.ts
│   │   │   │       ├── sort/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── sort-func.enum.ts
│   │   │   │       │   ├── sort.schema.spec.ts
│   │   │   │       │   └── sort.ts
│   │   │   │       ├── view.schema.ts
│   │   │   │       └── view.ts
│   │   │   ├── op-builder/
│   │   │   │   ├── common.spec.ts
│   │   │   │   ├── common.ts
│   │   │   │   ├── field/
│   │   │   │   │   ├── add-column-meta.spec.ts
│   │   │   │   │   ├── add-column-meta.ts
│   │   │   │   │   ├── add-field.ts
│   │   │   │   │   ├── delete-column-meta.spec.ts
│   │   │   │   │   ├── delete-column-meta.ts
│   │   │   │   │   ├── field-op-builder.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── set-field-property.spec.ts
│   │   │   │   │   └── set-field-property.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── op-builder.abstract.ts
│   │   │   │   ├── record/
│   │   │   │   │   ├── add-record.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── record-op-builder.ts
│   │   │   │   │   └── set-record.ts
│   │   │   │   ├── table/
│   │   │   │   │   ├── add-table.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── set-table-property.ts
│   │   │   │   │   └── table-op-builder.ts
│   │   │   │   └── view/
│   │   │   │       ├── add-view.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── set-view-property.ts
│   │   │   │       ├── update-view-column-meta.ts
│   │   │   │       └── view-op-builder.ts
│   │   │   ├── query/
│   │   │   │   ├── index.ts
│   │   │   │   ├── json-error.strategy.ts
│   │   │   │   ├── json.visitor.spec.ts
│   │   │   │   ├── json.visitor.ts
│   │   │   │   └── parser/
│   │   │   │       ├── Query.g4
│   │   │   │       ├── Query.interp
│   │   │   │       ├── Query.tokens
│   │   │   │       ├── Query.ts
│   │   │   │       ├── QueryLexer.g4
│   │   │   │       ├── QueryLexer.interp
│   │   │   │       ├── QueryLexer.tokens
│   │   │   │       ├── QueryLexer.ts
│   │   │   │       └── QueryVisitor.ts
│   │   │   ├── typeguards/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── typeguards.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── json-api/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── json-api-typeguard.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── json-api-response.types.ts
│   │   │   │   │   └── json-api.typeguard.ts
│   │   │   │   └── typeguards.ts
│   │   │   ├── types/
│   │   │   │   ├── either-or.ts
│   │   │   │   ├── ensure-keys.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── make-optional.ts
│   │   │   │   ├── make-required.ts
│   │   │   │   ├── remove-null.ts
│   │   │   │   ├── snapshot-query.ts
│   │   │   │   └── un-promisify.ts
│   │   │   ├── utils/
│   │   │   │   ├── clipboard.spec.ts
│   │   │   │   ├── clipboard.ts
│   │   │   │   ├── date.spec.ts
│   │   │   │   ├── date.ts
│   │   │   │   ├── dsn-parser.ts
│   │   │   │   ├── enum.ts
│   │   │   │   ├── get-random-int.spec.ts
│   │   │   │   ├── get-random-int.ts
│   │   │   │   ├── get-uniq-name.spec.ts
│   │   │   │   ├── get-uniq-name.ts
│   │   │   │   ├── id-generator.spec.ts
│   │   │   │   ├── id-generator.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── minidenticon.ts
│   │   │   │   └── replace-suffix.ts
│   │   │   └── zod.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.js
│   ├── db-main-prisma/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── db-main-prisma.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── prisma/
│   │   │   ├── postgres/
│   │   │   │   ├── migrations/
│   │   │   │   │   ├── 20240308114704_initial_database/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240313062534_add_credit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240409081450_field_order/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240410190501_primary_field_visible/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240416092001_clean_useless_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240528060827_add_pin_resource/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240625032002_add_admin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240626072754_add_setting_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240628115120_add_space_invitation/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240702084258_add_oauth/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240708080014_oauth_revoke/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240712040045_remove_bucket/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240716070632_notification_url_path/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240806110415_add_record_history/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240814074637_update_collaborator/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240906084530_add_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240913075702_add_dashboard_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240919032636_add_comment/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241008161823_share_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241031080906_add_attachment_thumbnail/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241126085325_add_ref_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241128112023_add_ai_config/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241205121129_add_table_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241223100142_collaborator_support_org/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241226111824_remove_collaborator_foreign_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250115084212_add_enable_email_verification_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250117105433_update_view/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250214080105_add_integration/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250217092955_add_table_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250218075500_add_plugin_context_menu/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250320062220_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250328035739_brand/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250402105144_add_template/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250406145144_add_share_id_unique/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250409093339_add_task_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250410102941_update_task_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250416113238_add_template_markdown_description/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250418091636_add_db_table_name_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250509062715_require_primary_key/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250513085306_add_ai_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520081803_update_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520103546_add_user_trial_used/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250526042029_repair_reference_caused_by_formula_duplicate/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250604101438_update_access_token_full_access/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250702035214_update_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250730041646_add_user_permanent_deleted_time/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250804000000_add_field_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250811102556_add_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812031017_remove_user_last_visit_useless_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812090828_remove_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250820022407_add_waitlist/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250820022408_add_table_meta_db_view_name/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250828083308_add_app_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250905035737_add_trash_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922111648_add_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922120000_add_conditional_lookup_flag/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251028105638_add_user_lang/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251029141643_add_notification_message_i18n/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251105070802_add_oauth_foreign_keys/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251119134101_add_base_node/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251208112242_template_community/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251210134101_disallow_dashboard/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251219083654_add_template_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104151713_add_computed_update_outbox_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104190000_add_outbox_seed_table_id/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260105123000_add_computed_update_run_tracking/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260114000000_add_field_json_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260118000000_add_symmetric_field_id_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260118010000_add_teable_try_cast_valid/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260120065143_add_core_table_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260121090646_add_task_run_log/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260121100000_add_base_share/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260129203000_add_outbox_pending_unique_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260303000000_alter_attachment_size_to_bigint/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260305000000_add_trace_data_and_nullable_steps_edges/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260305072937_oauth_app_token_optional_secret/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260305120931_add_oauth_app_client_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   └── migration_lock.toml
│   │   │   │   └── schema.prisma
│   │   │   ├── seed.ts
│   │   │   ├── sqlite/
│   │   │   │   ├── migrations/
│   │   │   │   │   ├── 20240308114656_initial_database/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240313061543_add_credit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240409081445_field_order/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240416091909_clean_useless_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240528055850_add_pin_resource/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240528060824_add_pin_resource/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240625031955_add_admin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240626072703_add_setting_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240628115107_add_space_invitation/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240702084255_add_oauth/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240708080010_oauth_revoke/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240712040040_remove_bucket/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240716070608_notification_url_path/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240806110404_add_record_history/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240814074632_update_collaborator/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240906084521_add_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240913075658_add_dashboard_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240919032621_add_comment/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241031080903_add_attachment_thumbnail/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241126081006_add_ref_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241128112016_add_ai_config/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241205121154_add_table_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241223100135_collaborator_support_org/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241226111815_remove_collaborator_foreign_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250115084207_add_enable_email_verification_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250117105406_update_view/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250214080102_add_integration/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250217092948_add_table_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250218075455_add_plugin_context_menu/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250320062213_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250328040207_brand/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250402105138_add_template/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250406145126_add_share_id_unique/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250409093334_add_task_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250410102938_update_task_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250416113234_add_template_markdown_description/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250418091633_add_db_table_name_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250509062710_require_primary_key/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250513085303_add_ai_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520081750_update_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520103541_add_user_trial_used/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250526042154_repair_reference_caused_by_formula_duplicate/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250604101438_update_access_token_full_access/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250702035214_update_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250730041646_add_user_permanent_deleted_time/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250804000000_add_field_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250811102551_add_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812031012_remove_user_last_visit_useless_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812090823_remove_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250820022401_add_waitlist/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250828083309_add_app_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250904034946_add_table_meta_db_view_name/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250905035730_add_trash_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922111616_add_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922120000_add_conditional_lookup_flag/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251028105630_add_user_lang/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251029141619_add_notification_message_i18n/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251105070757_add_oauth_foreign_keys/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251119134053_add_base_node/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251208112242_template_community/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251210134101_disallow_dashboard/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251219083654_add_template_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104151713_add_computed_update_outbox_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104190000_add_outbox_seed_table_id/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260120065143_add_core_table_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260121100000_add_base_share/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260129203000_add_outbox_pending_unique_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   └── migration_lock.toml
│   │   │   │   └── schema.prisma
│   │   │   └── template.prisma
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── prisma.module.ts
│   │   │   ├── prisma.service.ts
│   │   │   ├── seeds/
│   │   │   │   ├── e2e/
│   │   │   │   │   ├── space-seeds.ts
│   │   │   │   │   └── user-seeds.ts
│   │   │   │   └── seed.abstract.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.eslint.json
│   │   └── tsconfig.json
│   ├── eslint-config-bases/
│   │   ├── .eslintrc.cjs
│   │   ├── .idea/
│   │   │   ├── eslint-config-bases.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── bases/
│   │   │   │   ├── index.js
│   │   │   │   ├── jest.js
│   │   │   │   ├── mdx.js
│   │   │   │   ├── playwright.js
│   │   │   │   ├── prettier-config.js
│   │   │   │   ├── prettier-plugin.js
│   │   │   │   ├── react-query.js
│   │   │   │   ├── react.js
│   │   │   │   ├── regexp.js
│   │   │   │   ├── rtl.js
│   │   │   │   ├── sonar.js
│   │   │   │   ├── storybook.js
│   │   │   │   ├── tailwind.js
│   │   │   │   └── typescript.js
│   │   │   ├── helpers/
│   │   │   │   ├── getDefaultIgnorePatterns.js
│   │   │   │   ├── getPrettierConfig.js
│   │   │   │   └── index.js
│   │   │   ├── index.js
│   │   │   ├── patch/
│   │   │   │   └── modern-module-resolution.js
│   │   │   └── prettier.base.config.js
│   │   └── tsconfig.json
│   ├── formula/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── conversion.visitor.spec.ts
│   │   │   ├── conversion.visitor.ts
│   │   │   ├── datetime-format-pg.spec.ts
│   │   │   ├── datetime-format-pg.ts
│   │   │   ├── error.listener.ts
│   │   │   ├── field-reference.util.ts
│   │   │   ├── field-reference.visitor.spec.ts
│   │   │   ├── field-reference.visitor.ts
│   │   │   ├── function-call-collector.visitor.spec.ts
│   │   │   ├── function-call-collector.visitor.ts
│   │   │   ├── index.ts
│   │   │   ├── parse-formula.ts
│   │   │   └── parser/
│   │   │       ├── Formula.g4
│   │   │       ├── Formula.interp
│   │   │       ├── Formula.tokens
│   │   │       ├── Formula.ts
│   │   │       ├── FormulaLexer.g4
│   │   │       ├── FormulaLexer.interp
│   │   │       ├── FormulaLexer.tokens
│   │   │       ├── FormulaLexer.ts
│   │   │       ├── FormulaVisitor.ts
│   │   │       └── README.md
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.js
│   ├── i18n-keys/
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── icons/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── icons.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── generate.mjs
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── A.tsx
│   │   │   │   ├── ActionAI.tsx
│   │   │   │   ├── ActionCreateRecord.tsx
│   │   │   │   ├── ActionGetRecord.tsx
│   │   │   │   ├── ActionHttpRequest.tsx
│   │   │   │   ├── ActionScript.tsx
│   │   │   │   ├── ActionSendEmail.tsx
│   │   │   │   ├── ActionUpdateRecord.tsx
│   │   │   │   ├── Admin.tsx
│   │   │   │   ├── AlertCircle.tsx
│   │   │   │   ├── AlertTriangle.tsx
│   │   │   │   ├── AmazonBedrock.tsx
│   │   │   │   ├── Anthropic.tsx
│   │   │   │   ├── AppBuilder.tsx
│   │   │   │   ├── AppV0.tsx
│   │   │   │   ├── Apple.tsx
│   │   │   │   ├── ArceeAi.tsx
│   │   │   │   ├── Array.tsx
│   │   │   │   ├── ArrowDown.tsx
│   │   │   │   ├── ArrowLeft.tsx
│   │   │   │   ├── ArrowRight.tsx
│   │   │   │   ├── ArrowUp.tsx
│   │   │   │   ├── ArrowUpDown.tsx
│   │   │   │   ├── ArrowUpRight.tsx
│   │   │   │   ├── Audio.tsx
│   │   │   │   ├── Azure.tsx
│   │   │   │   ├── BarChart2.tsx
│   │   │   │   ├── Bell.tsx
│   │   │   │   ├── Bfl.tsx
│   │   │   │   ├── Boolean.tsx
│   │   │   │   ├── Box.tsx
│   │   │   │   ├── Building2.tsx
│   │   │   │   ├── Bytedance.tsx
│   │   │   │   ├── Calendar.tsx
│   │   │   │   ├── Check.tsx
│   │   │   │   ├── CheckCircle2.tsx
│   │   │   │   ├── CheckSquare.tsx
│   │   │   │   ├── Checked.tsx
│   │   │   │   ├── ChevronDown.tsx
│   │   │   │   ├── ChevronLeft.tsx
│   │   │   │   ├── ChevronRight.tsx
│   │   │   │   ├── ChevronUp.tsx
│   │   │   │   ├── ChevronsLeft.tsx
│   │   │   │   ├── ChevronsRight.tsx
│   │   │   │   ├── ChevronsUpDown.tsx
│   │   │   │   ├── Circle.tsx
│   │   │   │   ├── ClipboardList.tsx
│   │   │   │   ├── Clock4.tsx
│   │   │   │   ├── Code.tsx
│   │   │   │   ├── Code2.tsx
│   │   │   │   ├── CodeReact.tsx
│   │   │   │   ├── Cohere.tsx
│   │   │   │   ├── Coins.tsx
│   │   │   │   ├── Component.tsx
│   │   │   │   ├── Compose.tsx
│   │   │   │   ├── Condition.tsx
│   │   │   │   ├── ConditionalLookup.tsx
│   │   │   │   ├── ConditionalRollup.tsx
│   │   │   │   ├── Copy.tsx
│   │   │   │   ├── CreditCard.tsx
│   │   │   │   ├── Credits.tsx
│   │   │   │   ├── Cuppy.tsx
│   │   │   │   ├── CuppyLoader.tsx
│   │   │   │   ├── Database.tsx
│   │   │   │   ├── DeepThinking.tsx
│   │   │   │   ├── Deepseek.tsx
│   │   │   │   ├── Discord.tsx
│   │   │   │   ├── DivideCircle.tsx
│   │   │   │   ├── DivideSquare.tsx
│   │   │   │   ├── DollarSign.tsx
│   │   │   │   ├── Download.tsx
│   │   │   │   ├── DraggableHandle.tsx
│   │   │   │   ├── Edit.tsx
│   │   │   │   ├── Expand.tsx
│   │   │   │   ├── ExpandAll.tsx
│   │   │   │   ├── Export.tsx
│   │   │   │   ├── Eye.tsx
│   │   │   │   ├── EyeOff.tsx
│   │   │   │   ├── File.tsx
│   │   │   │   ├── FileAudio.tsx
│   │   │   │   ├── FileAudioDark.tsx
│   │   │   │   ├── FileCsv.tsx
│   │   │   │   ├── FileDocument.tsx
│   │   │   │   ├── FileDocumentDark.tsx
│   │   │   │   ├── FileExcel.tsx
│   │   │   │   ├── FileFont.tsx
│   │   │   │   ├── FileImage.tsx
│   │   │   │   ├── FileJson.tsx
│   │   │   │   ├── FilePack.tsx
│   │   │   │   ├── FilePackDark.tsx
│   │   │   │   ├── FilePdf.tsx
│   │   │   │   ├── FilePdfDark.tsx
│   │   │   │   ├── FilePresentation.tsx
│   │   │   │   ├── FilePresentationDark.tsx
│   │   │   │   ├── FileQuestion.tsx
│   │   │   │   ├── FileScript.tsx
│   │   │   │   ├── FileSpreadsheet.tsx
│   │   │   │   ├── FileSpreadsheetDark.tsx
│   │   │   │   ├── FileText.tsx
│   │   │   │   ├── FileUnknown.tsx
│   │   │   │   ├── FileUnknownDark.tsx
│   │   │   │   ├── FileVideo.tsx
│   │   │   │   ├── FileVideoDark.tsx
│   │   │   │   ├── Filter.tsx
│   │   │   │   ├── Flame.tsx
│   │   │   │   ├── FreezeColumn.tsx
│   │   │   │   ├── Frown.tsx
│   │   │   │   ├── Gauge.tsx
│   │   │   │   ├── GiftPerson.tsx
│   │   │   │   ├── GiftPersonDark.tsx
│   │   │   │   ├── Github.tsx
│   │   │   │   ├── GithubLogo.tsx
│   │   │   │   ├── Globe.tsx
│   │   │   │   ├── GoogleLogo.tsx
│   │   │   │   ├── Hash.tsx
│   │   │   │   ├── Heart.tsx
│   │   │   │   ├── HelpCircle.tsx
│   │   │   │   ├── History.tsx
│   │   │   │   ├── Home.tsx
│   │   │   │   ├── Image.tsx
│   │   │   │   ├── ImageGeneration.tsx
│   │   │   │   ├── Import.tsx
│   │   │   │   ├── InIcon.tsx
│   │   │   │   ├── Inbox.tsx
│   │   │   │   ├── Inception.tsx
│   │   │   │   ├── Integration.tsx
│   │   │   │   ├── Kanban.tsx
│   │   │   │   ├── Key.tsx
│   │   │   │   ├── Kwaipilot.tsx
│   │   │   │   ├── Layers.tsx
│   │   │   │   ├── LayoutGrid.tsx
│   │   │   │   ├── LayoutList.tsx
│   │   │   │   ├── LayoutTemplate.tsx
│   │   │   │   ├── License.tsx
│   │   │   │   ├── Line1.tsx
│   │   │   │   ├── Line2.tsx
│   │   │   │   ├── Line3.tsx
│   │   │   │   ├── Lingyiwanwu.tsx
│   │   │   │   ├── Link.tsx
│   │   │   │   ├── LinkedIn.tsx
│   │   │   │   ├── ListChecks.tsx
│   │   │   │   ├── ListOrdered.tsx
│   │   │   │   ├── ListPlus.tsx
│   │   │   │   ├── Loader2.tsx
│   │   │   │   ├── Lock.tsx
│   │   │   │   ├── LongText.tsx
│   │   │   │   ├── MagicAi.tsx
│   │   │   │   ├── Mail.tsx
│   │   │   │   ├── MarkUnread.tsx
│   │   │   │   ├── Maximize2.tsx
│   │   │   │   ├── Meituan.tsx
│   │   │   │   ├── Menu.tsx
│   │   │   │   ├── MessageSquare.tsx
│   │   │   │   ├── MessageSquareDot.tsx
│   │   │   │   ├── Meta.tsx
│   │   │   │   ├── MicrosoftTeams.tsx
│   │   │   │   ├── Minimax.tsx
│   │   │   │   ├── Minimize2.tsx
│   │   │   │   ├── Mistral.tsx
│   │   │   │   ├── Moon.tsx
│   │   │   │   ├── Moonshot.tsx
│   │   │   │   ├── MoreHorizontal.tsx
│   │   │   │   ├── Morph.tsx
│   │   │   │   ├── MousePointerClick.tsx
│   │   │   │   ├── Network.tsx
│   │   │   │   ├── Nvidia.tsx
│   │   │   │   ├── Object.tsx
│   │   │   │   ├── Ollama.tsx
│   │   │   │   ├── OpenRouter.tsx
│   │   │   │   ├── Openai.tsx
│   │   │   │   ├── PackageCheck.tsx
│   │   │   │   ├── PaintBucket.tsx
│   │   │   │   ├── Paperclip.tsx
│   │   │   │   ├── Pencil.tsx
│   │   │   │   ├── Percent.tsx
│   │   │   │   ├── Perplexity.tsx
│   │   │   │   ├── Phone.tsx
│   │   │   │   ├── Play.tsx
│   │   │   │   ├── Plus.tsx
│   │   │   │   ├── PlusCircle.tsx
│   │   │   │   ├── PrimeIntellect.tsx
│   │   │   │   ├── Puzzle.tsx
│   │   │   │   ├── Qrcode.tsx
│   │   │   │   ├── Qwen.tsx
│   │   │   │   ├── Redo2.tsx
│   │   │   │   ├── RefreshCcw.tsx
│   │   │   │   ├── RotateCw.tsx
│   │   │   │   ├── RowExtralTall.tsx
│   │   │   │   ├── RowMedium.tsx
│   │   │   │   ├── RowShort.tsx
│   │   │   │   ├── RowTall.tsx
│   │   │   │   ├── Search.tsx
│   │   │   │   ├── Server.tsx
│   │   │   │   ├── Settings.tsx
│   │   │   │   ├── Share2.tsx
│   │   │   │   ├── Sheet.tsx
│   │   │   │   ├── ShieldCheck.tsx
│   │   │   │   ├── ShieldUser.tsx
│   │   │   │   ├── Sidebar.tsx
│   │   │   │   ├── Slack.tsx
│   │   │   │   ├── SortAsc.tsx
│   │   │   │   ├── Square.tsx
│   │   │   │   ├── Star.tsx
│   │   │   │   ├── Stealth.tsx
│   │   │   │   ├── StretchHorizontal.tsx
│   │   │   │   ├── Sun.tsx
│   │   │   │   ├── SunMedium.tsx
│   │   │   │   ├── Switch.tsx
│   │   │   │   ├── Table2.tsx
│   │   │   │   ├── Teable.tsx
│   │   │   │   ├── TeableAi.tsx
│   │   │   │   ├── TeableNew.tsx
│   │   │   │   ├── ThumbsUp.tsx
│   │   │   │   ├── Token.tsx
│   │   │   │   ├── Translation.tsx
│   │   │   │   ├── Trash.tsx
│   │   │   │   ├── Trash2.tsx
│   │   │   │   ├── TriggerButton.tsx
│   │   │   │   ├── TriggerCreateOrUpdate.tsx
│   │   │   │   ├── TriggerCreateRecord.tsx
│   │   │   │   ├── TriggerEmailReceived.tsx
│   │   │   │   ├── TriggerForm.tsx
│   │   │   │   ├── TriggerRecordMatchesConditions.tsx
│   │   │   │   ├── TriggerSchedule.tsx
│   │   │   │   ├── TriggerUpdateRecord.tsx
│   │   │   │   ├── TriggerWebhook.tsx
│   │   │   │   ├── Twitter.tsx
│   │   │   │   ├── Undo2.tsx
│   │   │   │   ├── User.tsx
│   │   │   │   ├── UserEdit.tsx
│   │   │   │   ├── UserPlus.tsx
│   │   │   │   ├── Users.tsx
│   │   │   │   ├── Vercel.tsx
│   │   │   │   ├── Video.tsx
│   │   │   │   ├── Voyage.tsx
│   │   │   │   ├── Webhook.tsx
│   │   │   │   ├── WorkflowLogic.tsx
│   │   │   │   ├── Wrench.tsx
│   │   │   │   ├── X.tsx
│   │   │   │   ├── Xai.tsx
│   │   │   │   ├── Xiaomi.tsx
│   │   │   │   ├── Zap.tsx
│   │   │   │   ├── Zapier.tsx
│   │   │   │   ├── Zhipu.tsx
│   │   │   │   ├── ZoomIn.tsx
│   │   │   │   └── ZoomOut.tsx
│   │   │   └── index.ts
│   │   ├── tsconfig.eslint.json
│   │   └── tsconfig.json
│   ├── openapi/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── openapi.iml
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── access-token/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── refresh.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── admin/
│   │   │   │   ├── enterprise-license/
│   │   │   │   │   ├── get-status.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── plugin/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── publish.ts
│   │   │   │   │   └── unpublish.ts
│   │   │   │   └── setting/
│   │   │   │       ├── ai-key-stats.ts
│   │   │   │       ├── batch-test-llm.ts
│   │   │   │       ├── get-public.ts
│   │   │   │       ├── get.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── key.enum.ts
│   │   │   │       ├── pricing.spec.ts
│   │   │   │       ├── set-transport-config.ts
│   │   │   │       ├── test-api-key.ts
│   │   │   │       ├── test-llm.ts
│   │   │   │       ├── test-public-access.ts
│   │   │   │       ├── update.ts
│   │   │   │       └── upload-logo.ts
│   │   │   ├── aggregation/
│   │   │   │   ├── get-aggregation.ts
│   │   │   │   ├── get-calendar-daily-collection.ts
│   │   │   │   ├── get-group-points.ts
│   │   │   │   ├── get-record-index.ts
│   │   │   │   ├── get-row-count.ts
│   │   │   │   ├── get-search-by-index.ts
│   │   │   │   ├── get-search-count.ts
│   │   │   │   ├── get-task-status-collection.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── type.ts
│   │   │   ├── ai/
│   │   │   │   ├── generate-stream.ts
│   │   │   │   ├── get-ai-disable-actions.ts
│   │   │   │   ├── get-config.ts
│   │   │   │   ├── image-model-config.ts
│   │   │   │   └── index.ts
│   │   │   ├── attachment/
│   │   │   │   ├── index.ts
│   │   │   │   ├── notify.ts
│   │   │   │   ├── read-file.ts
│   │   │   │   ├── signature.ts
│   │   │   │   ├── upload-file.ts
│   │   │   │   └── utils.ts
│   │   │   ├── auth/
│   │   │   │   ├── add-password.ts
│   │   │   │   ├── change-email.ts
│   │   │   │   ├── change-password.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── reset-password.ts
│   │   │   │   ├── send-change-email-code.ts
│   │   │   │   ├── send-reset-password-email.ts
│   │   │   │   ├── send-signup-verification-code.ts
│   │   │   │   ├── signin.ts
│   │   │   │   ├── signout.ts
│   │   │   │   ├── signup.ts
│   │   │   │   ├── temp-token.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── user-me.ts
│   │   │   │   ├── user.ts
│   │   │   │   └── waitlist/
│   │   │   │       ├── get.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── invite-code.ts
│   │   │   │       ├── invite.ts
│   │   │   │       └── join.ts
│   │   │   ├── automation/
│   │   │   │   ├── index.ts
│   │   │   │   └── workflow/
│   │   │   │       └── create.ts
│   │   │   ├── axios.ts
│   │   │   ├── base/
│   │   │   │   ├── all-list.ts
│   │   │   │   ├── collaborator-add.ts
│   │   │   │   ├── collaborator-delete.ts
│   │   │   │   ├── collaborator-get-list-user.ts
│   │   │   │   ├── collaborator-get-list.ts
│   │   │   │   ├── collaborator-update.ts
│   │   │   │   ├── create-from-template.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── erd.ts
│   │   │   │   ├── export.ts
│   │   │   │   ├── get-permission.ts
│   │   │   │   ├── get-shared-base.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── import.spec.ts
│   │   │   │   ├── import.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── invitation-create-link.ts
│   │   │   │   ├── invitation-delete-link.ts
│   │   │   │   ├── invitation-email.ts
│   │   │   │   ├── invitation-get-link-list.ts
│   │   │   │   ├── invitation-update-link.ts
│   │   │   │   ├── move.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── publish.ts
│   │   │   │   ├── query-data/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── route.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   └── update.ts
│   │   │   ├── base-node/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── folder/
│   │   │   │   │   ├── create.ts
│   │   │   │   │   ├── delete.ts
│   │   │   │   │   └── update.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-tree.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── move.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── base-share/
│   │   │   │   ├── auth.ts
│   │   │   │   ├── copy.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── refresh.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── billing/
│   │   │   │   ├── index.ts
│   │   │   │   └── subscription/
│   │   │   │       ├── get-subscription-summary-list.ts
│   │   │   │       ├── get-subscription-summary.ts
│   │   │   │       └── index.ts
│   │   │   ├── comment/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-attachment-url.ts
│   │   │   │   ├── get-count.ts
│   │   │   │   ├── get-counts-by-query.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── reaction/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── create-reaction.ts
│   │   │   │   │   ├── delete-reaction.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── subscribe/
│   │   │   │   │   ├── create-subscribe.ts
│   │   │   │   │   ├── delete-subscribe.ts
│   │   │   │   │   ├── get-subscribe.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── dashboard/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate-installed.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-remove.ts
│   │   │   │   ├── plugin-rename.ts
│   │   │   │   ├── plugin-update-storage.ts
│   │   │   │   ├── rename.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update-layout.ts
│   │   │   ├── db-connection/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get.ts
│   │   │   │   └── index.ts
│   │   │   ├── export/
│   │   │   │   ├── export-csv.ts
│   │   │   │   └── index.ts
│   │   │   ├── field/
│   │   │   │   ├── auto-fill-field.ts
│   │   │   │   ├── convert.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete-list.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── filter-link-records.ts
│   │   │   │   ├── get-delete-references.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── stop-fill-field.ts
│   │   │   │   └── update.ts
│   │   │   ├── formula/
│   │   │   │   ├── ai.ts
│   │   │   │   ├── func-define.ts
│   │   │   │   └── index.ts
│   │   │   ├── generate.schema.ts
│   │   │   ├── import/
│   │   │   │   ├── analyze.ts
│   │   │   │   ├── constant.ts
│   │   │   │   ├── import-status.ts
│   │   │   │   ├── import-table.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── inplace-import-table.ts
│   │   │   │   └── types.ts
│   │   │   ├── index.ts
│   │   │   ├── integrity/
│   │   │   │   ├── index.ts
│   │   │   │   ├── link-check.ts
│   │   │   │   └── link-fix.ts
│   │   │   ├── invitation/
│   │   │   │   ├── accept.ts
│   │   │   │   └── index.ts
│   │   │   ├── mail/
│   │   │   │   ├── index.ts
│   │   │   │   ├── test.ts
│   │   │   │   └── types.ts
│   │   │   ├── notification/
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── read-all.ts
│   │   │   │   ├── unread-count.ts
│   │   │   │   └── update-status.ts
│   │   │   ├── oauth/
│   │   │   │   ├── authorized-list.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── decision-info.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── revoke-token.ts
│   │   │   │   ├── revoke.ts
│   │   │   │   ├── secret-delete.ts
│   │   │   │   ├── secret-generate.ts
│   │   │   │   └── update.ts
│   │   │   ├── openapi-snippet/
│   │   │   │   ├── index.js
│   │   │   │   └── openapi-to-har.js
│   │   │   ├── organization/
│   │   │   │   ├── departments.ts
│   │   │   │   ├── get-me.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── user-get.ts
│   │   │   ├── pin/
│   │   │   │   ├── add.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update-order.ts
│   │   │   ├── plan/
│   │   │   │   ├── index.ts
│   │   │   │   ├── plan-convert.ts
│   │   │   │   ├── plan-create.ts
│   │   │   │   ├── plan-delete.ts
│   │   │   │   └── plan.ts
│   │   │   ├── plugin/
│   │   │   │   ├── chart/
│   │   │   │   │   ├── dashboard-query.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── plugin-panel-query.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-auth-code.ts
│   │   │   │   ├── get-center-list.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-token.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── refresh-token.ts
│   │   │   │   ├── regenerate-secret.ts
│   │   │   │   ├── submit.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── unpublish.ts
│   │   │   │   └── update.ts
│   │   │   ├── plugin-context-menu/
│   │   │   │   ├── index.ts
│   │   │   │   ├── plugin-get-list.ts
│   │   │   │   ├── plugin-get-storage.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-move.ts
│   │   │   │   ├── plugin-remove.ts
│   │   │   │   ├── plugin-rename.ts
│   │   │   │   └── plugin-update-storage.ts
│   │   │   ├── plugin-panel/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate-panel-installed.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-remove.ts
│   │   │   │   ├── plugin-rename.ts
│   │   │   │   ├── plugin-update-storage.ts
│   │   │   │   ├── rename.ts
│   │   │   │   └── update-layout.ts
│   │   │   ├── query/
│   │   │   │   ├── index.ts
│   │   │   │   └── save-query-params.ts
│   │   │   ├── record/
│   │   │   │   ├── README.ts
│   │   │   │   ├── auto-fill-cell.ts
│   │   │   │   ├── button-click.ts
│   │   │   │   ├── button-reset.ts
│   │   │   │   ├── constant.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete-list.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── form-submit.ts
│   │   │   │   ├── get-collaborators.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-record-history.ts
│   │   │   │   ├── get-record-list-history.ts
│   │   │   │   ├── get-record-status.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── insert-attachment.ts
│   │   │   │   ├── record.schema.spec.ts
│   │   │   │   ├── update-records.ts
│   │   │   │   ├── update.ts
│   │   │   │   └── upload-attachment.ts
│   │   │   ├── selection/
│   │   │   │   ├── clear.ts
│   │   │   │   ├── copy.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── paste.ts
│   │   │   │   ├── range.ts
│   │   │   │   └── temporary-paste.ts
│   │   │   ├── share/
│   │   │   │   ├── index.ts
│   │   │   │   ├── view-aggregations.ts
│   │   │   │   ├── view-auth.ts
│   │   │   │   ├── view-button-click.ts
│   │   │   │   ├── view-calendar-daily-collection.ts
│   │   │   │   ├── view-collaborators.ts
│   │   │   │   ├── view-copy.ts
│   │   │   │   ├── view-form-submit.ts
│   │   │   │   ├── view-get.ts
│   │   │   │   ├── view-group-points.ts
│   │   │   │   ├── view-link-records.ts
│   │   │   │   ├── view-records.ts
│   │   │   │   ├── view-row-count.ts
│   │   │   │   ├── view-search-count.ts
│   │   │   │   └── view-search-index.ts
│   │   │   ├── space/
│   │   │   │   ├── collaborator-add.ts
│   │   │   │   ├── collaborator-delete.ts
│   │   │   │   ├── collaborator-get-list.ts
│   │   │   │   ├── collaborator-update.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-base-list.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── integration-create.ts
│   │   │   │   ├── integration-delete.ts
│   │   │   │   ├── integration-get-list.ts
│   │   │   │   ├── integration-update.ts
│   │   │   │   ├── invitation-create-link.ts
│   │   │   │   ├── invitation-delete-link.ts
│   │   │   │   ├── invitation-email.ts
│   │   │   │   ├── invitation-get-link-list.ts
│   │   │   │   ├── invitation-update-link.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── search.ts
│   │   │   │   ├── test-llm-integration.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── table/
│   │   │   │   ├── create.ts
│   │   │   │   ├── default-view-id.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── get-abnormal-index.ts
│   │   │   │   ├── get-activated-index.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-permission.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── repair-table-index.ts
│   │   │   │   ├── toggle-table-index.ts
│   │   │   │   ├── update-db-table-name.ts
│   │   │   │   ├── update-description.ts
│   │   │   │   ├── update-icon.ts
│   │   │   │   ├── update-name.ts
│   │   │   │   └── update-order.ts
│   │   │   ├── template/
│   │   │   │   ├── category/
│   │   │   │   │   ├── create.ts
│   │   │   │   │   ├── delete.ts
│   │   │   │   │   ├── get.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── update-order.ts
│   │   │   │   │   └── update.ts
│   │   │   │   ├── create-snapshot.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-by-base-id.ts
│   │   │   │   ├── get-permalink.ts
│   │   │   │   ├── get-published.ts
│   │   │   │   ├── get-template-detail.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── increment-visit.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── pin-top.ts
│   │   │   │   ├── unpublish.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   └── update.ts
│   │   │   ├── trash/
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-items.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── reset-items.ts
│   │   │   │   ├── restore.ts
│   │   │   │   └── types.ts
│   │   │   ├── types.ts
│   │   │   ├── undo-redo/
│   │   │   │   ├── index.ts
│   │   │   │   ├── redo.ts
│   │   │   │   └── undo.ts
│   │   │   ├── unsubscribe/
│   │   │   │   ├── export-list.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── import-list.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── usage/
│   │   │   │   ├── get-base-usage.ts
│   │   │   │   ├── get-instance-usage.ts
│   │   │   │   ├── get-space-usage.ts
│   │   │   │   └── index.ts
│   │   │   ├── user/
│   │   │   │   ├── index.ts
│   │   │   │   ├── last-visit/
│   │   │   │   │   ├── get-base-node.ts
│   │   │   │   │   ├── get.ts
│   │   │   │   │   ├── getMap.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── list-base.ts
│   │   │   │   │   └── update.ts
│   │   │   │   ├── update-avatar.ts
│   │   │   │   ├── update-lang.ts
│   │   │   │   ├── update-name.ts
│   │   │   │   └── update-notify-meta.ts
│   │   │   ├── user-integration/
│   │   │   │   ├── delete.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update-name.ts
│   │   │   ├── utils.ts
│   │   │   ├── view/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── filter-link-records.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── manual-sort.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-update-storage.ts
│   │   │   │   ├── refresh-share-id.ts
│   │   │   │   ├── share-disable.ts
│   │   │   │   ├── share-enable.ts
│   │   │   │   ├── update-description.ts
│   │   │   │   ├── update-fields-column-meta.ts
│   │   │   │   ├── update-filter.ts
│   │   │   │   ├── update-group.ts
│   │   │   │   ├── update-locked.ts
│   │   │   │   ├── update-name.ts
│   │   │   │   ├── update-options.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   ├── update-record-order.ts
│   │   │   │   ├── update-share-meta.ts
│   │   │   │   └── update-sort.ts
│   │   │   └── zod.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.js
│   ├── sdk/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── sdk.iml
│   │   ├── LICENSE
│   │   ├── components.json
│   │   ├── config/
│   │   │   └── tests/
│   │   │       └── setupVitest.ts
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── plate-components.json
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── FileZone.tsx
│   │   │   │   ├── ReadOnlyTip.tsx
│   │   │   │   ├── base-query/
│   │   │   │   │   ├── FormItem.tsx
│   │   │   │   │   ├── QueryBuilder.tsx
│   │   │   │   │   ├── QueryEditor.tsx
│   │   │   │   │   ├── QueryEditorContainer.tsx
│   │   │   │   │   ├── QueryFom.tsx
│   │   │   │   │   ├── QueryOperators.tsx
│   │   │   │   │   ├── common/
│   │   │   │   │   │   ├── ContextColumnCommand.tsx
│   │   │   │   │   │   ├── ContextColumnSelector.tsx
│   │   │   │   │   │   ├── NewPopover.tsx
│   │   │   │   │   │   └── useAllColumns.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── context/
│   │   │   │   │   │   ├── QueryEditorContext.tsx
│   │   │   │   │   │   ├── QueryEditorProvider.tsx
│   │   │   │   │   │   ├── QueryFormContext.tsx
│   │   │   │   │   │   └── QueryFormProvider.tsx
│   │   │   │   │   ├── editors/
│   │   │   │   │   │   ├── QueryAggregation.tsx
│   │   │   │   │   │   ├── QueryFilter/
│   │   │   │   │   │   │   ├── FieldComponent.tsx
│   │   │   │   │   │   │   ├── OperatorComponent.tsx
│   │   │   │   │   │   │   ├── QueryFilter.tsx
│   │   │   │   │   │   │   ├── ValueComponent.tsx
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── QueryGroup.tsx
│   │   │   │   │   │   ├── QueryJoin.tsx
│   │   │   │   │   │   ├── QueryOrder.tsx
│   │   │   │   │   │   ├── QuerySelect.tsx
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── query-from/
│   │   │   │   │   │   ├── QueryFrom.tsx
│   │   │   │   │   │   ├── QueryFromValue.tsx
│   │   │   │   │   │   └── useQueryFromTableValidation.ts
│   │   │   │   │   ├── useQueryContext.ts
│   │   │   │   │   └── useQueryOperatorsStatic.ts
│   │   │   │   ├── billing/
│   │   │   │   │   └── store/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── usage-limit-modal.ts
│   │   │   │   ├── cell-value/
│   │   │   │   │   ├── CellValue.tsx
│   │   │   │   │   ├── cell-attachment/
│   │   │   │   │   │   ├── CellAttachment.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-button/
│   │   │   │   │   │   ├── CellButton.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-checkbox/
│   │   │   │   │   │   ├── CellCheckbox.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-date/
│   │   │   │   │   │   ├── CellDate.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-link/
│   │   │   │   │   │   ├── CellLink.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-markdown/
│   │   │   │   │   │   ├── CellMarkdown.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-number/
│   │   │   │   │   │   ├── CellNumber.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-rating/
│   │   │   │   │   │   ├── CellRating.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-select/
│   │   │   │   │   │   ├── CellSelect.tsx
│   │   │   │   │   │   ├── SelectTag.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-text/
│   │   │   │   │   │   ├── CellText.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-user/
│   │   │   │   │   │   ├── CellUser.tsx
│   │   │   │   │   │   ├── UserAvatar.tsx
│   │   │   │   │   │   ├── UserTag.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── OverflowTooltip.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── useTagVisibility.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── cell-value-editor/
│   │   │   │   │   ├── CellEditor.tsx
│   │   │   │   │   ├── CellEditorMain.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── collaborator/
│   │   │   │   │   ├── CollaboratorWithHoverCard.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── color/
│   │   │   │   │   ├── Color.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── comment/
│   │   │   │   │   ├── CommentHeader.tsx
│   │   │   │   │   ├── CommentPanel.tsx
│   │   │   │   │   ├── comment-editor/
│   │   │   │   │   │   ├── CommentEditor.tsx
│   │   │   │   │   │   ├── CommentQuote.tsx
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── transform.tsx
│   │   │   │   │   ├── comment-list/
│   │   │   │   │   │   ├── CommentContent.tsx
│   │   │   │   │   │   ├── CommentItem.tsx
│   │   │   │   │   │   ├── CommentList.tsx
│   │   │   │   │   │   ├── CommentSkeleton.tsx
│   │   │   │   │   │   ├── context.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── node/
│   │   │   │   │   │   │   ├── block-element/
│   │   │   │   │   │   │   │   ├── Image.tsx
│   │   │   │   │   │   │   │   ├── Paragraph.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── inline-element/
│   │   │   │   │   │   │   │   ├── Link.tsx
│   │   │   │   │   │   │   │   ├── MentionUser.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   └── type.ts
│   │   │   │   │   │   ├── reaction/
│   │   │   │   │   │   │   ├── Reaction.tsx
│   │   │   │   │   │   │   ├── ReactionPicker.tsx
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── useCommentPatchListener.ts
│   │   │   │   │   │   └── useIsMe.ts
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── useBaseId.ts
│   │   │   │   │   │   ├── useRecordCommentCount.ts
│   │   │   │   │   │   └── useRecordId.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── useCommentStore.ts
│   │   │   │   ├── create-record/
│   │   │   │   │   ├── CreateRecordModal.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── editor/
│   │   │   │   │   ├── attachment/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── EditorMain.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── upload-attachment/
│   │   │   │   │   │   │   ├── AttachmentItem.tsx
│   │   │   │   │   │   │   ├── FileInput.tsx
│   │   │   │   │   │   │   ├── UploadAttachment.tsx
│   │   │   │   │   │   │   ├── UploadAttachmentView.tsx
│   │   │   │   │   │   │   ├── UploadingFile.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   ├── useCellAttachmentUpload.ts
│   │   │   │   │   │   │   │   ├── useLocalAttachmentUpload.ts
│   │   │   │   │   │   │   │   ├── usePendingAttachmentUpload.spec.tsx
│   │   │   │   │   │   │   │   └── usePendingAttachmentUpload.ts
│   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   └── uploadManage.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── button/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── checkbox/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── date/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── EditorMain.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── formula/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   ├── AiPromptContainer.tsx
│   │   │   │   │   │   │   ├── CodeEditor.tsx
│   │   │   │   │   │   │   ├── FunctionGuide.tsx
│   │   │   │   │   │   │   ├── FunctionHelper.tsx
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── constants.

================================================
FILE CONTENTS
================================================

================================================
FILE: .codeclimate.yml
================================================
# @link https://docs.codeclimate.com/docs/default-analysis-configuration#sample-codeclimateyml

version: '2'

checks:
  argument-count:
    enabled: true
    config:
      threshold: 4
  complex-logic:
    enabled: true
    config:
      threshold: 4
  file-lines:
    enabled: true
    config:
      threshold: 300
  method-complexity:
    enabled: true
    config:
      threshold: 5
  method-count:
    enabled: true
    config:
      threshold: 20
  method-lines:
    enabled: true
    config:
      threshold: 300
  nested-control-flow:
    enabled: true
    config:
      threshold: 4
  return-statements:
    enabled: true
    config:
      threshold: 4
  similar-code:
    enabled: false
    config:
      threshold: 5
  identical-code:
    enabled: false
    config:
      threshold: 5

# plugins:
#   eslint:
#     enabled: true
#     channel: "eslint-7"

exclude_patterns:
  - 'docs/'
  - '**/node_modules/'
  - '**/config/'
  - '**/*.config.js'
  - '**/dist/'
  - '**/scripts/'
  - '**/__tests__/'
  - '**/*.test.js'
  - '**/*.test.jsx'
  - '**/*.test.ts'
  - '**/*.test.tsx'
  - '**/*.d.ts'
  - '**/*.seed.ts'
  - '**/seed.ts'
  - '**/.mesh/'


================================================
FILE: .dockerignore
================================================
# All node_modules directories
**/node_modules
**/dist
**/.next

# All secrets
**/.env.local
**/.env.*.local

# By default all git files
.git
**/.gitignore
.gitattributes
.github

# Tools caches
.cache
**/*.tsbuildinfo
**/.eslintcache

# eslint
**/.eslintrc.cjs
**/lint-staged.config.js

# npm
!.npmrc

# Docker related
.dockerignore
dockers
*Dockerfile*
*docker-compose*

# Log files
logs
**/*.log

# Temp files
tmp
*.tmp

# IDE related
.idea
.vscode

# other
**/db
!packages/v2/adapter-repository-postgres/src/db
!packages/v2/adapter-repository-postgres/src/db/**
**/.assets
**/.temporary
**.DS_Store
docs
**/*.md


================================================
FILE: .gitattributes
================================================
## Source: https://github.com/alexkaratarakis/gitattributes
## Modified * text=auto to * text eol=lf to force LF endings.

## GITATTRIBUTES FOR WEB PROJECTS
#
# These settings are for any web project.
#
# Details per file setting:
#   text    These files should be normalized (i.e. convert CRLF to LF).
#   binary  These files are binary and should be left untouched.
#
# Note that binary is a macro for -text -diff.
######################################################################

# Auto detect
##   Force LF line endings automatically for files detected as
##   text and leave all files detected as binary untouched.
##   This will handle all files NOT defined below.
*                 text eol=lf

# Source code
*.bash            text eol=lf
*.bat             text eol=crlf
*.cmd             text eol=crlf
*.coffee          text
*.css             text
*.htm             text diff=html
*.html            text diff=html
*.inc             text
*.ini             text
*.js              text
*.json            text
*.jsx             text
*.less            text
*.ls              text
*.map             text -diff
*.od              text
*.onlydata        text
*.php             text diff=php
*.pl              text
*.ps1             text eol=crlf
*.py              text diff=python
*.rb              text diff=ruby
*.sass            text
*.scm             text
*.scss            text diff=css
*.sh              text eol=lf
*.sql             text
*.styl            text
*.tag             text
*.ts              text
*.tsx             text
*.xml             text
*.xhtml           text diff=html

# Docker
Dockerfile        text

# Documentation
*.ipynb           text
*.markdown        text
*.md              text
*.mdwn            text
*.mdown           text
*.mkd             text
*.mkdn            text
*.mdtxt           text
*.mdtext          text
*.txt             text
AUTHORS           text
CHANGELOG         text
CHANGES           text
CONTRIBUTING      text
COPYING           text
copyright         text
*COPYRIGHT*       text
INSTALL           text
license           text
LICENSE           text
NEWS              text
readme            text
*README*          text
TODO              text

# Templates
*.dot             text
*.ejs             text
*.haml            text
*.handlebars      text
*.hbs             text
*.hbt             text
*.jade            text
*.latte           text
*.mustache        text
*.njk             text
*.phtml           text
*.tmpl            text
*.tpl             text
*.twig            text
*.vue             text

# Configs
*.cnf             text
*.conf            text
*.config          text
.editorconfig     text
.env              text
.gitattributes    text
.gitconfig        text
.htaccess         text
*.lock            text -diff
package-lock.json text -diff
*.toml            text
*.yaml            text
*.yml             text
browserslist      text
Makefile          text
makefile          text

# Heroku
Procfile          text

# Graphics
*.ai              binary
*.bmp             binary
*.eps             binary
*.gif             binary
*.gifv            binary
*.glb             binary
*.ico             binary
*.jng             binary
*.jp2             binary
*.jpg             binary
*.jpeg            binary
*.jpx             binary
*.jxr             binary
*.pdf             binary
*.png             binary
*.psb             binary
*.psd             binary
# SVG treated as an asset (binary) by default.
*.svg             text
# If you want to treat it as binary,
# use the following line instead.
# *.svg           binary
*.svgz            binary
*.tif             binary
*.tiff            binary
*.wbmp            binary
*.webp            binary
*.avif            binary
*.icns            binary


# Audio
*.kar             binary
*.m4a             binary
*.mid             binary
*.midi            binary
*.mp3             binary
*.ogg             binary
*.ra              binary

# Video
*.3gpp            binary
*.3gp             binary
*.as              binary
*.asf             binary
*.asx             binary
*.fla             binary
*.flv             binary
*.m4v             binary
*.mng             binary
*.mov             binary
*.mp4             binary
*.mpeg            binary
*.mpg             binary
*.ogv             binary
*.swc             binary
*.swf             binary
*.webm            binary

# Archives
*.7z              binary
*.gz              binary
*.jar             binary
*.rar             binary
*.tar             binary
*.zip             binary

# Fonts
*.ttf             binary
*.eot             binary
*.otf             binary
*.woff            binary
*.woff2           binary

# Executables
*.exe             binary
*.pyc             binary

# RC files (like .babelrc or .eslintrc)
*.*rc             text

# Ignore files (like .npmignore or .gitignore)
*.*ignore         text

================================================
FILE: .github/FUNDING.yml
================================================
github: teableio
ko_fi: teable


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ""
labels: ""
assignees: ""
---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

** Client (please complete the following information):**

- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Platform (Please tell us which deployment version you are using)**
[eg. teable.ai, docker-standalone, docker-swarm, docker-cluster]

**Additional context**
Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ""
labels: ""
assignees: ""
---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/actions/docker-build-push/action.yml
================================================
name: 'Docker build push (app)'
description: 'Build and push Docker images with Buildx'
inputs:
  context:
    description: "Build's context is the set of files located in the specified PATH or URL"
    required: false
    default: '.'
  dockerfile:
    description: 'Path to the Dockerfile'
    required: false
    default: 'Dockerfile'
  push:
    description: 'Push is a shorthand for --output=type=registry'
    required: false
    default: 'true'
  push-images:
    description: 'List of Docker images to use as base name for tags'
    required: true
  push-tags:
    description: 'List of tags as key-value pair attributes'
    required: false
    default: |
      type=ref,event=branch
      type=semver,pattern={{version}}
      type=semver,pattern={{major}}.{{minor}}
      type=sha
      # set latest tag for default branch
      type=raw,value=latest,enable={{is_default_branch}}
  platforms:
    description: 'List of target platforms for build'
    required: false
  cache-from:
    description: 'List of external cache sources for buildx (e.g., user/app:cache, type=local,src=path/to/dir)'
    required: false
  cache-to:
    description: 'List of cache export destinations for buildx (e.g., user/app:cache, type=local,dest=path/to/dir)'
    required: false

runs:
  using: 'composite'

  steps:
    - name: ⚙️ Docker meta
      id: meta
      uses: docker/metadata-action@v5
      with:
        # list of Docker images to use as base name for tags
        images: ${{ inputs.push-images }}
        # generate Docker tags based on the following events/attributes
        tags: ${{ inputs.push-tags }}

    - name: ⚙️ Set up QEMU
      uses: docker/setup-qemu-action@v3
    - name: ⚙️ Set up Docker Buildx
      uses: docker/setup-buildx-action@v3

    - name: 📦 Build and push(Dockerfile)
      uses: docker/build-push-action@v5
      env:
        GITHUB_ACTIONS: $env:GITHUB_ACTIONS
        GITHUB_REF_TYPE: $GITHUB_REF_TYPE
        GITHUB_RUN_NUMBER: GITHUB_RUN_NUMBER
        GITHUB_SHA: GITHUB_SHA
      with:
        context: ${{ inputs.context }}
        file: ${{ inputs.dockerfile }}
        push: ${{ inputs.push }}
        tags: ${{ steps.meta.outputs.tags }}
        # platforms: linux/amd64,linux/arm64
        platforms: ${{ inputs.platforms }}
        cache-from: ${{ inputs.cache-from }}
        cache-to: ${{ inputs.cache-to }}


================================================
FILE: .github/actions/pnpm-install/action.yml
================================================
#######################################################################################
# "pnpm install" composite action                                                      #
########################################################################################

name: 'Monorepo install (pnpm)'
description: 'Run pnpm install with node_modules linker and cache enabled'
inputs:
  cwd:
    description: "Changes node's process.cwd() if the project is not located on the root. Default to process.cwd()"
    required: false
    default: '.'
  cache-prefix:
    description: 'Add a specific cache-prefix'
    required: false
    default: 'default'
  cache-pnpm-cache:
    description: 'Cache npm global cache folder often used by node-gyp, prebuild binaries (invalidated on lock/os/node-version)'
    required: false
    default: 'true'
  enable-corepack:
    description: 'Enable corepack'
    required: false
    default: 'true'

runs:
  using: 'composite'

  steps:
    - name: ⚙️ Enable Corepack
      if: inputs.enable-corepack == 'true'
      shell: bash
      working-directory: ${{ inputs.cwd }}
      run: corepack enable

    - name: ⚙️ Expose pnpm config as "$GITHUB_OUTPUT"
      id: pnpm-config
      shell: bash
      run: |
        echo "STORE_PATH=$(pnpm store path | tr -d '\n')" >> $GITHUB_OUTPUT

    - name: ⚙️ Cache rotation keys
      id: cache-rotation
      shell: bash
      run: |
        echo "YEAR_MONTH=$(/bin/date -u "+%Y%m")" >> $GITHUB_OUTPUT
        echo "YEAR_WEEK=$(/bin/date -u "+%Y%W")" >> $GITHUB_OUTPUT

    - name: ♻️ Restore pnpm cache
      id: pnpm-store-cache
      uses: actions/cache@v4
      with:
        path: ${{ steps.pnpm-config.outputs.STORE_PATH }}
        key: ${{ runner.os }}-pnpm-store-cache-${{ steps.cache-rotation.outputs.YEAR_WEEK }}-${{ hashFiles('**/pnpm-lock.yaml') }}
        restore-keys: |
          ${{ runner.os }}-pnpm-store-cache-${{ steps.cache-rotation.outputs.YEAR_WEEK }}-

    - name: 📥 Install dependencies
      shell: bash
      run: pnpm install --frozen-lockfile
      env:
        # Other environment variables
        HUSKY: '0' # By default do not run HUSKY install


================================================
FILE: .github/workflows/docker-push.yml
================================================
name: Build and Push to Docker Registry

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

on:
  push:
    branches:
      - develop
    tags:
      - 'v*'
    paths:
      - 'apps/nestjs-backend/**'
      - 'apps/nextjs-app/**'
      - 'packages/**'
      - '.github/**'
      - 'scripts/**'

jobs:
  build-push:
    strategy:
      matrix:
        target: [app, db-migrate]
        arch: [amd64, arm64]
        include:
          - target: app
            file: Dockerfile
            image: teable-community
          - target: db-migrate
            file: Dockerfile.db-migrate
            image: teable-db-migrate-community
          - arch: amd64
            runner: ubuntu-latest
          - arch: arm64
            runner: ubuntu-24.04-arm
    runs-on: ${{ matrix.runner }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Login to GitHub container registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.PACKAGES_KEY }}

      - name: Login to Docker Hub registry
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_NAME }}
          password: ${{ secrets.DOCKER_HUB_AK }}

      - name: Login to Ali container registry
        uses: docker/login-action@v3
        with:
          registry: registry.cn-shenzhen.aliyuncs.com
          username: ${{ secrets.ALI_DOCKER_USERNAME }}
          password: ${{ secrets.ALI_DOCKER_PASSWORD }}

      - uses: actions/setup-node@v4
        with:
          node-version: 22.18.0
      - name: ⚙️ Install zx
        run: npm install -g zx

      - name: ⚙️ Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            registry.cn-shenzhen.aliyuncs.com/teable/${{ matrix.image }}
            ghcr.io/teableio/${{ matrix.image }}
            docker.io/teableio/${{ matrix.image }}
          tags: |
            type=sha,format=long
            type=raw,value=latest

      - name: 📦 Build and push
        run: |
          zx scripts/build-image.mjs --file=dockers/teable/${{ matrix.file }} \
              --build-arg="ENABLE_CSP=false" \
              --tag="${{ steps.meta.outputs.tags }}" \
              --platform="linux/${{ matrix.arch }}" \
              --push

  create-manifest:
    needs: build-push
    runs-on: ubuntu-latest
    strategy:
      matrix:
        target: [app, db-migrate]
        include:
          - target: app
            image: teable-community
          - target: db-migrate
            image: teable-db-migrate-community

    steps:
      - name: Login to GitHub container registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.PACKAGES_KEY }}

      - name: Login to Docker Hub registry
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKER_HUB_NAME }}
          password: ${{ secrets.DOCKER_HUB_AK }}

      - name: Login to Ali container registry
        uses: docker/login-action@v3
        with:
          registry: registry.cn-shenzhen.aliyuncs.com
          username: ${{ secrets.ALI_DOCKER_USERNAME }}
          password: ${{ secrets.ALI_DOCKER_PASSWORD }}

      - name: Create and push manifest
        run: |
          REGISTRIES=("registry.cn-shenzhen.aliyuncs.com/teable" "ghcr.io/teableio" "docker.io/teableio")
          TAGS=("latest" "sha-${{ github.sha }}")

          for REGISTRY in "${REGISTRIES[@]}"; do
            for TAG in "${TAGS[@]}"; do
              docker manifest create $REGISTRY/${{ matrix.image }}:$TAG \
                $REGISTRY/${{ matrix.image }}:${TAG}-amd64 \
                $REGISTRY/${{ matrix.image }}:${TAG}-arm64
              
              docker manifest push $REGISTRY/${{ matrix.image }}:$TAG
            done
          done


================================================
FILE: .github/workflows/integration-tests.yml
================================================
name: Integration Tests

on:
  push:
    branches:
      - develop
  pull_request:
    branches:
      - develop
    paths:
      - 'apps/nestjs-backend/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    name: Integration Tests - ${{ matrix.e2e.database-type }} ${{ matrix.e2e.shard }} ${{ matrix.runtime.mode }}

    strategy:
      fail-fast: false
      matrix:
        node-version: [22.18.0]
        runtime:
          - mode: v1
            force-v2-all: ''
            computed-update-mode: ''
          - mode: v2
            force-v2-all: 'true'
            computed-update-mode: 'sync'
        e2e:
          - database-type: postgres
            shard: 1/4
          - database-type: postgres
            shard: 2/4
          - database-type: postgres
            shard: 3/4
          - database-type: postgres
            shard: 4/4
    env:
      CI: 1

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: 📥 Monorepo install
        uses: ./.github/actions/pnpm-install

      - name: 🧪 Run Tests
        env:
          CI: 1
          FORCE_V2_ALL: ${{ matrix.runtime.force-v2-all }}
          V2_COMPUTED_UPDATE_MODE: ${{ matrix.runtime.computed-update-mode }}
          VITEST_MAX_THREADS: 2
          VITEST_MIN_THREADS: 1
          VITEST_SHARD: ${{ matrix.e2e.shard }}
          VITEST_REPORTER: blob
        run: |
          make ${{ matrix.e2e.database-type }}.integration.test
          pnpm -F "@teable/backend" test-unit-cover
          pnpm -F "@teable/backend" merge-cover
          pnpm -F "@teable/backend" generate-cover

      - name: Coveralls Parallel
        uses: coverallsapp/github-action@v2
        with:
          flag-name: run-${{ join(matrix.*, '-') }}
          file: apps/nestjs-backend/coverage/nestjs-backend/clover.xml
          parallel: true

  finish:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: Coveralls Finished
        uses: coverallsapp/github-action@v2
        with:
          parallel-finished: true


================================================
FILE: .github/workflows/issue-id-check.yml
================================================
name: Issue ID Check

on:
  pull_request:
    types: [opened, synchronize, edited, reopened]
    branches:
      - develop

permissions:
  pull-requests: write

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  check-issue-ids:
    runs-on: ubuntu-latest
    name: Check Issue IDs

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: 🔍 Extract Issue IDs from PR
        id: extract-issues
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}
          PR_BODY: ${{ github.event.pull_request.body }}
          BASE_SHA: ${{ github.event.pull_request.base.sha }}
          HEAD_SHA: ${{ github.event.pull_request.head.sha }}
        run: |
          echo "🔍 Checking for Issue IDs (pattern: T followed by numbers)..."

          # Extract Issue IDs from PR title
          echo "📝 PR Title: $PR_TITLE"
          TITLE_ISSUES=$(echo "$PR_TITLE" | grep -oE 'T[0-9]+' || true)

          # Extract Issue IDs from PR body/description
          echo "📝 PR Body:"
          echo "$PR_BODY"
          BODY_ISSUES=$(echo "$PR_BODY" | grep -oE 'T[0-9]+' || true)

          # Extract Issue IDs from all commit messages (including body)
          echo "📝 Commit Messages:"
          COMMIT_MESSAGES=$(git log --format="%B" $BASE_SHA..$HEAD_SHA 2>/dev/null || git log --format="%B" -n 20)
          echo "$COMMIT_MESSAGES"
          COMMIT_ISSUES=$(echo "$COMMIT_MESSAGES" | grep -oE 'T[0-9]+' || true)

          # Combine all Issue IDs and remove duplicates
          ALL_ISSUES=$(echo -e "$TITLE_ISSUES\n$BODY_ISSUES\n$COMMIT_ISSUES" | grep -E '^T[0-9]+$' | sort -u | tr '\n' ' ' | xargs)

          echo "📋 Found Issue IDs: $ALL_ISSUES"

          if [ -z "$ALL_ISSUES" ]; then
            echo "❌ No Issue IDs found!"
            echo "issue_ids=" >> $GITHUB_OUTPUT
            echo "has_issues=false" >> $GITHUB_OUTPUT
          else
            echo "✅ Found Issue IDs: $ALL_ISSUES"
            echo "issue_ids=$ALL_ISSUES" >> $GITHUB_OUTPUT
            echo "has_issues=true" >> $GITHUB_OUTPUT
          fi

      - name: ❌ Fail if no Issue IDs found
        if: steps.extract-issues.outputs.has_issues == 'false'
        run: |
          echo "::error::No Issue IDs found in PR title, body, or commit messages."
          echo "Please include at least one Issue ID (format: T followed by numbers, e.g., T1263) in:"
          echo "  - PR title"
          echo "  - PR description/body"
          echo "  - Commit message (including body)"
          exit 1

      - name: 🔗 Verify Issue IDs exist in Teable
        if: steps.extract-issues.outputs.has_issues == 'true'
        id: verify-issues
        env:
          TEABLE_API_TOKEN: ${{ secrets.APP_TEABLE_AI_TOKEN }}
          ISSUE_IDS: ${{ steps.extract-issues.outputs.issue_ids }}
          PR_URL: ${{ github.event.pull_request.html_url }}
        run: |
          echo "🔗 Verifying Issue IDs in Teable: $ISSUE_IDS"

          # Build filter for multiple Issue IDs
          FILTER_SET=""
          for ISSUE_ID in $ISSUE_IDS; do
            if [ -n "$FILTER_SET" ]; then
              FILTER_SET="$FILTER_SET,"
            fi
            FILTER_SET="$FILTER_SET{\"fieldId\":\"Issue_ID\",\"operator\":\"is\",\"value\":\"$ISSUE_ID\"}"
          done

          FILTER="{\"conjunction\":\"or\",\"filterSet\":[$FILTER_SET]}"
          ENCODED_FILTER=$(echo "$FILTER" | jq -sRr @uri)

          echo "📤 Querying Teable API..."

          RESPONSE=$(curl -s -w "\n%{http_code}" -X GET \
            "https://app.teable.ai/api/table/tblNHimLUhUDtC3K7Jk/record?fieldKeyType=dbFieldName&viewId=viwBK7iTy1604XbFdYh&filter=$ENCODED_FILTER" \
            -H "Authorization: Bearer $TEABLE_API_TOKEN" \
            -H "Accept: application/json")

          HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
          BODY=$(echo "$RESPONSE" | sed '$d')

          echo "📥 API Response Code: $HTTP_CODE"

          if [ "$HTTP_CODE" != "200" ]; then
            echo "::error::Failed to query Teable API. HTTP Code: $HTTP_CODE"
            echo "Response: $BODY"
            exit 1
          fi

          # Check if records exist
          RECORD_COUNT=$(echo "$BODY" | jq '.records | length')
          echo "📊 Found $RECORD_COUNT matching records in Teable"

          if [ "$RECORD_COUNT" -eq 0 ]; then
            echo "::error::No matching Issue IDs found in Teable. Please ensure the Issue IDs ($ISSUE_IDS) exist."
            exit 1
          fi

          # Extract record IDs and their statuses for updating
          echo "$BODY" | jq -c '.records[] | {id: .id, status: .fields.status}' > /tmp/records.json

          RECORD_IDS=$(echo "$BODY" | jq -r '.records[].id')
          echo "record_ids<<EOF" >> $GITHUB_OUTPUT
          echo "$RECORD_IDS" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
          echo "record_count=$RECORD_COUNT" >> $GITHUB_OUTPUT

          # Save full response for status checking
          echo "$BODY" > /tmp/teable_response.json

          echo "✅ All Issue IDs verified successfully!"

      - name: 📝 Update Teable records (Community_PR & Status)
        if: steps.extract-issues.outputs.has_issues == 'true' && steps.verify-issues.outputs.record_count > 0
        env:
          TEABLE_API_TOKEN: ${{ secrets.APP_TEABLE_AI_TOKEN }}
          PR_URL: ${{ github.event.pull_request.html_url }}
        run: |
          echo "📝 Updating Teable records..."

          # Status values that should be updated to "Entered development workflow"
          STATUSES_TO_UPDATE=("" "Need more information" "Added to backlog")

          # Read records from saved response
          cat /tmp/teable_response.json | jq -c '.records[]' | while read -r record; do
            RECORD_ID=$(echo "$record" | jq -r '.id')
            CURRENT_STATUS=$(echo "$record" | jq -r '.fields.status // ""')
            
            echo "Processing record: $RECORD_ID (current status: '$CURRENT_STATUS')"
            
            # Determine if status should be updated
            SHOULD_UPDATE_STATUS="false"
            for status in "${STATUSES_TO_UPDATE[@]}"; do
              if [ "$CURRENT_STATUS" == "$status" ]; then
                SHOULD_UPDATE_STATUS="true"
                break
              fi
            done
            
            # Build update payload
            if [ "$SHOULD_UPDATE_STATUS" == "true" ]; then
              echo "  → Status will be updated to 'Entered development workflow'"
              UPDATE_PAYLOAD="{\"fieldKeyType\":\"dbFieldName\",\"record\":{\"fields\":{\"Community_PR\":\"$PR_URL\",\"status\":\"Entered development workflow\"}}}"
            else
              echo "  → Status will not be changed (current: '$CURRENT_STATUS')"
              UPDATE_PAYLOAD="{\"fieldKeyType\":\"dbFieldName\",\"record\":{\"fields\":{\"Community_PR\":\"$PR_URL\"}}}"
            fi
            
            # Send update request
            UPDATE_RESPONSE=$(curl -s -w "\n%{http_code}" -X PATCH \
              "https://app.teable.ai/api/table/tblNHimLUhUDtC3K7Jk/record/$RECORD_ID" \
              -H "Authorization: Bearer $TEABLE_API_TOKEN" \
              -H "Content-Type: application/json" \
              -H "Accept: application/json" \
              -d "$UPDATE_PAYLOAD")
            
            HTTP_CODE=$(echo "$UPDATE_RESPONSE" | tail -n1)
            BODY=$(echo "$UPDATE_RESPONSE" | sed '$d')
            
            if [ "$HTTP_CODE" != "200" ]; then
              echo "::warning::Failed to update record $RECORD_ID. HTTP Code: $HTTP_CODE"
              echo "Response: $BODY"
            else
              echo "✅ Successfully updated record $RECORD_ID"
            fi
          done

          echo "✅ Teable records update completed!"

      - name: 📝 Append Issue IDs to PR description
        if: steps.extract-issues.outputs.has_issues == 'true' && steps.verify-issues.outputs.record_count > 0
        env:
          GH_TOKEN: ${{ github.token }}
          ISSUE_IDS: ${{ steps.extract-issues.outputs.issue_ids }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
          PR_BODY: ${{ github.event.pull_request.body }}
        run: |
          echo "📝 Checking if Issue IDs need to be appended to PR description..."

          # Create Issue IDs reference line
          ISSUE_IDS_LINE="**Related Issues:** $ISSUE_IDS"

          # Check if Issue IDs are already in the PR body
          ISSUES_ALREADY_IN_BODY="true"
          for ISSUE_ID in $ISSUE_IDS; do
            if ! echo "$PR_BODY" | grep -q "$ISSUE_ID"; then
              ISSUES_ALREADY_IN_BODY="false"
              break
            fi
          done

          # Check if the reference line already exists
          if echo "$PR_BODY" | grep -q "^\*\*Related Issues:\*\*"; then
            echo "✅ Related Issues line already exists in PR description, skipping update"
            exit 0
          fi

          # If all Issue IDs are already in the body but not in the reference format, we still want to add the reference line
          # This ensures consistency and makes it easier to parse

          echo "📝 Appending Issue IDs to PR description..."

          # Append Issue IDs to PR body
          if [ -z "$PR_BODY" ]; then
            NEW_BODY="$ISSUE_IDS_LINE"
          else
            NEW_BODY="$PR_BODY

          ---
          $ISSUE_IDS_LINE"
          fi

          # Update PR description using GitHub CLI
          gh pr edit "$PR_NUMBER" --body "$NEW_BODY"

          echo "✅ PR description updated with Issue IDs!"

      - name: ✅ Check Complete
        if: steps.extract-issues.outputs.has_issues == 'true'
        run: |
          echo "✅ Issue ID check completed successfully!"
          echo "📋 Verified Issue IDs: ${{ steps.extract-issues.outputs.issue_ids }}"
          echo "🔗 PR URL and status updated in Teable records"
          echo "📝 Issue IDs appended to PR description for squash merge"


================================================
FILE: .github/workflows/linting.yml
================================================
name: Linting and Types

on:
  pull_request:
    branches:
      - develop
    paths:
      - 'apps/**'
      - 'packages/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  build:
    runs-on: ubuntu-latest
    name: Linting and Types

    strategy:
      matrix:
        node-version: [22.18.0]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: 📥 Monorepo install
        uses: ./.github/actions/pnpm-install

      - name: 🧩 Generate Prisma Client
        working-directory: packages/db-main-prisma
        run: |
          pnpm -F @teable/db-main-prisma prisma-generate --schema ./prisma/postgres/schema.prisma

      - name: 🏗 Run build
        run: |
          pnpm -F "./packages/**" run build

      - name: 🕵️ Typecheck
        run: |
          pnpm g:typecheck

      - name: 🔬 Linter
        run: |
          pnpm g:lint
          pnpm g:lint-styles


================================================
FILE: .github/workflows/manual-preview.yml
================================================
name: Preview PR

permissions:
  contents: read
  pull-requests: write

on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
      - labeled
      - unlabeled

env:
  NAMESPACE: 38puz7wo
  INSTANCE_NAME: pr-${{ github.event.pull_request.number }}
  INSTANCE_DOMAIN: pr-${{ github.event.pull_request.number }}
  DISPLAY_NAME: 'teable-pr-${{ github.event.pull_request.number }}'
  MAIN_IMAGE_REPOSITORY: registry.cn-shenzhen.aliyuncs.com/teable/teable
  IMAGE_TAG: ${{ github.sha }}-amd64

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  check-pr:
    runs-on: ubuntu-latest
    outputs:
      should_deploy: ${{ steps.check.outputs.should_deploy }}
    steps:
      - name: Check PR labels
        id: check
        uses: actions/github-script@v6
        with:
          script: |
            const hasPreviewLabel = context.payload.pull_request.labels.some(
              label => label.name === 'preview'
            );
            console.log('Has preview label:', hasPreviewLabel);
            core.setOutput('should_deploy', hasPreviewLabel.toString());
            return hasPreviewLabel;

  build-push:
    needs: check-pr
    if: needs.check-pr.outputs.should_deploy == 'true'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - image: teable
            file: Dockerfile
          - image: teable-db-migrate
            file: Dockerfile.db-migrate
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Login to Ali container registry
        uses: docker/login-action@v3
        with:
          registry: registry.cn-shenzhen.aliyuncs.com
          username: ${{ secrets.ALI_DOCKER_USERNAME }}
          password: ${{ secrets.ALI_DOCKER_PASSWORD }}

      - uses: actions/setup-node@v4
        with:
          node-version: 22.18.0
      - name: ⚙️ Install zx
        run: npm install -g zx

      - name: ⚙️ Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: |
            registry.cn-shenzhen.aliyuncs.com/teable/${{ matrix.image }}
          tags: |
            type=raw,value=alpha-pr-${{ github.event.pull_request.number }}
            type=raw,value=${{ github.sha }}
      - name: ⚙️ Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: 📦 Build and push
        run: |
          zx scripts/build-image.mjs --file=dockers/teable/${{ matrix.file }} \
              --build-arg="ENABLE_CSP=false" \
              --tag="${{ steps.meta.outputs.tags }}" \
              --platform="linux/amd64" \
              --push

  deploy:
    needs: [check-pr, build-push]
    if: needs.check-pr.outputs.should_deploy == 'true'
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Create deployment YAML
        run: |
          cp .github/workflows/templates/preview-template.yaml deploy.yaml
          sed -i "s#__NAMESPACE__#${{ env.NAMESPACE }}#g" deploy.yaml
          sed -i "s#__INSTANCE_NAME__#${{ env.INSTANCE_NAME }}#g" deploy.yaml
          sed -i "s#__INSTANCE_DOMAIN__#${{ env.INSTANCE_DOMAIN }}#g" deploy.yaml
          sed -i "s#__MAIN_IMAGE_REPOSITORY__#${{ env.MAIN_IMAGE_REPOSITORY }}#g" deploy.yaml
          sed -i "s#__IMAGE_TAG__#${{ env.IMAGE_TAG }}#g" deploy.yaml
          sed -i "s#__DISPLAY_NAME__#${{ env.DISPLAY_NAME }}#g" deploy.yaml

      - name: Apply deploy job
        uses: actions-hub/kubectl@master
        env:
          KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
        with:
          args: apply -f deploy.yaml

      - name: Rollout status
        uses: actions-hub/kubectl@master
        env:
          KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
        with:
          args: rollout status deployment/teable-${{ env.INSTANCE_NAME }} --timeout=300s

      - name: Wait for application health check
        uses: actions-hub/kubectl@master
        env:
          KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
        with:
          args: exec deployment/teable-${{ env.INSTANCE_NAME }} -- curl -f --retry 30 --retry-delay 5 --retry-connrefused http://localhost:3000/health

      - name: Create deployment status comment
        if: always()
        env:
          JOB_STATUS: ${{ job.status }}
        uses: actions/github-script@v6
        with:
          script: |
            const success = process.env.JOB_STATUS === 'success';
            const deploymentUrl = `https://${process.env.INSTANCE_DOMAIN}.sealoshzh.site`;
            const status = success ? '✅ Success' : '❌ Failed';
            console.log(process.env.JOB_STATUS);

            const commentBody = `**Deployment Status: ${status}**
            ${success ? `🔗 Preview URL: ${deploymentUrl}` : ''}`;

            await github.rest.issues.createComment({
              ...context.repo,
              issue_number: context.payload.pull_request.number,
              body: commentBody
            });


================================================
FILE: .github/workflows/preview-cleanup.yml
================================================
name: Cleanup Preview Environment

on:
  pull_request:
    types: [closed]

env:
  NAMESPACE: 38puz7wo
  INSTANCE_NAME: pr-${{ github.event.pull_request.number }}
  INSTANCE_DOMAIN: pr-${{ github.event.pull_request.number }}
  DISPLAY_NAME: "teable-pr-${{ github.event.pull_request.number }}"
  MAIN_IMAGE_REPOSITORY: registry.cn-shenzhen.aliyuncs.com/teable/teable
  IMAGE_TAG: ${{ github.sha }}-amd64

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Create deployment YAML
        run: |
          cp .github/workflows/templates/preview-template.yaml deploy.yaml
          sed -i "s#__NAMESPACE__#${{ env.NAMESPACE }}#g" deploy.yaml
          sed -i "s#__INSTANCE_NAME__#${{ env.INSTANCE_NAME }}#g" deploy.yaml
          sed -i "s#__INSTANCE_DOMAIN__#${{ env.INSTANCE_DOMAIN }}#g" deploy.yaml
          sed -i "s#__MAIN_IMAGE_REPOSITORY__#${{ env.MAIN_IMAGE_REPOSITORY }}#g" deploy.yaml
          sed -i "s#__IMAGE_TAG__#${{ env.IMAGE_TAG }}#g" deploy.yaml
          sed -i "s#__DISPLAY_NAME__#${{ env.DISPLAY_NAME }}#g" deploy.yaml

      - name: Delete deployment
        uses: actions-hub/kubectl@master
        env:
          KUBE_CONFIG: ${{ secrets.KUBE_CONFIG }}
        with:
          args: delete -f deploy.yaml --ignore-not-found=true

      - name: Create cleanup status comment
        uses: actions/github-script@v6
        with:
          script: |
            const prNumber = context.payload.pull_request.number;
            const mergeStatus = context.payload.pull_request.merged ? 'Merged' : 'Closed';
            
            const commentBody = `## 🧹 Preview Environment Cleanup
            * PR #${prNumber} has been ${mergeStatus}
            * Preview environment has been deleted
            * Cleanup time: ${new Date().toISOString()}`;

            await github.rest.issues.createComment({
              ...context.repo,
              issue_number: prNumber,
              body: commentBody
            });


================================================
FILE: .github/workflows/templates/preview-template.yaml
================================================
apiVersion: app.sealos.io/v1
kind: Instance
metadata:
  name: teable-__INSTANCE_NAME__
  labels:
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
spec:
  gitRepo: https://github.com/teableio/teable
  templateType: inline
  categories:
    - database
    - low-code
  defaults:
    app_host:
      type: string
      value: __INSTANCE_DOMAIN__
    app_name:
      type: string
      value: teable-__INSTANCE_NAME__
    jwt_secret:
      type: string
      value: exdpbfxmlqhjnqxu
    session_secret:
      type: string
      value: lvgxahpasprcclii
  inputs: null
  title: teable
  url: teable.cn
  author: Sealos
  description: >-
    Teable is a Super fast, Real-time, Professional, Developer friendly, No-code
    database built on Postgres.
  readme: https://cdn.jsdelivr.net/gh/teableio/teable@develop/README.md
  icon: https://framerusercontent.com/images/x9gZmjwbtvaGd95qbfUmsZ8Jc.png

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: teable-__INSTANCE_NAME__
  annotations:
    originImageName: >-
      __MAIN_IMAGE_REPOSITORY__:__IMAGE_TAG__
    deploy.cloud.sealos.io/minReplicas: '1'
    deploy.cloud.sealos.io/maxReplicas: '1'
  labels:
    cloud.sealos.io/app-deploy-manager: teable-__INSTANCE_NAME__
    app: teable-__INSTANCE_NAME__
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
spec:
  replicas: 1
  revisionHistoryLimit: 1
  minReadySeconds: 10
  selector:
    matchLabels:
      app: teable-__INSTANCE_NAME__
  template:
    metadata:
      labels:
        app: teable-__INSTANCE_NAME__
    spec:
      terminationGracePeriodSeconds: 10
      automountServiceAccountToken: false
      initContainers:
        - name: db-migrate
          image: >-
            __MAIN_IMAGE_REPOSITORY__:__IMAGE_TAG__
          args: ['migrate-only']
          env:
            - name: PG_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-pg-conn-credential
                  key: password
            - name: PG_PORT
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-pg-conn-credential
                  key: port
            - name: PRISMA_DATABASE_URL
              value: >-
                postgresql://postgres:$(PG_PASSWORD)@teable-__INSTANCE_NAME__-pg-postgresql.ns-__NAMESPACE__.svc:$(PG_PORT)/teable
            - name: PRISMA_ENGINES_CHECKSUM_IGNORE_MISSING
              value: '1'
          resources:
            requests:
              cpu: 100m
              memory: 102Mi
            limits:
              cpu: 1000m
              memory: 1024Mi
      containers:
        - name: teable-__INSTANCE_NAME__
          image: >-
            __MAIN_IMAGE_REPOSITORY__:__IMAGE_TAG__
          args: ['skip-migrate']
          env:
            - name: PG_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-pg-conn-credential
                  key: password
            - name: PG_PORT
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-pg-conn-credential
                  key: port
            - name: PRISMA_DATABASE_URL
              value: >-
                postgresql://postgres:$(PG_PASSWORD)@teable-__INSTANCE_NAME__-pg-postgresql.ns-__NAMESPACE__.svc:$(PG_PORT)/teable
            - name: PUBLIC_ORIGIN
              value: https://__INSTANCE_DOMAIN__.sealoshzh.site
            - name: BACKEND_JWT_SECRET
              value: exdpbfxmlqhjnqxu
            - name: BACKEND_SESSION_SECRET
              value: lvgxahpasprcclii
            - name: BACKEND_STORAGE_PROVIDER
              value: minio
            - name: BACKEND_STORAGE_PUBLIC_BUCKET
              valueFrom:
                secretKeyRef:
                  name: object-storage-key-__NAMESPACE__-teable-__INSTANCE_NAME__-public
                  key: bucket
            - name: BACKEND_STORAGE_PRIVATE_BUCKET
              valueFrom:
                secretKeyRef:
                  name: object-storage-key-__NAMESPACE__-teable-__INSTANCE_NAME__-private
                  key: bucket
            - name: BACKEND_STORAGE_MINIO_ENDPOINT
              valueFrom:
                secretKeyRef:
                  name: object-storage-key
                  key: external
            - name: BACKEND_STORAGE_MINIO_INTERNAL_ENDPOINT
              valueFrom:
                secretKeyRef:
                  name: object-storage-key
                  key: internal
            - name: BACKEND_STORAGE_MINIO_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: object-storage-key
                  key: accessKey
            - name: BACKEND_STORAGE_MINIO_SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: object-storage-key
                  key: secretKey
            - name: BACKEND_STORAGE_MINIO_PORT
              value: '443'
            - name: BACKEND_STORAGE_MINIO_INTERNAL_PORT
              value: '80'
            - name: BACKEND_STORAGE_MINIO_USE_SSL
              value: 'true'
            - name: STORAGE_PREFIX
              value: https://$(BACKEND_STORAGE_MINIO_ENDPOINT)
            - name: BACKEND_CACHE_PROVIDER
              value: redis
            - name: REDIS_HOST
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-redis-conn-credential
                  key: host
            - name: REDIS_PORT
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-redis-conn-credential
                  key: port
            - name: REDIS_USERNAME
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-redis-conn-credential
                  key: username
            - name: REDIS_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-redis-conn-credential
                  key: password
            - name: BACKEND_CACHE_REDIS_URI
              value: >-
                redis://$(REDIS_USERNAME):$(REDIS_PASSWORD)@$(REDIS_HOST).ns-__NAMESPACE__.svc:$(REDIS_PORT)/1
          resources:
            requests:
              cpu: 200m
              memory: 400Mi
            limits:
              cpu: 1000m
              memory: 1024Mi
          ports:
            - containerPort: 3000
          imagePullPolicy: IfNotPresent
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 30
            periodSeconds: 30
            timeoutSeconds: 3
      securityContext:
        fsGroup: 1000

---
apiVersion: v1
kind: Service
metadata:
  name: teable-__INSTANCE_NAME__
  labels:
    cloud.sealos.io/app-deploy-manager: teable-__INSTANCE_NAME__
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
spec:
  ports:
    - port: 3000
  selector:
    app: teable-__INSTANCE_NAME__

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: teable-__INSTANCE_NAME__
  labels:
    cloud.sealos.io/app-deploy-manager: teable-__INSTANCE_NAME__
    cloud.sealos.io/app-deploy-manager-domain: __INSTANCE_DOMAIN__
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/proxy-body-size: 32m
    nginx.ingress.kubernetes.io/server-snippet: |
      client_header_buffer_size 64k;
      large_client_header_buffers 4 128k;
    nginx.ingress.kubernetes.io/ssl-redirect: 'false'
    nginx.ingress.kubernetes.io/backend-protocol: HTTP
    nginx.ingress.kubernetes.io/client-body-buffer-size: 64k
    nginx.ingress.kubernetes.io/proxy-buffer-size: 64k
    nginx.ingress.kubernetes.io/proxy-send-timeout: '300'
    nginx.ingress.kubernetes.io/proxy-read-timeout: '300'
spec:
  rules:
    - host: __INSTANCE_DOMAIN__.sealoshzh.site
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: teable-__INSTANCE_NAME__
                port:
                  number: 3000
  tls:
    - hosts:
        - __INSTANCE_DOMAIN__.sealoshzh.site
      secretName: wildcard-cert

---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-pg
    app.kubernetes.io/instance: teable-__INSTANCE_NAME__-pg
    app.kubernetes.io/managed-by: kbcli
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  name: teable-__INSTANCE_NAME__-pg

---
apiVersion: apps.kubeblocks.io/v1alpha1
kind: Cluster
metadata:
  finalizers:
    - cluster.kubeblocks.io/finalizer
  labels:
    clusterdefinition.kubeblocks.io/name: postgresql
    clusterversion.kubeblocks.io/name: postgresql-14.8.0
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-pg
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  annotations: {}
  name: teable-__INSTANCE_NAME__-pg
spec:
  affinity:
    nodeLabels: {}
    podAntiAffinity: Preferred
    tenancy: SharedNode
    topologyKeys: []
  clusterDefinitionRef: postgresql
  clusterVersionRef: postgresql-14.8.0
  componentSpecs:
    - componentDefRef: postgresql
      monitor: true
      name: postgresql
      replicas: 1
      resources:
        limits:
          cpu: 500m
          memory: 512Mi
        requests:
          cpu: 100m
          memory: 102Mi
      serviceAccountName: teable-__INSTANCE_NAME__-pg
      switchPolicy:
        type: Noop
      volumeClaimTemplates:
        - name: data
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 1Gi
  terminationPolicy: Delete
  tolerations: []

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-pg
    app.kubernetes.io/instance: teable-__INSTANCE_NAME__-pg
    app.kubernetes.io/managed-by: kbcli
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  name: teable-__INSTANCE_NAME__-pg
rules:
  - apiGroups:
      - '*'
    resources:
      - '*'
    verbs:
      - '*'

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-pg
    app.kubernetes.io/instance: teable-__INSTANCE_NAME__-pg
    app.kubernetes.io/managed-by: kbcli
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  name: teable-__INSTANCE_NAME__-pg
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: teable-__INSTANCE_NAME__-pg
subjects:
  - kind: ServiceAccount
    name: teable-__INSTANCE_NAME__-pg

---
apiVersion: batch/v1
kind: Job
metadata:
  name: teable-__INSTANCE_NAME__-init
  labels:
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
spec:
  completions: 1
  template:
    spec:
      containers:
        - name: pgsql-init
          image: senzing/postgresql-client:2.2.4
          env:
            - name: PG_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: teable-__INSTANCE_NAME__-pg-conn-credential
                  key: password
            - name: DATABASE_URL
              value: >-
                postgresql://postgres:$(PG_PASSWORD)@teable-__INSTANCE_NAME__-pg-postgresql.ns-__NAMESPACE__.svc:5432
          command:
            - /bin/sh
            - '-c'
            - >
              until psql ${DATABASE_URL} -c 'CREATE DATABASE teable;'
              &>/dev/null; do sleep 1; done
      restartPolicy: Never
  backoffLimit: 0
  ttlSecondsAfterFinished: 300

---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-redis
    app.kubernetes.io/instance: teable-__INSTANCE_NAME__-redis
    app.kubernetes.io/managed-by: kbcli
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  name: teable-__INSTANCE_NAME__-redis

---
apiVersion: apps.kubeblocks.io/v1alpha1
kind: Cluster
metadata:
  finalizers:
    - cluster.kubeblocks.io/finalizer
  labels:
    clusterdefinition.kubeblocks.io/name: redis
    clusterversion.kubeblocks.io/name: redis-7.0.6
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-redis
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  annotations: {}
  name: teable-__INSTANCE_NAME__-redis
spec:
  affinity:
    nodeLabels: {}
    podAntiAffinity: Preferred
    tenancy: SharedNode
    topologyKeys: []
  clusterDefinitionRef: redis
  clusterVersionRef: redis-7.0.6
  componentSpecs:
    - componentDefRef: redis
      monitor: true
      name: redis
      replicas: 1
      resources:
        limits:
          cpu: 500m
          memory: 512Mi
        requests:
          cpu: 100m
          memory: 102Mi
      serviceAccountName: teable-__INSTANCE_NAME__-redis
      switchPolicy:
        type: Noop
      volumeClaimTemplates:
        - name: data
          spec:
            accessModes:
              - ReadWriteOnce
            resources:
              requests:
                storage: 1Gi
    - componentDefRef: redis-sentinel
      monitor: true
      name: redis-sentinel
      replicas: 1
      resources:
        limits:
          cpu: 100m
          memory: 100Mi
        requests:
          cpu: 100m
          memory: 100Mi
      serviceAccountName: teable-__INSTANCE_NAME__-redis
  terminationPolicy: Delete
  tolerations: []

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-redis
    app.kubernetes.io/instance: teable-__INSTANCE_NAME__-redis
    app.kubernetes.io/managed-by: kbcli
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  name: teable-__INSTANCE_NAME__-redis
rules:
  - apiGroups:
      - '*'
    resources:
      - '*'
    verbs:
      - '*'

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    sealos-db-provider-cr: teable-__INSTANCE_NAME__-redis
    app.kubernetes.io/instance: teable-__INSTANCE_NAME__-redis
    app.kubernetes.io/managed-by: kbcli
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
  name: teable-__INSTANCE_NAME__-redis
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: teable-__INSTANCE_NAME__-redis
subjects:
  - kind: ServiceAccount
    name: teable-__INSTANCE_NAME__-redis
    namespace: ns-__NAMESPACE__

---
apiVersion: objectstorage.sealos.io/v1
kind: ObjectStorageBucket
metadata:
  name: teable-__INSTANCE_NAME__-private
  labels:
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
spec:
  policy: private

---
apiVersion: objectstorage.sealos.io/v1
kind: ObjectStorageBucket
metadata:
  name: teable-__INSTANCE_NAME__-public
  labels:
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
spec:
  policy: publicRead

---
apiVersion: app.sealos.io/v1
kind: App
metadata:
  name: teable-__INSTANCE_NAME__
  labels:
    cloud.sealos.io/app-deploy-manager: teable-__INSTANCE_NAME__
    cloud.sealos.io/deploy-on-sealos: teable-__INSTANCE_NAME__
spec:
  data:
    url: https://__INSTANCE_DOMAIN__.sealoshzh.site
  displayType: normal
  icon: https://framerusercontent.com/images/x9gZmjwbtvaGd95qbfUmsZ8Jc.png
  name: __DISPLAY_NAME__
  type: link


================================================
FILE: .github/workflows/trigger-sync-to-ee.yml
================================================
name: Trigger Sync to EE

on:
  push:
    branches:
      - develop

jobs:
  check-and-trigger:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Get latest commit info
        id: commit-info
        run: |
          COMMIT_MSG=$(git log -1 --format="%s")
          COMMIT_AUTHOR=$(git log -1 --format="%an")
          
          echo "message=$COMMIT_MSG" >> $GITHUB_OUTPUT
          echo "author=$COMMIT_AUTHOR" >> $GITHUB_OUTPUT

      - name: Check if should trigger sync
        id: check-trigger
        run: |
          COMMIT_MSG="${{ steps.commit-info.outputs.message }}"
          COMMIT_AUTHOR="${{ steps.commit-info.outputs.author }}"
          
          # Skip if commit message contains [sync] marker or author is the sync bot
          # This prevents circular sync loops
          if [[ "$COMMIT_MSG" == *"[sync]"* ]] || [[ "$COMMIT_AUTHOR" == "teable-bot" ]]; then
            echo "trigger=false" >> $GITHUB_OUTPUT
            echo "⏭️ Skipping trigger: commit is from sync workflow"
          else
            echo "trigger=true" >> $GITHUB_OUTPUT
            echo "✅ Will trigger sync to EE"
          fi

      - name: Trigger sync to EE
        if: steps.check-trigger.outputs.trigger == 'true'
        run: |
          curl -X POST \
            -H "Accept: application/vnd.github.v3+json" \
            -H "Authorization: token ${{ secrets.BOT_TOKEN }}" \
            https://api.github.com/repos/teableio/teable-ee/dispatches \
            -d '{"event_type": "sync-from-opensource"}'
          
          echo "✅ Triggered sync workflow in teable-ee"

      - name: Skipped
        if: steps.check-trigger.outputs.trigger == 'false'
        run: echo "⏭️ Sync trigger skipped to avoid circular dependency"



================================================
FILE: .github/workflows/unit-tests.yml
================================================
name: Unit Tests

on:
  push:
    branches:
      - develop
  pull_request:
    branches:
      - develop
    paths:
      - 'apps/nextjs-app/**'
      - 'packages/core/**'
      - 'packages/sdk/**'
      - 'packages/openapi/**'
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true
jobs:
  test:
    runs-on: ubuntu-latest
    name: Unit Tests

    strategy:
      matrix:
        node-version: [22.18.0]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: 📥 Monorepo install
        uses: ./.github/actions/pnpm-install

      - name: 🧩 Generate Prisma Client
        working-directory: packages/db-main-prisma
        run: |
          pnpm -F @teable/db-main-prisma prisma-generate --schema ./prisma/postgres/schema.prisma

      - name: 🏗 Run build
        run: |
          pnpm -F "./packages/**" run build

      - name: 🧪 Run Tests
        run: |
          pnpm -F "!@teable/backend" -r --parralel test-unit


================================================
FILE: .github/workflows/v2-benchmark-tests.yml
================================================
name: V2 Benchmarks

on:
  workflow_dispatch:
  pull_request:
    branches:
      - develop
    paths:
      - 'packages/v2/**'
      - '.github/workflows/v2-benchmark-tests.yml'

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  bench:
    runs-on: ubuntu-latest
    name: V2 Benchmarks
    env:
      CI: 1
      TESTCONTAINERS_REUSE_ENABLE: 'false'

    strategy:
      matrix:
        node-version: [22.18.0]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: 📥 Monorepo install
        uses: ./.github/actions/pnpm-install

      - name: 🧪 Run v2 benchmarks
        run: |
          pnpm -C packages/v2/benchmark-node bench


================================================
FILE: .github/workflows/v2-core-tests.yml
================================================
name: V2 Tests

on:
  pull_request:
    branches:
      - develop

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  # Unit tests - run each package in parallel
  unit-tests:
    runs-on: ubuntu-latest
    name: V2 Unit Tests (${{ matrix.package }})
    env:
      CI: 1
      TESTCONTAINERS_REUSE_ENABLE: 'false'

    strategy:
      fail-fast: false
      max-parallel: 6
      matrix:
        package:
          - '@teable/v2-adapter-db-postgres-pg'
          - '@teable/v2-adapter-repository-postgres'
          - '@teable/v2-adapter-table-repository-postgres'
          - '@teable/v2-core'
          - '@teable/v2-formula-sql-pg'
          - '@teable/v2-test-node'

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js 22.18.0
        uses: actions/setup-node@v4
        with:
          node-version: 22.18.0

      - name: 📥 Monorepo install
        uses: ./.github/actions/pnpm-install
        with:
          filter: ${{ matrix.package }}

      - name: 🧪 Run unit tests (${{ matrix.package }})
        run: |
          pnpm -F "${{ matrix.package }}" --if-present test-unit-cover

  # E2E tests - use sharding for parallel execution (the slowest tests)
  e2e-tests:
    runs-on: ubuntu-latest
    name: V2 E2E Tests (Shard ${{ matrix.shard }}/4)
    env:
      CI: 1
      TESTCONTAINERS_REUSE_ENABLE: 'false'

    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3, 4]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js 22.18.0
        uses: actions/setup-node@v4
        with:
          node-version: 22.18.0

      - name: 📥 Monorepo install
        uses: ./.github/actions/pnpm-install
        with:
          filter: '@teable/v2-e2e'

      - name: 🧪 Run E2E tests with coverage (shard ${{ matrix.shard }}/4)
        run: |
          pnpm -C packages/v2/e2e test-unit-cover -- --shard=${{ matrix.shard }}/4 --reporter=json --reporter=default --outputFile=e2e-report-${{ matrix.shard }}.json

      - name: 📊 Upload test report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: e2e-report-shard-${{ matrix.shard }}
          path: packages/v2/e2e/e2e-report-${{ matrix.shard }}.json
          retention-days: 7

      - name: 📈 Upload coverage artifact
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: e2e-coverage-shard-${{ matrix.shard }}
          path: packages/v2/e2e/coverage/
          retention-days: 7

  # Merge coverage from all e2e shards
  e2e-coverage-merge:
    needs: e2e-tests
    runs-on: ubuntu-latest
    name: V2 E2E Coverage Report

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js 22.18.0
        uses: actions/setup-node@v4
        with:
          node-version: 22.18.0

      - name: 📥 Download all coverage artifacts
        uses: actions/download-artifact@v4
        with:
          pattern: e2e-coverage-shard-*
          path: coverage-parts
          merge-multiple: false

      - name: 📥 Install nyc for merging coverage
        run: npm install -g nyc

      - name: 📊 Merge coverage reports
        run: |
          mkdir -p merged-coverage
          # Copy all lcov.info files to merged-coverage with unique names
          for dir in coverage-parts/e2e-coverage-shard-*; do
            shard=$(basename $dir | sed 's/e2e-coverage-shard-//')
            if [ -f "$dir/lcov.info" ]; then
              cp "$dir/lcov.info" "merged-coverage/lcov-$shard.info"
            fi
          done
          # Merge lcov files using lcov command (available on ubuntu)
          sudo apt-get install -y lcov
          lcov -a merged-coverage/lcov-1.info \
               -a merged-coverage/lcov-2.info \
               -a merged-coverage/lcov-3.info \
               -a merged-coverage/lcov-4.info \
               -o merged-coverage/lcov.info || true

      - name: 📈 Upload merged coverage to Coveralls
        if: ${{ hashFiles('merged-coverage/lcov.info') != '' }}
        uses: coverallsapp/github-action@v2
        with:
          file: merged-coverage/lcov.info
          flag-name: v2-e2e
          parallel: false
          allow-empty: true
          fail-on-error: false


================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# and https://github.com/github/gitignore for examples

# local env files (followinf dotenv-flow / nextjs convention)

.env.local
.env.*.local

# security: atlassian/changeset

**/.netrc

# dependencies
node_modules
.pnpm-store/
.pnp.*

# testing
/coverage
.out/

# Debug

**/.debug

# Build directories (next.js...)
/.next/
/out/
/build
/dist/

# v2 packages build output
packages/v2/**/dist/

# Next.js auto-generated type definitions
**/next-env.d.ts

# Cache
*.tsbuildinfo
**/.eslintcache
.cache/*
.swc/
apps/playground/src/routeTree.gen.ts

# Misc
.DS_Store
*.pem
.worktrees/

# Debug
npm-debug.log*
pnpm-debug.log*


# IDE
**/.idea/*
!**/.idea/modules.xml
!**/.idea/*.iml
.project
.classpath
*.launch
*.sublime-workspace

.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Docker overrides

./docker-compose.override.yml

# Deployment platforms

.vercel

# LocalStorage assets

**/.assets


================================================
FILE: .gitpod.yml
================================================
tasks:
  - init: pnpm install
    command: make sqlite-mode && cd apps/nestjs-backend && pnpm dev


================================================
FILE: .husky/commit-msg
================================================
pnpm commitlint --edit $1

================================================
FILE: .husky/install.mjs
================================================
// Skip Husky install in production and CI
if (process.env.NODE_ENV === 'production' || process.env.CI === 'true') {
  process.exit(0);
}
const husky = (await import('husky')).default;
console.log(husky());


================================================
FILE: .husky/pre-commit
================================================
pnpm g:lint-staged-files --debug

================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/packages/common-i18n/.idea/common-i18n.iml" filepath="$PROJECT_DIR$/packages/common-i18n/.idea/common-i18n.iml" />
      <module fileurl="file://$PROJECT_DIR$/packages/core/.idea/core.iml" filepath="$PROJECT_DIR$/packages/core/.idea/core.iml" />
      <module fileurl="file://$PROJECT_DIR$/packages/db-main-prisma/.idea/db-main-prisma.iml" filepath="$PROJECT_DIR$/packages/db-main-prisma/.idea/db-main-prisma.iml" />
      <module fileurl="file://$PROJECT_DIR$/packages/eslint-config-bases/.idea/eslint-config-bases.iml" filepath="$PROJECT_DIR$/packages/eslint-config-bases/.idea/eslint-config-bases.iml" />
      <module fileurl="file://$PROJECT_DIR$/packages/icons/.idea/icons.iml" filepath="$PROJECT_DIR$/packages/icons/.idea/icons.iml" />
      <module fileurl="file://$PROJECT_DIR$/apps/nestjs-backend/.idea/nestjs-backend.iml" filepath="$PROJECT_DIR$/apps/nestjs-backend/.idea/nestjs-backend.iml" />
      <module fileurl="file://$PROJECT_DIR$/apps/nextjs-app/.idea/nextjs-app.iml" filepath="$PROJECT_DIR$/apps/nextjs-app/.idea/nextjs-app.iml" />
      <module fileurl="file://$PROJECT_DIR$/packages/openapi/.idea/openapi.iml" filepath="$PROJECT_DIR$/packages/openapi/.idea/openapi.iml" />
      <module fileurl="file://$PROJECT_DIR$/plugins/.idea/plugins.iml" filepath="$PROJECT_DIR$/plugins/.idea/plugins.iml" />
      <module fileurl="file://$PROJECT_DIR$/packages/sdk/.idea/sdk.iml" filepath="$PROJECT_DIR$/packages/sdk/.idea/sdk.iml" />
      <module fileurl="file://$PROJECT_DIR$/.idea/teable.iml" filepath="$PROJECT_DIR$/.idea/teable.iml" />
      <module fileurl="file://$PROJECT_DIR$/packages/ui-lib/.idea/ui-lib.iml" filepath="$PROJECT_DIR$/packages/ui-lib/.idea/ui-lib.iml" />
    </modules>
  </component>
</project>

================================================
FILE: .idea/teable.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
  <component name="NewModuleRootManager">
    <content url="file://$MODULE_DIR$">
      <excludeFolder url="file://$MODULE_DIR$/.tmp" />
      <excludeFolder url="file://$MODULE_DIR$/temp" />
      <excludeFolder url="file://$MODULE_DIR$/tmp" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="module" module-name="nestjs-backend" />
    <orderEntry type="module" module-name="nextjs-app" />
    <orderEntry type="module" module-name="plugins" />
    <orderEntry type="module" module-name="common-i18n" />
    <orderEntry type="module" module-name="core" />
    <orderEntry type="module" module-name="db-main-prisma" />
    <orderEntry type="module" module-name="eslint-config-bases" />
    <orderEntry type="module" module-name="icons" />
    <orderEntry type="module" module-name="openapi" />
    <orderEntry type="module" module-name="sdk" />
    <orderEntry type="module" module-name="ui-lib" />
  </component>
</module>

================================================
FILE: .ncurc.yml
================================================
# npm-check-updates configuration used by yarn deps:check && yarn deps:update
# convenience scripts.
# @link https://github.com/raineorshine/npm-check-updates

# Add here exclusions on packages if any
reject: [
    'vite-plugin-svgr',

    # Too early cause in esm
    'is-port-reachable',
    'nanoid',
    'node-fetch',
  ]


================================================
FILE: .npmrc
================================================
engine-strict=true
strict-peer-dependencies=false
auto-install-peers=true
lockfile=true
# force use npmjs.org registry
registry=https://registry.npmjs.org/
use-node-version=22.18.0
save-prefix=''


================================================
FILE: .prettierignore
================================================
.idea/
.vscode/
pnpm-lock.yaml
**/.next
**/.out
**/dist
**/build
**/.tmp
**/.cache
apps/playground/src/routeTree.gen.ts


================================================
FILE: .prettierrc.js
================================================
// @ts-check

const { getPrettierConfig } = require('@teable/eslint-config-bases/helpers');

const { overrides = [], ...prettierConfig } = getPrettierConfig();

/**
 * @type {import('prettier').Config}
 */
const config = {
  ...prettierConfig,
  overrides: [
    ...overrides,
    ...[
      {
        files: '*.md',
        options: {
          singleQuote: false,
          quoteProps: 'preserve',
        },
      },
    ],
  ],
};

module.exports = config;


================================================
FILE: .vscode/extensions.json
================================================
{
  "recommendations": ["bradlc.vscode-tailwindcss"]
}


================================================
FILE: .vscode/launch.json
================================================
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "vitest e2e nest backend",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}/apps/nestjs-backend",
      "runtimeExecutable": "sh",
      "autoAttachChildProcesses": true,
      "program": "./node_modules/.bin/vitest",
      "args": [
        "run",
        "${workspaceFolder}/${relativeFile}",
        "--config",
        "./vitest-e2e.config.ts",
        "--hideSkippedTests"
      ],
      "smartStep": true,
      "console": "integratedTerminal",
      "skipFiles": [
        "<node_internals>/**",
        "**/node_modules/**"
      ],
      "internalConsoleOptions": "neverOpen"
    },
    {
      "name": "Debug vitest e2e nest backend",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}/apps/nestjs-backend",
      "runtimeExecutable": "node",
      "program": "${workspaceFolder}/apps/nestjs-backend/node_modules/vitest/vitest.mjs",
      "args": [
        "run",
        "${workspaceFolder}/${relativeFile}",
        "--config",
        "./vitest-e2e.config.ts",
        "--hideSkippedTests",
        "--no-file-parallelism",
        "--reporter",
        "verbose"
      ],
      "autoAttachChildProcesses": true,
      "smartStep": true,
      "console": "integratedTerminal",
      "skipFiles": [
        "<node_internals>/**",
        "**/node_modules/**"
      ],
      "internalConsoleOptions": "neverOpen"
    },
    {
      "name": "vitest nest backend",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}/apps/nestjs-backend",
      "runtimeExecutable": "sh",
      "autoAttachChildProcesses": true,
      "program": "./node_modules/.bin/vitest",
      "args": [
        "run",
        "${workspaceFolder}/${relativeFile}",
        "--config",
        "./vitest.config.ts"
      ],
      "smartStep": true,
      "console": "integratedTerminal",
      "skipFiles": [
        "<node_internals>/**",
        "**/node_modules/**"
      ],
      "internalConsoleOptions": "neverOpen"
    },
    {
      "name": "vitest next app",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}/apps/nextjs-app",
      "runtimeExecutable": "sh",
      "autoAttachChildProcesses": true,
      "program": "./node_modules/.bin/vitest",
      "args": [
        "run",
        "${workspaceFolder}/${relativeFile}",
        "--config",
        "./vitest.config.ts"
      ],
      "smartStep": true,
      "console": "integratedTerminal",
      "skipFiles": [
        "<node_internals>/**",
        "**/node_modules/**"
      ],
      "internalConsoleOptions": "neverOpen"
    },
    {
      "name": "vitest core",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}/packages/core",
      "runtimeExecutable": "sh",
      "autoAttachChildProcesses": true,
      "program": "./node_modules/.bin/vitest",
      "args": [
        "run",
        "${workspaceFolder}/${relativeFile}",
        "--config",
        "./vitest.config.ts"
      ],
      "smartStep": true,
      "console": "integratedTerminal",
      "skipFiles": [
        "<node_internals>/**",
        "**/node_modules/**"
      ],
      "internalConsoleOptions": "neverOpen"
    },
    {
      "name": "vitest sdk",
      "type": "node",
      "request": "launch",
      "cwd": "${workspaceFolder}/packages/sdk",
      "runtimeExecutable": "sh",
      "autoAttachChildProcesses": true,
      "program": "./node_modules/.bin/vitest",
      "args": [
        "run",
        "${workspaceFolder}/${relativeFile}",
        "--config",
        "./vitest.config.ts"
      ],
      "smartStep": true,
      "console": "integratedTerminal",
      "skipFiles": [
        "<node_internals>/**",
        "**/node_modules/**"
      ],
      "internalConsoleOptions": "neverOpen"
    },
    {
      "name": "Debug nest backend",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "pnpm",
      "args": [
        "apps/nestjs-backend/src/index.ts"
      ],
      "runtimeArgs": [
        "start-debug"
      ],
      "outFiles": [
        "${workspaceFolder}/**/*.js",
        "!**/node_modules/**"
      ],
      "cwd": "${workspaceFolder}/apps/nestjs-backend",
      "internalConsoleOptions": "openOnSessionStart",
      "sourceMaps": true,
      "console": "internalConsole",
      "outputCapture": "std"
    },
  ]
}

================================================
FILE: .vscode/settings.json
================================================
{
  "cSpell.words": [
    "antlr",
    "AUTOINCREMENT",
    "COUNTALL",
    "DATETIME",
    "gantt",
    "ILIKE",
    "Localstorage",
    "minio",
    "nextjs",
    "nonstrict",
    "OPENAI",
    "openapi",
    "shadcn",
    "sharedb",
    "signin",
    "signout",
    "sonarjs",
    "sonner",
    "teable",
    "teableio",
    "testid",
    "topo",
    "trgm",
    "umami",
    "univer",
    "zustand"
  ],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "eslint.format.enable": true,
  "eslint.alwaysShowStatus": true,
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "[javascript]": {
    "editor.formatOnSave": false
  },
  "[javascriptreact]": {
    "editor.formatOnSave": false
  },
  "[typescript]": {
    "editor.formatOnSave": false
  },
  "[typescriptreact]": {
    "editor.formatOnSave": false
  },
  "eslint.workingDirectories": [
    {
      "pattern": "./apps/*/"
    },
    {
      "pattern": "./packages/*/"
    },
    {
      "pattern": "./packages/v2/*/"
    }
  ],
  "vitest.maximumConfigs": 50,
  "vitest.nodeEnv": {
    "DOCKER_HOST": "unix:///Users/nichenqin/.colima/default/docker.sock",
    "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE": "/var/run/docker.sock",
    "TESTCONTAINERS_HOST_OVERRIDE": "127.0.0.1"
  }
}

================================================
FILE: AGPL_LICENSE
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.

Additional Terms under GNU Affero General Public License Version 3 (AGPLv3)

In accordance with Section 7 of the GNU Affero General Public License Version 3,
the following additional terms apply to this software:

Brand Protection (Under Section 7(e)):

The Teable brand assets (including but not limited to the Teable name, logo,
icons, and visual identity elements) are protected intellectual property and
are not covered by the AGPLv3 license. While the software code may be modified
under the terms of AGPL, any modification, replacement, or removal of these
brand assets is explicitly prohibited.

Specifically:
1. You may not modify or replace the Teable brand assets
2. You may not remove the Teable brand assets
3. You may not use the brand assets in a way that suggests endorsement


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
support (at) teable.ai.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].

Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].

For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].

[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

The base branch is **`develop`**.

## Development Setup

> **Note**
> The following commands are for Linux/Mac environments. For Windows, please use WSL2.

### 1. Initial Setup

```bash
# Enable the Package Manager
corepack enable

# Install project dependencies
pnpm install
```

### 2. Database Selection
We support SQLite (dev only) and PostgreSQL. PostgreSQL is recommended and requires Docker installed.

```bash
# Switch between SQLite and PostgreSQL
make switch-db-mode
```

### 3. Environment Configuration (Optional)
```bash
cd apps/nextjs-app
cp .env.development .env.development.local
```

### 4. Start Development Server
```bash
cd apps/nestjs-backend
pnpm dev
```
This will automatically start both backend and frontend servers with hot reload enabled.

## Continuous Development

After pulling the latest code, ensure your development environment stays up-to-date:

```bash
# Update dependencies to latest versions
pnpm install

# Update database schema to latest version
make switch-db-mode
```

### Known Issues

Port conflict: In dev mode, code changes trigger hot reloading. If changes affect app/nestjs-backend (packages/core, packages/db-main-prisma), nodejs may restart, potentially causing port conflicts.
If backend code changes seem ineffective, check if the port is occupied with `lsof -i:3000`. If so, kill the old process with `kill -9 [pid]` and restart the application with `pnpm dev`.

Websocket: In development, Next.js occupies port 3000 for websocket to trigger hot reloading. To avoid conflicts, the application's websocket uses port 3001. That's why you see SOCKET_PORT=3001 in .env.development.local, while in production, port 3000 is used by default for websocket requests.

## Database Migration Workflow

Teable uses Prisma as ORM for database management. Follow these steps for schema changes:

1. Modify `packages/db-main-prisma/prisma/template.prisma`

2. Generate Prisma schemas:
```bash
make gen-prisma-schema
```
This generates both SQLite and PostgreSQL schemas and TypeScript definitions.

3. Create migrations file:
```bash
make db-migration
```

4. Apply migrations:
```bash
make switch-db-mode
```

> **Note**
> If you need to modify the schema after applying migrations, you need to delete the latest migration file and run `pnpm prisma-migrate-reset` in `packages/db-main-prisma` to reset the database. (Make sure you run it in the development database.)

## Testing

### E2E Tests
Located in `apps/nestjs-backend`:

```bash
# First-time setup
pnpm pre-test-e2e

# Run all E2E tests
pnpm test-e2e

# Run specific test file
pnpm test-e2e [test-file]
```

### Unit Tests
```bash
# Run all unit tests
pnpm g:test-unit

# Run tests in specific package
cd packages/[package-name]
pnpm test-unit

# Run specific test file
pnpm test-unit [test-file]
```

### IDE Integration
Using VSCode/Cursor:
1. For E2E tests in `apps/nestjs-backend`:
   - Switch to test file (e.g. `apps/nestjs-backend/test/record.e2e-spec.ts`)
   - Select "vitest e2e nest backend" in Debug panel

2. For unit tests in different packages:
   - For `packages/core`: 
     - Switch to test file (e.g. `packages/core/src/utils/date.spec.ts`)
     - Select "vitest core" in Debug panel
   - For other packages, select their corresponding debug configuration

Each package has its own debug configuration in VSCode/Cursor, make sure to select the matching one for the package you're testing.

## Git Commit Convention

This repo follows [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) format.

### Common Prefixes
- **feat**: New feature
- **fix**: Bug fix
- **docs**: Documentation changes
- **test**: Adding or modifying tests
- **refactor**: Code changes that neither fix bugs nor add features
- **style**: Changes to styling/CSS
- **chore**: Changes to build process or tools

> **Note**
> Full configuration can be found in [commitlint.config.js](https://github.com/teableio/teable/blob/main/commitlint.config.js)

## Docker Build

### Building Images Locally
- `teable`: The main application image

#### Build the Application Image
> **Note**
> You should run this command in the root directory.

```bash
# Build the main application image
docker build -f dockers/teable/Dockerfile -t teable:latest .

# Build for a specific platform (e.g., amd64)
docker build --platform linux/amd64 -f dockers/teable/Dockerfile -t teable:latest .
```

### Pushing to Docker Hub

```bash
# Tag your local image
docker tag teable:latest your-username/teable:latest

# Login to Docker Hub
docker login

# Push the image
docker push your-username/teable:latest
```


================================================
FILE: LICENSE
================================================
Copyright (c) 2023-2025 Teable, Inc.

Teable Project Licensing

This project is a combination of components under different licenses to balance open source principles with the ability to provide commercial services:

1. Core Applications:
   - apps/nestjs-backend
   - apps/nextjs-app
   These core applications are licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).
   The full text of this license can be found at ./AGPL_LICENSE

2. SDK and Utility Packages:
   All packages under the 'packages' directory are licensed under the MIT License.
   For the full text of the MIT License, please see the individual LICENSE files in each package directory.

As a whole, this project is primarily under the AGPL-3.0 license, with the exception of the packages in the 'packages' directory, which are available under the more permissive MIT License to facilitate wider adoption and integration.

For any questions regarding licensing, please contact support@teable.ai

Additional Terms under GNU Affero General Public License Version 3 (AGPLv3)

In accordance with Section 7 of the GNU Affero General Public License Version 3,
the following additional terms apply to this software:

Brand Protection (Under Section 7(e)):

The Teable brand assets (including but not limited to the Teable name, logo,
icons, and visual identity elements) are protected intellectual property and
are not covered by the AGPLv3 license. While the software code may be modified
under the terms of AGPL, any modification, replacement, or removal of these
brand assets is explicitly prohibited.

Specifically:
1. You may not modify or replace the Teable brand assets
2. You may not remove the Teable brand assets
3. You may not use the brand assets in a way that suggests endorsement


================================================
FILE: Makefile
================================================
SHELL := /usr/bin/env bash

# define standard colors
ifneq (,$(findstring xterm,${TERM}))
	BLACK        := $(shell tput -Txterm setaf 0)
	RED          := $(shell tput -Txterm setaf 1)
	GREEN        := $(shell tput -Txterm setaf 2)
	YELLOW       := $(shell tput -Txterm setaf 3)
	LIGHTPURPLE  := $(shell tput -Txterm setaf 4)
	PURPLE       := $(shell tput -Txterm setaf 5)
	BLUE         := $(shell tput -Txterm setaf 6)
	WHITE        := $(shell tput -Txterm setaf 7)
	RESET := $(shell tput -Txterm sgr0)
else
	BLACK        := ""
	RED          := ""
	GREEN        := ""
	YELLOW       := ""
	LIGHTPURPLE  := ""
	PURPLE       := ""
	BLUE         := ""
	WHITE        := ""
	RESET        := ""
endif

ENV_PATH ?= ./apps/nextjs-app

DOCKER_COMPOSE ?= docker compose

DOCKER_COMPOSE_ENV_FILE := $(wildcard ./dockers/.env)
COMPOSE_FILES := $(wildcard ./dockers/*.yml)
COMPOSE_FILE_ARGS := --env-file $(DOCKER_COMPOSE_ENV_FILE) $(foreach yml,$(COMPOSE_FILES),-f $(yml))

NETWORK_MODE ?= teablenet
CI_JOB_ID ?= 0
CI ?= 0

# Timeout used to await services to become healthy
TIMEOUT ?= 300

SCRATCH ?= /tmp

UNAME_S := $(shell uname -s)

# prisma database url defaults
SQLITE_PRISMA_DATABASE_URL ?= file:../../db/main.db
# set param statement_cache_size=1 to avoid query error `ERROR: cached plan must not change result type` after alter column type (modify field type)
POSTGES_PRISMA_DATABASE_URL ?= postgresql://teable:teable\@127.0.0.1:5432/teable?schema=public\&statement_cache_size=1

# If the first make argument is "start", "stop"...
ifeq (docker.start,$(firstword $(MAKECMDGOALS)))
    SERVICE_TARGET = true
else ifeq (docker.stop,$(firstword $(MAKECMDGOALS)))
    SERVICE_TARGET = true
else ifeq (docker.restart,$(firstword $(MAKECMDGOALS)))
    SERVICE_TARGET = true
else ifeq (docker.up,$(firstword $(MAKECMDGOALS)))
    SERVICE_TARGET = true
else ifeq (docker.await,$(firstword $(MAKECMDGOALS)))
    SERVICE_TARGET = true
else ifeq (docker.run,$(firstword $(MAKECMDGOALS)))
    RUN_TARGET = true
else ifeq (docker.integration,$(firstword $(MAKECMDGOALS)))
    INTEGRATION_TARGET = true
endif

ifdef SERVICE_TARGET
    # .. then use the rest as arguments for the make target
    SERVICE := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
    # ...and turn them into do-nothing targets
    $(eval $(SERVICE):;@:)
else ifdef RUN_TARGET
    # Isolate second argument as service, the rest is arguments for run command
    SERVICE := $(wordlist 2, 2, $(MAKECMDGOALS))
    SERVICE_ARGS := $(wordlist 3, $(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
else ifdef INTEGRATION_TARGET
    # Isolate second argument as integration module, the rest as arguments
    INTEGRATION_MODULE := $(wordlist 2, 2, $(MAKECMDGOALS))
     $(eval $(INTEGRATION_MODULE):;@:)
    INTEGRATION_ARGS := $(wordlist 3, $(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
    $(eval $(INTEGRATION_ARGS):;@:)
endif

#
# Never use the network=host mode when running CI jobs, and add extra
# distinguishing identifiers to the network name and container names to
# prevent collisions with jobs from the same project running at the same
# time.
#
ifneq ($(CI_JOB_ID),)
    NETWORK_MODE := teablenet-$(CI_JOB_ID)
endif

ifeq ($(CI),0)
    export NODE_ENV = development
endif


ifeq ($(UNAME_S),Linux)
	DOCKER_GID ?= $(shell getent group docker | cut -d: -f 3)
else ifeq ($(UNAME_S),Darwin)
	DOCKER_GID ?= $(shell id -g)
else
    $(error Sorry, '${UNAME_S}' is not supported yet)
endif


DOCKER_COMPOSE_ARGS := DOCKER_UID=$(shell id -u) \
	DOCKER_GID=$(DOCKER_GID) \
    NETWORK_MODE=$(NETWORK_MODE)


define print_db_mode_options
@echo -e "\nSelect a database to start.\n"
@echo -e "1)sqlite			Lightweight embedded, ideal for mobile and embedded systems, simple, resource-efficient, easy integration (default database)"
@echo -e "2)postges(pg)			Powerful and scalable, suitable for complex enterprise needs, highly customizable, rich community support\n"
endef

define print_db_push_options
@echo -e "The 'db pull' command connects to your database and adds Prisma models to your Prisma schema that reflect the current database schema.\n"
@echo -e "1) sqlite"
@echo -e "2) postges(pg)\n"
endef

.PHONY: db-mode sqlite.mode postgres.mode gen-prisma-schema gen-sqlite-prisma-schema gen-postgres-prisma-schema
.DEFAULT_GOAL := help

docker.create.network:
ifneq ($(NETWORK_MODE),host)
	@docker network inspect $(NETWORK_MODE) &> /dev/null || ([ $$? -ne 0 ] && docker network create $(NETWORK_MODE))
	$(info ${GREEN}network $(NETWORK_MODE) create success${RESET})
endif

docker.rm.network:
ifneq ($(NETWORK_MODE),host)
	@docker network inspect $(NETWORK_MODE) &> /dev/null && ([ $$? -eq 0 ] && docker network rm $(NETWORK_MODE)) || true
	$(warning ${GREEN}network $(NETWORK_MODE) removed${RESET})
endif


docker.run: docker.create.network
	$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) run -T --no-deps --rm $(SERVICE) $(SERVICE_ARGS)

docker.up: docker.create.network
	@$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) up --no-recreate -d $(SERVICE)

docker.down: docker.rm.network
	$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) down

docker.start:
	$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) start $(SERVICE)

docker.stop:
	$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) stop $(SERVICE)

docker.restart:
	make docker.stop $(SERVICE)
	make docker.start $(SERVICE)

TIME := 0
docker.await: ## max timeout of 300
	@time=$(TIME); \
	for i in $(SERVICE); do \
		current_service=$$($(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) ps -q $${i}); \
		if [ -z "$${current_service}" ]; then \
			continue; \
		fi; \
		service_has_health=$$(docker inspect -f '{{.State.Health.Status}}' $${current_service}); \
		if [ -z "$${service_has_health}" ]; then \
			continue; \
		fi; \
		while [ "$$(docker inspect -f '{{.State.Health.Status}}' $${current_service})" != "healthy" ] ; do \
			sleep 1; \
			time=$$(expr $$time + 1); \
			if [ $${time} -gt $(TIMEOUT) ]; then \
				echo "${YELLOW}Timeout reached waiting for $${i} to become healthy${RESET}"; \
				docker logs $${i}; \
				exit 1; \
			fi; \
		done; \
		echo "${GREEN}Service $${i} is healthy${RESET}"; \
	done

docker.status:
	$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) ps

docker.images:
	$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) images


build.app:
	@zx --version || pnpm add -g zx; \
  	zx scripts/build-image.mjs --file=dockers/teable/Dockerfile \
		  --tag=teable:develop

build.db-migrate:
	@zx --version || pnpm add -g zx; \
  	zx scripts/build-image.mjs --file=dockers/teable/Dockerfile.db-migrate \
		  --tag=teable-db-migrate:develop


sqlite.integration.test:
	@export PRISMA_DATABASE_URL='file:../../db/main.db'; \
	export CALC_CHUNK_SIZE=400; \
	make sqlite.mode; \
	pnpm -F "./packages/**" run build; \
	pnpm g:test-e2e-cover

postgres.integration.test: docker.create.network
	@TEST_PG_CONTAINER_NAME=teable-postgres-$(CI_JOB_ID); \
	docker rm -fv $$TEST_PG_CONTAINER_NAME | true; \
	$(DOCKER_COMPOSE_ARGS) $(DOCKER_COMPOSE) $(COMPOSE_FILE_ARGS) run -p 25432:5432 -d -T --no-deps --rm --name $$TEST_PG_CONTAINER_NAME teable-postgres; \
	chmod +x scripts/wait-for; \
	scripts/wait-for 127.0.0.1:25432 --timeout=15 -- echo 'pg database started successfully' && \
		export PRISMA_DATABASE_URL=postgresql://teable:teable@127.0.0.1:25432/e2e_test_teable?schema=public\&statement_cache_size=1\&connection_limit=20 && \
		make postgres.mode && \
		pnpm -F "./packages/**" run build && \
		pnpm g:test-e2e-cover && \
		docker rm -fv $$TEST_PG_CONTAINER_NAME

gen-sqlite-prisma-schema:
	@cd ./packages/db-main-prisma; \
		echo '{ "PRISMA_PROVIDER": "sqlite" }' | pnpm mustache - ./prisma/template.prisma > ./prisma/sqlite/schema.prisma
	@echo 'generate【 prisma/sqlite/schema.prisma 】success.'

gen-postgres-prisma-schema:
	@cd ./packages/db-main-prisma; \
		echo '{ "PRISMA_PROVIDER": "postgres" }' | pnpm mustache - ./prisma/template.prisma > ./prisma/postgres/schema.prisma
	@echo 'generate【 prisma/postgres/schema.prisma 】success.'

gen-prisma-schema: gen-sqlite-prisma-schema gen-postgres-prisma-schema		## Generate 'schema.prisma' files for all versions of the system

sqlite-db.push:		## db.push by sqlite
	@cd ./packages/db-main-prisma; \
		pnpm prisma-db-push --schema ./prisma/sqlite/schema.prisma

postgres-db.push:		## db.push by postgres
	@cd ./packages/db-main-prisma; \
		pnpm prisma-db-push --schema ./prisma/postgres/schema.prisma

db.push:		## connects to your database and adds Prisma models to your Prisma schema that reflect the current database schema.
	$(print_db_push_options)
	@read -p "Enter a command: " command; \
    if [ "$$command" = "1" ] || [ "$$command" = "sqlite" ]; then \
      make gen-sqlite-prisma-schema; \
      make sqlite-db.push; \
    elif [ "$$command" = "2" ] || [ "$$command" = "postges" ] || [ "$$command" = "pg" ]; then \
      	make gen-postgres-prisma-schema; \
		make postgres-db.push; \
    else echo "Unknown command.";  fi

sqlite-db-migration:
	@_MIGRATION_NAME=$(if $(_MIGRATION_NAME),$(_MIGRATION_NAME),`read -p "Enter name of the migration (sqlite): " migration_name; echo $$migration_name`); \
	make gen-sqlite-prisma-schema; \
	PRISMA_DATABASE_URL=file:../../db/.shadow/main.db \
	pnpm -F @teable/db-main-prisma prisma-migrate dev --schema ./prisma/sqlite/schema.prisma --name $$_MIGRATION_NAME

postgres-db-migration:
	@_MIGRATION_NAME=$(if $(_MIGRATION_NAME),$(_MIGRATION_NAME),`read -p "Enter name of the migration (postgres): " migration_name; echo $$migration_name`); \
	make gen-postgres-prisma-schema; \
	PRISMA_DATABASE_URL=postgresql://teable:teable@127.0.0.1:5432/teable?schema=shadow \
	pnpm -F @teable/db-main-prisma prisma-migrate dev --schema ./prisma/postgres/schema.prisma --name $$_MIGRATION_NAME

db-migration:		## Reruns the existing migration history in the shadow database in order to detect schema drift (edited or deleted migration file, or a manual changes to the database schema)
	@read -p "Enter name of the migration: " migration_name; \
  	make sqlite-db-migration _MIGRATION_NAME=$$migration_name; \
  	make postgres-db-migration _MIGRATION_NAME=$$migration_name

sqlite.mode:		## sqlite.mode
	@cd ./packages/db-main-prisma; \
		pnpm prisma-generate --schema ./prisma/sqlite/schema.prisma; \
		pnpm prisma-migrate deploy --schema ./prisma/sqlite/schema.prisma

postgres.mode:		## postgres.mode
	@cd ./packages/db-main-prisma; \
		pnpm prisma-generate --schema ./prisma/postgres/schema.prisma; \
		pnpm prisma-migrate deploy --schema ./prisma/postgres/schema.prisma
# Override environment variable files based on variables
RUN_DB_MODE ?= sqlite
FILE_ENV_PATHS = $(ENV_PATH)/.env.development* $(ENV_PATH)/.env.test*
switch.prisma.env:
ifeq ($(CI)-$(RUN_DB_MODE),0-sqlite)
	@for file in $(FILE_ENV_PATHS); do \
		echo $$file; \
		perl -i -pe 's~^PRISMA_DATABASE_URL=.*~PRISMA_DATABASE_URL=$(SQLITE_PRISMA_DATABASE_URL)~' $$file; \
		if ! grep -q '^CALC_CHUNK_SIZE=' $$file; then \
			echo "CALC_CHUNK_SIZE=400" >> $$file; \
		else \
			perl -i -pe 's~^CALC_CHUNK_SIZE=.*~CALC_CHUNK_SIZE=400~' $$file; \
		fi; \
	done
else ifeq ($(CI)-$(RUN_DB_MODE),0-postges)
	@for file in $(FILE_ENV_PATHS); do \
		echo $$file; \
		perl -i -pe 's~^PRISMA_DATABASE_URL=.*~PRISMA_DATABASE_URL=$(POSTGES_PRISMA_DATABASE_URL)~' $$file; \
	done
endif

switch-db-mode:		## Switch Database environment
	$(print_db_mode_options)
	@read -p "Enter a command: " command; \
    if [ "$$command" = "1" ] || [ "$$command" = "sqlite" ]; then \
		make switch.prisma.env RUN_DB_MODE=sqlite; \
      	make sqlite.mode; \
    elif [ "$$command" = "2" ] || [ "$$command" = "postges" ] || [ "$$command" = "pg" ]; then \
      	make switch.prisma.env RUN_DB_MODE=postges; \
		make docker.up teable-postgres; \
    	make docker.await teable-postgres; \
    	make postgres.mode; \
    else \
      	echo "Unknown command.";  fi

help:   ## show this help
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'


================================================
FILE: README.md
================================================
<div align="center">
  <h1 align="center">
    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="static/assets/images/teable-vertical-dark.png">
      <img alt="teable logo" height="150" src="static/assets/images/teable-vertical-light.png">
    </picture>
  </h1>
  <h3 align="center"><strong>Manage Your Data & Connect Your Team</strong></h3>
  <p>Teable uses a simple, spreadsheet-like interface to create powerful database applications. Collaborate with your team in real-time, and scale to millions of rows
  <p>Try out Teable using our hosted version at <a href="https://teable.ai">teable.ai</a></p>
</div>

<div align="center">
<a href="https://trendshift.io/repositories/8516" target="_blank"><img src="https://trendshift.io/api/badge/repositories/8516" alt="teableio%2Fteable | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>

<p align="center">
  <a target="_blank" href="https://teable.ai">Home</a> | <a target="_blank" href="https://help.teable.ai">Help</a> | <a target="_blank" href="https://teable.ai/blog">Blog</a> | <a target="_blank" href="https://teable.ai/templates">Template</a> | <a target="_blank" href="https://help.teable.ai/en/api-doc/token">API</a> | <a target="_blank" href="https://community.teable.ai">Community</a> | <a target="_blank" href="https://twitter.com/teableio">Twitter</a>
</p>

<p align="center">
  <a aria-label="Build" href="https://github.com/teableio/teable/actions?query=Build%20and%20Push%20to%20Docker%20Registry">
    <img alt="build" src="https://img.shields.io/github/actions/workflow/status/teableio/teable/docker-push.yml?label=Build&logo=github&style=flat-quare&labelColor=000000" />
  </a>
  <a aria-label="Coverage Status" href="https://coveralls.io/github/teableio/teable?branch=develop">
    <img alt="Coverage" src="https://coveralls.io/repos/github/teableio/teable/badge.svg?branch=develop" />
  </a>
  <a aria-label="Codacy grade" href="https://www.codacy.com/gh/teableio/teable/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=teableio/teable&amp;utm_campaign=Badge_Grade">
    <img alt="Codacy grade" src="https://img.shields.io/codacy/grade/dff9c944af284a0fad4e165eb1727467?logo=codacy&style=flat-square&labelColor=000&label=Codacy">
  </a>
  <a aria-label="Top language" href="https://github.com/teableio/teable/search?l=typescript">
    <img alt="GitHub top language" src="https://img.shields.io/github/languages/top/teableio/teable?style=flat-square&labelColor=000&color=blue">
  </a>
  <a aria-label="Gurubase" href="https://gurubase.io/g/teable">
    <img alt="Gurubase" src="https://img.shields.io/badge/Gurubase-Ask%20Teable%20Guru-006BFF" />
  </a>
</p>
  <h1 align="center">
    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="static/assets/images/teable-interface-dark.png">
      <img alt="teable interface" width="100%" src="static/assets/images/teable-interface-light.png">
    </picture>
  </h1>

## Quick Guide

1. Looking for a quick experience? Select a scenario from the [template center](https://app.teable.ai/public/template) and click "Use this template".
2. Seeking high performance? Try the [1 million rows demo](https://app.teable.ai/share/shrVgdLiOvNQABtW0yX/view) to feel the speed of Teable.
3. Interested in deploying it yourself? Click [Deploy on Railway](https://railway.app/template/wada5e?referralCode=rE4BjB)

## ✨Features

### 🍺 Feature Packed

Everything you need, right out of the box:

- [x] Aggregation
- [x] Attachments Preview
- [x] Batch Editing
- [x] Charts
- [x] Comments
- [x] Custom Columns
- [x] Field Conversion
- [x] Filtering
- [x] Formatting
- [x] Formula Support
- [x] Grouping
- [x] History
- [x] Import/Export
- [x] Millions of Rows
- [x] Plugins
- [x] Real-time
- [x] Search
- [x] Sorting
- [x] SQL Query
- [x] Undo/Redo
- [x] Validation

### 🏞️ Multiple Views

Visualize and interact with data in various ways best suited for their specific tasks.

- [x] Grid View
- [x] Form View
- [x] Kanban View
- [x] Gallery View
- [x] Calendar View

<table align="center" style="width: 100%;">
  <tr>
    <td width="50%"><img alt="Grid View" src="static/assets/images/view-grid.png"></td>
    <td width="50%"><img alt="Search" src="static/assets/images/search.png"></td>
  </tr>
  <tr>
    <td width="50%"><img alt="Calendar View" src="static/assets/images/view-calendar.png"></td>
    <td width="50%"><img alt="Gallery View" src="static/assets/images/view-gallery.png"></td>
  </tr>
  <tr>
    <td width="50%"><img alt="Kanban View" src="static/assets/images/view-kanban.png"></td>
    <td width="50%"><img alt="Form View" src="static/assets/images/view-form.png"></td>
  </tr>
  <tr>
    <td width="50%"><img alt="Comments" src="static/assets/images/comments.png"></td>
    <td width="50%"><img alt="Record history" src="static/assets/images/record-history.png"></td>
  </tr>
</table>

More features have been added. See our <a target="_blank" href="https://help.teable.ai/en/changelog">Changelog</a>.

---

# Structure

[![Open in Gitpod](https://img.shields.io/badge/Open%20In-Gitpod.io-%231966D2?style=for-the-badge&logo=gitpod)](https://gitpod.io/#https://github.com/teableio/teable)

```
.
├── apps (AGPL 3.0)
│   ├── nextjs-app          (front-end)
│   └── nestjs-backend      (backend)
├── packages (MIT)
│   ├── common-i18n         (locales)
│   ├── core                (share code and interface)
│   ├── sdk                 (sdk for extensions)
│   ├── db-main-prisma      (schema, migrations, prisma client)
│   ├── eslint-config-bases (to shared eslint configs)
│   └── ui-lib              (ui component)
└── plugins (AGPL 3.0)      (custom plugins)

```

## Deploy

### Deploy With Docker

```sh
cd dockers/examples/standalone/
docker-compose up -d
```

for more details, see [install teable](https://help.teable.ai/en/deploy/docker)

### One Click Deployment

These platforms are easy to deploy with one click and come with free credits.

[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/template/wada5e?referralCode=rE4BjB)

[![Deploy on Sealos](https://sealos.io/Deploy-on-Sealos.svg)](https://template.sealos.io/deploy?templateName=teable)

[![Deploy on Zeabur](https://zeabur.com/button.svg)](https://zeabur.com/templates/QF8695)

[![Deploy to RepoCloud](https://d16t0pc4846x52.cloudfront.net/deploylobe.svg)](https://repocloud.io/details/?app_id=273)

[![Deploy on Elestio](https://elest.io/images/logos/deploy-to-elestio-btn.png)](https://elest.io/open-source/teable)

[![Deploy on AlibabaCloud ComputeNest](https://service-info-public.oss-cn-hangzhou.aliyuncs.com/computenest-en.svg)](https://computenest.console.aliyun.com/service/instance/create/default?ServiceName=Teable%20%E7%A4%BE%E5%8C%BA%E7%89%88)


## Development

#### 1. Initialize

```sh
# Enabling the Help Management Package Manager
corepack enable

# Install project dependencies
pnpm install
```

#### 2. Select Database

we currently support `sqlite` (dev only) and `postgres`, you can switch between them by running the following command

```sh
make switch-db-mode
```

#### 3. Custom Environment Variables(Optional)

```sh
cd apps/nextjs-app
cp .env.development .env.development.local
```

#### 4. Run Dev Server

you just need to start backend, it will start next server for frontend automatically, file change will be auto reload

```sh
cd apps/nestjs-backend
pnpm dev
```

By default, the plugin development server is not started. To preview and develop plugins, run:
```sh
# build packages
pnpm build:packages

# start plugin development server
cd plugins
pnpm dev
```
This will start the plugin development server on port 3002.


## Why Teable?

No-code tools have significantly speed up how we get things done, allowing non-tech users to build amazing apps and changing the way many work and live. People like using spreadsheet-like UI to handle their data because it's easy, flexible, and great for team collaboration. They also prefer designing their app screens without being stuck with clunky templates.

Giving non-techy people the ability to create their software sounds exciting. But that's just the start:

- As businesses expand, their data needs intensify. No one wishes to hear that once their orders reach 100k, they'll outgrow their current interface. Yet, many no-code platforms falter at such scales.
- Most no-code platforms are cloud-based. This means your important data sits with the provider, and switching to another platform can be a headache.
- Sometimes, no-code tools can't do what you want because of their limitations, leaving users stuck.
- If a tool becomes essential, you'll eventually need some tech expertise. But developers often find these platforms tricky.
- Maintaining systems with complex setups can be hard for developers, especially if these aren't built using common software standards.
- Systems that don't use these standards might need revamping or replacing, costing more in the long run. It might even mean ditching the no-code route and going back to traditional coding.

#### What We Think the Future Of No-code Products Look Like

- An interface that anyone can use to build applications easily.
- Easy access to data, letting users grab, move, and reuse their information as they wish.
- Data privacy and choice, whether that's in the cloud, on-premise, or even just on your local.
- It needs to work for developers too, not just non-tech users.
- It should handle lots of data, so it can grow with your business.
- Flexibility to integrate with other software, combining strengths to get the job done.
- Last, native AI integration to takes usability to the next level.

In essence, Teable isn't just another no-code solution, it's a comprehensive answer to the evolving demands of modern software development, ensuring that everyone, regardless of their technical proficiency, has a platform tailored to their needs.

# License

Teable Community Edition (CE) is free for self-hosting under the AGPL license. See [./LICENSE](./LICENSE) for details.

Teable Enterprise Edition (EE) includes advanced features such as AI, authority matrix, automation and advanced admin. For detailed information and pricing, please visit [pricing](https://app.teable.ai/public/pricing?host=self-hosted&billing=year).


================================================
FILE: agents.md
================================================
# Teable v2 agent guide

DDD/domain-model guidance has moved to the skill `teable-ddd-domain-model` in `.codex/skills/teable-ddd-domain-model`. Use that skill for any v2/core domain, specification, or aggregate changes.

## Git hygiene

- Ignore git changes that you did not make by default; never revert unknown/unrelated modifications unless explicitly instructed.

## v2 API contracts (HTTP)

For HTTP-ish integrations, keep framework-independent contracts/mappers in `packages/v2/contract-http`:

- Define API paths (e.g. `/tables`) as constants.
- Use action-style paths with camelCase action names (e.g. `/tables/create`, `/tables/get`, `/tables/rename`); avoid RESTful nested resources like `/bases/{baseId}/tables/{tableId}`.
- Re-export command input schemas (zod) for route-level validation if needed.
- Keep DTO types + domain-to-DTO mappers here.
- Router packages (e.g. `@teable/v2-contract-http-express`, `@teable/v2-contract-http-fastify`) should be thin adapters that only:
  - parse JSON/body
  - create a container
  - resolve handlers
  - call the endpoint executor/mappers from `@teable/v2-contract-http`
- OpenAPI is generated from the ts-rest contract via `@teable/v2-contract-http-openapi`.

## UI components (frontend)

- In app UIs (e.g. `apps/playground`), use shadcn wrappers from `apps/playground/src/components/ui/*` (or `@teable/ui-lib`) instead of importing Radix primitives directly.
- If a shadcn wrapper is missing, add it under `apps/playground/src/components/ui` before using the primitive.

## Dependency injection (DI)

- Do not import `tsyringe` / `reflect-metadata` directly anywhere; use `@teable/v2-di`.
- Do not use DI inside `v2/core/src/domain/**`; DI is only for application wiring (e.g. `v2/core/src/commands/**`).
- Prefer constructor injection with explicit tokens for ports (interfaces).
- Provide environment-level composition roots as separate packages (e.g. `@teable/v2-container-node`, `@teable/v2-container-browser`) that register all port implementations.

## Build tooling (v2)

- v2 packages build with `tsdown` (not `tsc` emit). `tsc` is used only for `typecheck` (`--noEmit`).
- Each v2 package has a local `tsdown.config.ts` that extends the shared base config from `@teable/v2-tsdown-config`.
- Outputs are written to `dist/` (ESM `.js` + `.d.ts`), and workspace deps (`@teable/v2-*`) are kept external (no bundling across packages).

## Source visibility (v2 packages)

**All v2 packages must support source visibility** to allow consumers to reference TypeScript sources without building `dist/` outputs. This is required for development workflows, testing, and tools like Vitest/Vite that can consume TypeScript directly.

**Required configuration:**

- In `package.json`:
  - Set `types` field to `"src/index.ts"` (not `"dist/index.d.ts"`)
  - Set `exports["."].types` to `"./src/index.ts"` (not `"./dist/index.d.ts"`)
  - Set `exports["."].import` to `"./src/index.ts"` (not `"./dist/index.js"`) to allow Vite/Vitest to use source files directly
  - Keep `exports["."].require` pointing to `"./dist/index.cjs"` for CommonJS compatibility
  - Include `"src"` in the `files` array (in addition to `"dist"`)
- In `tsconfig.json`:
  - Map workspace dependencies to their `src` paths in `compilerOptions.paths` (e.g. `"@teable/v2-core": ["../core/src"]`)
  - Include those source paths in the `include` array

**Example `package.json` configuration:**
```json
{
  "types": "src/index.ts",
  "exports": {
    ".": {
      "types": "./src/index.ts",
      "import": "./src/index.ts",
      "require": "./dist/index.cjs"
    }
  },
  "files": ["dist", "src"]
}
```

**Note:** Since v2 packages are workspace-only (`"private": true`) and not published to npm, pointing `import` to source files is safe. Vite/Vitest can process TypeScript files directly, enabling faster development cycles without requiring `dist/` to be built first.


================================================
FILE: apps/nestjs-backend/.eslintrc.js
================================================
/**
 * Specific eslint rules for this app/package, extends the base rules
 * @see https://github.com/teableio/teable/blob/main/docs/about-linters.md
 */

// Workaround for https://github.com/eslint/eslint/issues/3458 (re-export of @rushstack/eslint-patch)
require('@teable/eslint-config-bases/patch/modern-module-resolution');

const { getDefaultIgnorePatterns } = require('@teable/eslint-config-bases/helpers');

module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  parserOptions: {
    tsconfigRootDir: __dirname,
    project: 'tsconfig.eslint.json',
  },
  ignorePatterns: [...getDefaultIgnorePatterns()],
  extends: [
    '@teable/eslint-config-bases/typescript',
    '@teable/eslint-config-bases/sonar',
    '@teable/eslint-config-bases/regexp',
    '@teable/eslint-config-bases/jest',
    // Apply prettier and disable incompatible rules
    '@teable/eslint-config-bases/prettier-plugin',
  ],
  rules: {
    // optional overrides per project
  },
  overrides: [
    {
      files: ['src/event-emitter/events/**/*.event.ts'],
      rules: {
        '@typescript-eslint/naming-convention': 'off',
      },
    },
    {
      // Disable consistent-type-imports for files with decorators (NestJS controllers/services)
      // See: https://typescript-eslint.io/blog/changes-to-consistent-type-imports-with-decorators
      files: ['src/**/*.controller.ts'],
      rules: {
        '@typescript-eslint/consistent-type-imports': 'off',
      },
    },
  ],
};


================================================
FILE: apps/nestjs-backend/.gitignore
================================================
# build
build
dist

# testing
/coverage

# misc
.DS_Store
*.pem
.assets
.temporary
.webpack-cache


================================================
FILE: apps/nestjs-backend/.idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/.idea/nestjs-backend.iml" filepath="$PROJECT_DIR$/.idea/nestjs-backend.iml" />
    </modules>
  </component>
</project>

================================================
FILE: apps/nestjs-backend/.idea/nestjs-backend.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
  <component name="NewModuleRootManager">
    <content url="file://$MODULE_DIR$">
      <excludeFolder url="file://$MODULE_DIR$/.tmp" />
      <excludeFolder url="file://$MODULE_DIR$/temp" />
      <excludeFolder url="file://$MODULE_DIR$/tmp" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
  </component>
</module>

================================================
FILE: apps/nestjs-backend/README.md
================================================
# NestJS backend for teable

TODO:
remove @valibot/to-json-schema in ai-sdk6
remove effect in ai-sdk6
remove @ai-sdk/provider-utils in ai-sdk6


================================================
FILE: apps/nestjs-backend/nest-cli.json
================================================
{
  "$schema": "https://json.schemastore.org/nest-cli",
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "entryFile": "index",
  "flat": true,
  "compilerOptions": {
    "builder": "webpack"
  }
}


================================================
FILE: apps/nestjs-backend/package.json
================================================
{
  "name": "@teable/backend",
  "version": "1.10.0",
  "license": "AGPL-3.0",
  "private": true,
  "main": "dist/index.js",
  "exports": {
    ".": "./dist"
  },
  "homepage": "https://github.com/teableio/teable",
  "repository": {
    "type": "git",
    "url": "https://github.com/teableio/teable",
    "directory": "apps/nestjs-backend"
  },
  "author": {
    "name": "tea artist",
    "url": "https://github.com/tea-artist"
  },
  "browserslist": {
    "production": [
      ">0.3%",
      "not ie 11",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "scripts": {
    "build": "nest build",
    "clean": "rimraf ./out ./coverage ./main ./dist ./tsconfig.tsbuildinfo ./node_modules/.cache .webpack-cache",
    "dev": "nest start --webpackPath ./webpack.dev.js -w",
    "dev:swc": "nest start --webpackPath ./webpack.swc.js -w",
    "start": "nest start",
    "check-dist": "es-check -v",
    "start-debug": "nest start --webpackPath ./webpack.dev.js --debug -w",
    "check-size": "size-limit --highlight-less",
    "test": "run-s test-unit test-e2e",
    "test-unit:watch": "vitest --watch",
    "test-unit": "vitest run --silent --bail 1",
    "test-unit-cover": "pnpm test-unit --coverage ${VITEST_SHARD:+--shard=$VITEST_SHARD}",
    "pre-test-e2e": "cross-env NODE_ENV=test pnpm -F @teable/db-main-prisma prisma-db-seed -- --e2e",
    "test-e2e": "pnpm pre-test-e2e && vitest run --config ./vitest-e2e.config.ts --silent",
    "test-e2e-cover": "pnpm test-e2e --coverage --bail 1 ${VITEST_SHARD:+--shard=$VITEST_SHARD}",
    "typecheck": "tsc --project ./tsconfig.json --noEmit",
    "lint": "eslint . --ext .ts,.js,.cjs,.mjs,.mdx --cache --cache-location ../../.cache/eslint/nestjs-backend.eslintcache",
    "fix-all-files": "eslint . --ext .ts,.tsx,.js,.jsx,.cjs,.mjs,.mdx --fix",
    "flamegraph-home": "npx 0x --output-dir './.debug/flamegraph/{pid}.0x' --on-port 'autocannon http://localhost:$PORT --duration 20' -- node ../../node_modules/.bin/next start",
    "merge-cover": "istanbul-merge --out ./coverage/nestjs-backend/coverage-final.json ./coverage/e2e/coverage-final.json ./coverage/unit/coverage-final.json",
    "generate-cover": "nyc report --report-dir=coverage/nestjs-backend --temp-dir=coverage/nestjs-backend -r text -r html -r clover"
  },
  "devDependencies": {
    "@faker-js/faker": "8.4.1",
    "@nestjs/cli": "10.3.2",
    "@nestjs/testing": "10.3.5",
    "@teable/eslint-config-bases": "workspace:^",
    "@types/archiver": "6.0.3",
    "@types/bcrypt": "5.0.2",
    "@types/cookie": "0.6.0",
    "@types/cookie-parser": "1.4.7",
    "@types/cors": "2.8.17",
    "@types/express": "4.17.21",
    "@types/express-session": "1.18.0",
    "@types/fs-extra": "11.0.4",
    "@types/lodash": "4.17.0",
    "@types/markdown-it": "13.0.7",
    "@types/mime-types": "2.1.4",
    "@types/ms": "0.7.34",
    "@types/multer": "1.4.11",
    "@types/node": "22.18.0",
    "@types/node-fetch": "2.6.11",
    "@types/nodemailer": "6.4.14",
    "@types/oauth2orize": "1.11.5",
    "@types/oauth2orize-pkce": "0.1.2",
    "@types/papaparse": "5.3.14",
    "@types/passport": "1.0.16",
    "@types/passport-github2": "1.2.9",
    "@types/passport-google-oauth20": "2.0.14",
    "@types/passport-jwt": "4.0.1",
    "@types/passport-local": "1.0.38",
    "@types/passport-oauth2-client-password": "0.1.5",
    "@types/passport-openidconnect": "0.1.3",
    "@types/pause": "0.1.3",
    "@types/pg": "8.16.0",
    "@types/sharedb": "5.1.0",
    "@types/sockjs": "0.3.36",
    "@types/sockjs-client": "1.5.4",
    "@types/stream-json": "1.7.8",
    "@types/through2": "2.0.41",
    "@types/unzipper": "0.10.11",
    "@types/ws": "8.18.1",
    "@vitest/coverage-v8": "4.0.17",
    "copy-webpack-plugin": "12.0.2",
    "cross-env": "7.0.3",
    "dotenv-flow": "4.1.0",
    "dotenv-flow-cli": "1.1.1",
    "es-check": "7.1.1",
    "eslint": "8.57.0",
    "eslint-config-next": "15.5.9",
    "get-tsconfig": "4.7.3",
    "istanbul-merge": "2.0.0",
    "npm-run-all2": "6.1.2",
    "nyc": "15.1.0",
    "pg-mem": "3.0.5",
    "prettier": "3.2.5",
    "rimraf": "5.0.5",
    "sockjs-client": "1.6.1",
    "sql-formatter": "^15.3.1",
    "swc-loader": "0.2.6",
    "symlink-dir": "5.2.1",
    "sync-directory": "6.0.5",
    "ts-loader": "9.5.1",
    "ts-node": "10.9.2",
    "typescript": "5.4.3",
    "unplugin-swc": "1.4.4",
    "vite-tsconfig-paths": "4.3.2",
    "vitest": "4.0.17",
    "vitest-mock-extended": "2.0.2",
    "webpack": "5.91.0"
  },
  "dependencies": {
    "@ai-sdk/amazon-bedrock": "4.0.69",
    "@ai-sdk/anthropic": "3.0.50",
    "@ai-sdk/azure": "3.0.38",
    "@ai-sdk/cohere": "3.0.22",
    "@ai-sdk/deepseek": "2.0.21",
    "@ai-sdk/google": "3.0.34",
    "@ai-sdk/mistral": "3.0.21",
    "@ai-sdk/openai": "3.0.37",
    "@ai-sdk/openai-compatible": "2.0.31",
    "@ai-sdk/togetherai": "2.0.35",
    "@ai-sdk/xai": "3.0.60",
    "@an-epiphany/websocket-json-stream": "1.2.0",
    "@aws-sdk/client-s3": "3.609.0",
    "@aws-sdk/lib-storage": "3.609.0",
    "@aws-sdk/s3-request-presigner": "3.609.0",
    "@keyv/redis": "2.8.4",
    "@keyv/sqlite": "3.6.7",
    "@nestjs-modules/mailer": "1.11.2",
    "@nestjs/axios": "3.0.2",
    "@nestjs/bullmq": "11.0.4",
    "@nestjs/common": "10.3.5",
    "@nestjs/config": "3.2.1",
    "@nestjs/core": "10.3.5",
    "@nestjs/event-emitter": "2.0.4",
    "@nestjs/jwt": "10.2.0",
    "@nestjs/passport": "10.0.3",
    "@nestjs/platform-express": "10.3.5",
    "@nestjs/platform-ws": "10.3.5",
    "@nestjs/swagger": "7.3.0",
    "@nestjs/terminus": "10.2.3",
    "@nestjs/websockets": "10.3.5",
    "@openrouter/ai-sdk-provider": "2.2.3",
    "@opentelemetry/api": "1.9.0",
    "@opentelemetry/context-async-hooks": "2.5.0",
    "@opentelemetry/exporter-logs-otlp-http": "0.201.1",
    "@opentelemetry/exporter-metrics-otlp-http": "0.201.1",
    "@opentelemetry/exporter-trace-otlp-http": "0.201.1",
    "@opentelemetry/instrumentation-express": "0.50.0",
    "@opentelemetry/instrumentation-http": "0.201.1",
    "@opentelemetry/instrumentation-ioredis": "0.49.0",
    "@opentelemetry/instrumentation-nestjs-core": "0.49.0",
    "@opentelemetry/instrumentation-pg": "0.49.0",
    "@opentelemetry/instrumentation-pino": "0.49.0",
    "@opentelemetry/instrumentation-runtime-node": "0.24.0",
    "@opentelemetry/resources": "2.0.1",
    "@opentelemetry/sdk-node": "0.201.1",
    "@opentelemetry/sdk-trace-base": "2.0.1",
    "@opentelemetry/semantic-conventions": "1.34.0",
    "@orpc/nest": "1.13.0",
    "@prisma/client": "6.2.1",
    "@prisma/instrumentation": "6.2.1",
    "@sentry/nestjs": "10.22.0",
    "@sentry/opentelemetry": "10.22.0",
    "@sentry/profiling-node": "10.22.0",
    "@smithy/node-http-handler": "^3.1.1",
    "@teable/common-i18n": "workspace:^",
    "@teable/core": "workspace:^",
    "@teable/db-main-prisma": "workspace:^",
    "@teable/openapi": "workspace:^",
    "@teable/v2-adapter-db-postgres-pg": "workspace:*",
    "@teable/v2-adapter-undo-redo-keyv": "workspace:*",
    "@teable/v2-adapter-realtime-sharedb": "workspace:*",
    "@teable/v2-container-node": "workspace:*",
    "@teable/v2-contract-http": "workspace:*",
    "@teable/v2-contract-http-implementation": "workspace:*",
    "@teable/v2-contract-http-openapi": "workspace:*",
    "@teable/v2-core": "workspace:*",
    "@teable/v2-di": "workspace:*",
    "@teable/v2-import": "workspace:*",
    "@valibot/to-json-schema": "1.3.0",
    "ai": "6.0.105",
    "ajv": "8.12.0",
    "archiver": "7.0.1",
    "axios": "1.7.7",
    "bcrypt": "5.1.1",
    "bullmq": "5.66.5",
    "class-transformer": "0.5.1",
    "class-validator": "0.14.1",
    "cookie": "0.6.0",
    "cookie-parser": "1.4.6",
    "cors": "2.8.5",
    "csv-parser": "3.2.0",
    "csv-stringify": "6.5.2",
    "date-fns-tz": "3.2.0",
    "dayjs": "1.11.10",
    "effect": "3.19.1",
    "esbuild": "0.23.0",
    "express": "4.21.1",
    "express-session": "1.18.0",
    "fs-extra": "11.2.0",
    "handlebars": "4.7.8",
    "helmet": "7.1.0",
    "http-proxy-middleware": "3.0.3",
    "ioredis": "5.9.1",
    "is-port-reachable": "3.1.0",
    "joi": "17.12.2",
    "jschardet": "3.1.3",
    "keyv": "4.5.4",
    "knex": "3.1.0",
    "lodash": "4.17.21",
    "mime-types": "2.1.35",
    "minio": "7.1.3",
    "ms": "2.1.3",
    "multer": "1.4.5-lts.1",
    "nanoid": "3.3.7",
    "nest-knexjs": "0.0.22",
    "nestjs-cls": "4.3.0",
    "nestjs-i18n": "10.5.1",
    "nestjs-pino": "4.4.1",
    "nestjs-redoc": "2.2.2",
    "next": "16.1.6",
    "node-fetch": "2.7.0",
    "node-sql-parser": "5.3.8",
    "nodemailer": "6.9.13",
    "oauth2orize": "1.12.0",
    "oauth2orize-pkce": "0.1.2",
    "object-sizeof": "2.6.4",
    "ollama-ai-provider-v2": "3.0.2",
    "papaparse": "5.4.1",
    "passport": "0.7.0",
    "passport-github2": "0.1.12",
    "passport-google-oauth20": "2.0.0",
    "passport-jwt": "4.0.1",
    "passport-local": "1.0.0",
    "passport-oauth2-client-password": "0.1.2",
    "passport-openidconnect": "0.1.2",
    "pause": "0.1.0",
    "pg": "8.11.5",
    "pino-http": "10.5.0",
    "pino-pretty": "11.0.0",
    "react": "18.3.1",
    "react-dom": "18.3.1",
    "redlock": "5.0.0-beta.2",
    "reflect-metadata": "0.2.1",
    "rxjs": "7.8.1",
    "sharedb": "5.2.2",
    "sharp": "0.33.3",
    "sockjs": "0.3.24",
    "stream-json": "1.9.1",
    "through2": "4.0.2",
    "transliteration": "2.3.5",
    "ts-pattern": "5.0.8",
    "unzipper": "0.12.3",
    "ws": "8.18.3",
    "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
    "zod": "4.1.8",
    "zod-validation-error": "4.0.2"
  }
}


================================================
FILE: apps/nestjs-backend/src/app.module.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import { BullModule } from '@nestjs/bullmq';
import type { ModuleMetadata } from '@nestjs/common';
import { Module } from '@nestjs/common';
import { ConditionalModule, ConfigService } from '@nestjs/config';
import { SentryModule } from '@sentry/nestjs/setup';
import Redis from 'ioredis';
import type { ICacheConfig } from './configs/cache.config';
import { ConfigModule } from './configs/config.module';
import { AccessTokenModule } from './features/access-token/access-token.module';
import { AggregationOpenApiModule } from './features/aggregation/open-api/aggregation-open-api.module';
import { AiModule } from './features/ai/ai.module';
import { AttachmentsModule } from './features/attachments/attachments.module';
import { AuthModule } from './features/auth/auth.module';
import { BaseModule } from './features/base/base.module';
import { BaseNodeModule } from './features/base-node/base-node.module';
import { BuiltinAssetsInitModule } from './features/builtin-assets-init';
import { CanaryModule } from './features/canary';
import { ChatModule } from './features/chat/chat.module';
import { CollaboratorModule } from './features/collaborator/collaborator.module';
import { CommentOpenApiModule } from './features/comment/comment-open-api.module';
import { DashboardModule } from './features/dashboard/dashboard.module';
import { ExportOpenApiModule } from './features/export/open-api/export-open-api.module';
import { FieldOpenApiModule } from './features/field/open-api/field-open-api.module';
import { HealthModule } from './features/health/health.module';
import { ImportOpenApiModule } from './features/import/open-api/import-open-api.module';
import { IntegrityModule } from './features/integrity/integrity.module';
import { InvitationModule } from './features/invitation/invitation.module';
import { MailSenderOpenApiModule } from './features/mail-sender/open-api/mail-sender-open-api.module';
import { MailSenderMergeModule } from './features/mail-sender/open-api/mail-sender.merge.module';
import { NextModule } from './features/next/next.module';
import { NotificationModule } from './features/notification/notification.module';
import { OAuthModule } from './features/oauth/oauth.module';
import { OrganizationModule } from './features/organization/organization.module';
import { PinModule } from './features/pin/pin.module';
import { PluginChartModule } from './features/plugin/official/chart/plugin-chart.module';
import { PluginModule } from './features/plugin/plugin.module';
import { PluginContextMenuModule } from './features/plugin-context-menu/plugin-context-menu.module';
import { PluginPanelModule } from './features/plugin-panel/plugin-panel.module';
import { SelectionModule } from './features/selection/selection.module';
import { AdminOpenApiModule } from './features/setting/open-api/admin-open-api.module';
import { SettingOpenApiModule } from './features/setting/open-api/setting-open-api.module';
import { BaseShareModule } from './features/base-share/base-share.module';
import { ShareModule } from './features/share/share.module';
import { SpaceModule } from './features/space/space.module';
import { TemplateOpenApiModule } from './features/template/template-open-api.module';
import { TrashModule } from './features/trash/trash.module';
import { UndoRedoModule } from './features/undo-redo/open-api/undo-redo.module';
import { UserModule } from './features/user/user.module';
import { V2Module } from './features/v2/v2.module';
import { GlobalModule } from './global/global.module';
import { InitBootstrapProvider } from './global/init-bootstrap.provider';
import { LoggerModule } from './logger/logger.module';
import { ObservabilityModule } from './observability/observability.module';
import { WsModule } from './ws/ws.module';

// In CI or test environments, use a longer timeout for ConditionalModule
// to avoid sporadic timeout errors when resources are under pressure
const isTestOrCI = process.env.CI || process.env.NODE_ENV === 'test' || process.env.VITEST;
const CONDITIONAL_MODULE_TIMEOUT = isTestOrCI ? 60000 : 5000;

export const appModules = {
  imports: [
    SentryModule.forRoot(),
    LoggerModule.register(),
    MailSenderOpenApiModule,
    MailSenderMergeModule,
    HealthModule,
    NextModule,
    FieldOpenApiModule,
    TemplateOpenApiModule,
    BaseModule,
    BaseNodeModule,
    IntegrityModule,
    ChatModule,
    AttachmentsModule,
    WsModule,
    SelectionModule,
    UndoRedoModule,
    AggregationOpenApiModule,
    UserModule,
    AuthModule,
    SpaceModule,
    CollaboratorModule,
    InvitationModule,
    ShareModule,
    BaseShareModule,
    NotificationModule,
    AccessTokenModule,
    ImportOpenApiModule,
    ExportOpenApiModule,
    PinModule,
    AdminOpenApiModule,
    CanaryModule,
    SettingOpenApiModule,
    OAuthModule,
    TrashModule,
    DashboardModule,
    CommentOpenApiModule,
    OrganizationModule,
    AiModule,
    PluginModule,
    PluginPanelModule,
    PluginContextMenuModule,
    PluginChartModule,
    ObservabilityModule,
    BuiltinAssetsInitModule,
    V2Module,
  ],
  providers: [InitBootstrapProvider],
};

@Module({
  ...appModules,
  imports: [
    GlobalModule,
    ...appModules.imports,
    ConditionalModule.registerWhen(
      BullModule.forRootAsync({
        imports: [ConfigModule],
        useFactory: async (configService: ConfigService) => {
          const redisUri = configService.get<ICacheConfig>('cache')?.redis.uri;
          if (!redisUri) {
            throw new Error('Redis URI is not defined');
          }
          const redis = new Redis(redisUri, { lazyConnect: true, maxRetriesPerRequest: null });
          await redis.connect();

          return {
            connection: redis,
          };
        },
        inject: [ConfigService],
      }),
      (env) => {
        return Boolean(env.BACKEND_CACHE_REDIS_URI);
      },
      { timeout: CONDITIONAL_MODULE_TIMEOUT }
    ),
  ],
  controllers: [],
})
export class AppModule {
  static register(customModuleMetadata: ModuleMetadata) {
    return {
      module: AppModule,
      ...customModuleMetadata,
    };
  }
}


================================================
FILE: apps/nestjs-backend/src/bootstrap.ts
================================================
import 'dayjs/plugin/timezone';
import 'dayjs/plugin/utc';
import type { INestApplication } from '@nestjs/common';
import { ValidationPipe } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { NestFactory } from '@nestjs/core';
import { json, urlencoded } from 'express';
import helmet from 'helmet';
import isPortReachable from 'is-port-reachable';
import { Logger } from 'nestjs-pino';
import { AppModule } from './app.module';
import type { IBaseConfig } from './configs/base.config';
import type { ISecurityWebConfig, IApiDocConfig } from './configs/bootstrap.config';
import { GlobalExceptionFilter } from './filter/global-exception.filter';
import { setupSwagger } from './swagger';

const host = 'localhost';

export async function setUpAppMiddleware(app: INestApplication, configService: ConfigService) {
  app.useGlobalFilters(new GlobalExceptionFilter(configService));
  app.useGlobalPipes(
    new ValidationPipe({ transform: true, stopAtFirstError: true, forbidUnknownValues: false })
  );
  // HSTS is configured at the WAF level. Disable it here to avoid sending duplicate
  // `Strict-Transport-Security` headers with potentially different max-age values.
  app.use(helmet({ hsts: false }));
  app.use(json({ limit: '50mb' }));
  app.use(urlencoded({ limit: '50mb', extended: true }));

  const apiDocConfig = configService.get<IApiDocConfig>('apiDoc');
  const securityWebConfig = configService.get<ISecurityWebConfig>('security.web');
  const baseConfig = configService.get<IBaseConfig>('base');
  if (!apiDocConfig?.disabled) {
    await setupSwagger(app, baseConfig?.publicOrigin ?? '', apiDocConfig?.enabledSnippet ?? false);
  }

  if (securityWebConfig?.cors.enabled) {
    app.enableCors();
  }
}

export async function bootstrap() {
  const app = await NestFactory.create(AppModule, { bufferLogs: true });
  const configService = app.get(ConfigService);

  const logger = app.get(Logger);
  app.useLogger(logger);
  app.flushLogs();

  app.enableShutdownHooks();

  await setUpAppMiddleware(app, configService);

  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
  // app.getHttpServer().on('upgrade', async function (req: any, socket: any, head: any) {
  //   if (req.url.startsWith('/_next')) {
  //     console.log('upgrade: ', req.url);
  //     const server = app.get(NextService).server;
  //     return server.getUpgradeHandler()(req, socket, head);
  //   }
  // });

  const port = await getAvailablePort(configService.get<string>('PORT') as string);
  process.env.PORT = port.toString();

  await app.listen(port);

  const now = new Date();
  const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
  logger.log(`> NODE_ENV is ${process.env.NODE_ENV}`);
  logger.log(`> Ready on http://${host}:${port}`);
  logger.log(`> System Time Zone: ${timeZone}`);
  logger.log(`> Current System Time: ${now.toString()}`);

  process.on('unhandledRejection', (reason: string, promise: Promise<unknown>) => {
    logger.error(`Unhandled Rejection at: ${promise}, reason: ${reason}`);
    throw reason;
  });

  process.on('uncaughtException', (error) => {
    logger.error(error);
  });
  return app;
}

async function getAvailablePort(dPort: number | string): Promise<number> {
  let port = Number(dPort);
  while (await isPortReachable(port, { host })) {
    console.log(`> Fail on http://${host}:${port} Trying on ${port + 1}`);
    port++;
  }
  return port;
}


================================================
FILE: apps/nestjs-backend/src/cache/cache.module.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import { ConfigurableModuleBuilder, type DynamicModule, Module } from '@nestjs/common';
import { CacheProvider } from './cache.provider';

export interface CacheModuleOptions {
  global?: boolean;
}

export const { ConfigurableModuleClass: CacheModuleClass, OPTIONS_TYPE } =
  new ConfigurableModuleBuilder<CacheModuleOptions>().build();

@Module({
  providers: [CacheProvider],
  exports: [CacheProvider],
})
export class CacheModule extends CacheModuleClass {
  static register(options: typeof OPTIONS_TYPE): DynamicModule {
    return {
      global: options.global,
      ...super.register(options),
    };
  }
}


================================================
FILE: apps/nestjs-backend/src/cache/cache.provider.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import path from 'path';
import KeyvRedis from '@keyv/redis';
import KeyvSqlite from '@keyv/sqlite';
import type { Provider } from '@nestjs/common';
import { Logger } from '@nestjs/common';
import * as fse from 'fs-extra';
import Keyv from 'keyv';
import { match } from 'ts-pattern';
import type { ICacheConfig } from '../configs/cache.config';
import { cacheConfig } from '../configs/cache.config';
import { CacheService } from './cache.service';

export const CacheProvider: Provider = {
  provide: CacheService,
  inject: [cacheConfig.KEY],
  useFactory: async (config: ICacheConfig) => {
    const { provider, sqlite, redis } = config;

    Logger.log(`[Cache Manager Adapter]: ${provider}`);

    const store = match(provider)
      .with('memory', () => new Map())
      .with('sqlite', () => {
        const uri = sqlite.uri.replace(/^sqlite:\/\//, '');
        fse.ensureFileSync(uri);

        Logger.log(`[Cache Manager File Path]: ${path.resolve(uri)}`);

        return new KeyvSqlite({
          ...sqlite,
          uri,
        });
      })
      .with('redis', () => new KeyvRedis(redis, { useRedisSets: false }))
      .exhaustive();

    const keyv = new Keyv({ namespace: 'teable_cache', store: store });
    keyv.on('error', (error) => {
      error && Logger.error(error, 'Cache Manager Connection Error');
    });

    Logger.log(`[Cache Manager Namespace]: ${keyv.opts.namespace}`);
    return new CacheService(keyv);
  },
};


================================================
FILE: apps/nestjs-backend/src/cache/cache.service.ts
================================================
import { Injectable, Logger } from '@nestjs/common';
import { getRandomInt } from '@teable/core';
import type { Redis } from 'ioredis';
import Keyv from 'keyv';
import { second } from '../utils/second';
import type { ICacheStore } from './types';

@Injectable()
export class CacheService<T extends ICacheStore = ICacheStore> {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  constructor(private readonly cacheManager: Keyv<any>) {}
  private readonly logger = new Logger(CacheService.name);

  getKeyv(): Keyv<any> {
    return this.cacheManager;
  }

  /**
   * Get the underlying Redis client if available
   * Returns undefined if not using Redis
   */
  private getRedisClient(): Redis | undefined {
    try {
      // KeyvRedis stores the Redis client in store.redis
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      const store = this.cacheManager.opts?.store as any;
      return store?.redis || store?.client;
    } catch {
      return undefined;
    }
  }

  /**
   * Atomic set-if-not-exists operation (Redis SETNX with EX)
   * Returns true if the key was set, false if it already existed
   * @param key - The key to set
   * @param value - The value to set
   * @param ttlSeconds - TTL in seconds
   */
  async setnx<TKey extends keyof T>(
    key: TKey,
    value: T[TKey],
    ttlSeconds: number
  ): Promise<boolean> {
    const redis = this.getRedisClient();
    if (!redis) {
      // Fallback for non-Redis: not truly atomic, but better than nothing
      const existing = await this.get(key);
      if (existing !== undefined) {
        return false;
      }
      await this.setDetail(key, value, ttlSeconds);
      return true;
    }

    // Use Redis SET with NX and EX for atomic operation
    const fullKey = `${this.cacheManager.opts.namespace}:${key as string}`;
    const serializedValue = JSON.stringify(value);
    const result = await redis.set(fullKey, serializedValue, 'EX', ttlSeconds, 'NX');
    return result === 'OK';
  }

  /**
   * Atomic increment operation (Redis INCR with optional EX)
   * Returns the new value after increment
   * @param key - The key to increment
   * @param ttlSeconds - Optional TTL in seconds (only set on first increment)
   */
  async incr<TKey extends keyof T>(key: TKey, ttlSeconds?: number): Promise<number> {
    const redis = this.getRedisClient();
    if (!redis) {
      // Fallback for non-Redis: not truly atomic
      const current = (await this.get(key)) as number | undefined;
      const newValue = (current || 0) + 1;
      await this.setDetail(key, newValue as T[TKey], ttlSeconds);
      return newValue;
    }

    const fullKey = `${this.cacheManager.opts.namespace}:${key as string}`;
    const newValue = await redis.incr(fullKey);

    // Set TTL only if provided and this is the first increment (value is 1)
    if (ttlSeconds && newValue === 1) {
      await redis.expire(fullKey, ttlSeconds);
    }

    return newValue;
  }

  private warnNotSetTTL(key: string, ttl?: number) {
    if (!ttl || Number.isNaN(ttl) || ttl <= 0) {
      this.logger.warn(`[Cache Service] Not set ttl for key: ${key}`);
    }
  }

  async get<TKey extends keyof T>(key: TKey): Promise<T[TKey] | undefined> {
    return this.cacheManager.get(key as string);
  }

  async set<TKey extends keyof T>(
    key: TKey,
    value: T[TKey],
    // seconds, and will add random 20-60 seconds
    ttl?: number | string
  ): Promise<void> {
    const numberTTL = typeof ttl === 'string' ? second(ttl) : ttl;
    this.warnNotSetTTL(key as string, numberTTL);
    await this.cacheManager.set(
      key as string,
      value,
      numberTTL ? (numberTTL + getRandomInt(20, 60)) * 1000 : undefined
    );
  }

  // no add random ttl
  async setDetail<TKey extends keyof T>(
    key: TKey,
    value: T[TKey],
    ttl?: number | string // seconds
  ): Promise<void> {
    const numberTTL = typeof ttl === 'string' ? second(ttl) : ttl;
    this.warnNotSetTTL(key as string, numberTTL);
    await this.cacheManager.set(key as string, value, numberTTL ? numberTTL * 1000 : undefined);
  }

  async del<TKey extends keyof T>(key: TKey): Promise<void> {
    await this.cacheManager.delete(key as string);
  }

  async getMany<TKey extends keyof T>(keys: TKey[]): Promise<Array<T[TKey] | undefined>> {
    return this.cacheManager.get(keys as string[]);
  }

  /**
   * Update the TTL of an existing key without reading/writing data
   * Returns true if the key exists and TTL was updated
   */
  async expire<TKey extends keyof T>(key: TKey, ttl: number | string): Promise<boolean> {
    const ttlSeconds = typeof ttl === 'string' ? second(ttl) : ttl;
    const redis = this.getRedisClient();
    if (!redis) {
      // Fallback for non-Redis: get and re-set
      const value = await this.get(key);
      if (value !== undefined) {
        await this.setDetail(key, value, ttlSeconds);
        return true;
      }
      return false;
    }

    const fullKey = `${this.cacheManager.opts.namespace}:${key as string}`;
    const result = await redis.expire(fullKey, ttlSeconds);
    return result === 1;
  }
}


================================================
FILE: apps/nestjs-backend/src/cache/types.ts
================================================
import type { IColumnMeta, IFieldVo, IOtOperation, IViewPropertyKeys, IViewVo } from '@teable/core';
import type { IRecord, MailType } from '@teable/openapi';
import type { ICellContext } from '../features/calculation/utils/changes';
import type { IOpsMap } from '../features/calculation/utils/compose-maps';
import type { ISendMailOptions } from '../features/mail-sender/mail-helpers';
import type { ISessionData } from '../types/session';

/* eslint-disable @typescript-eslint/naming-convention */
export interface ICacheStore {
  [key: `attachment:signature:${string}`]: IAttachmentSignatureCache;
  [key: `attachment:upload:${string}`]: IAttachmentUploadCache;
  [key: `attachment:local-signature:${string}`]: IAttachmentLocalTokenCache;
  [key: `attachment:preview:${string}`]: IAttachmentPreviewCache;
  [key: `auth:session-store:${string}`]: ISessionData;
  [key: `auth:session-user:${string}`]: Record<string, number>;
  [key: `auth:session-expire:${string}`]: boolean;
  [key: `oauth2:${string}`]: IOauth2State;
  [key: `reset-password-email:${string}`]: IResetPasswordEmailCache;
  [key: `workflow:running:${string}`]: string;
  [key: `workflow:repeatKey:${string}`]: string;
  [key: `oauth:code:${string}`]: IOAuthCodeState;
  [key: `oauth:txn:${string}`]: IOAuthTxnStore;
  // userId:tableId:windowId
  [key: `operations:undo:${string}:${string}:${string}`]: IUndoRedoOperation[];
  [key: `operations:redo:${string}:${string}:${string}`]: IUndoRedoOperation[];
  [key: `plugin:auth-code:${string}`]: IPluginAuthStore;
  [key: `signin:attempts:${string}`]: number;
  [key: `signin:lockout:${string}`]: boolean;
  [key: `query-params:${string}`]: Record<string, unknown>;
  [key: `mail-sender:notify-mail-merge:${string}`]: (ISendMailOptions & {
    mailType: MailType;
  })[];
  [key: `waitlist:invite-code:${string}`]: number;
  [key: `send-mail-rate-limit:${string}`]: boolean;
  [key: `oauth:token-rate:${string}:${string}`]: number;
  [key: `automation:email:rate:${string}:${number}`]: number;
  // Distributed lock keys
  [key: `lock:${string}`]: string;
  [key: `import:result:manifest:${string}`]: {
    successCount: number;
    failedCount: number;
    errorFilePaths: string[];
    fieldNames: string[];
    maxWidth: number;
    errorReportUrl?: string;
  };
  [key: `import:latest-job:${string}`]: string;
  // trash cleanup: per-item backoff after failed cleanup attempts
  [key: `trash-cleanup:skipped:${string}`]: { attempts: number; retryAfter: number };
}

export interface IAttachmentSignatureCache {
  path: string;
  bucket: string;
  hash?: string;
}

export interface IAttachmentUploadCache {
  mimetype: string;
  hash: string;
  size: number;
}

export interface IAttachmentLocalTokenCache {
  expiresDate: number;
  contentLength: number;
  contentType: string;
}

export interface IAttachmentPreviewCache {
  url: string;
  expiresIn: number;
}

export interface IOauth2State {
  redirectUri?: string;
}

export interface IResetPasswordEmailCache {
  userId: string;
}

export interface IOAuthCodeState {
  scopes: string[];
  redirectUri: string;
  clientId: string;
  user: {
    id: string;
    name: string;
    email: string;
  };
  codeChallenge?: string;
  codeChallengeMethod?: 'S256';
}

export interface IOAuthTxnStore {
  redirectURI: string;
  clientId: string;
  type: string;
  scopes: string[];
  userId: string;
  state?: string;
  codeChallenge?: string;
  codeChallengeMethod?: string;
}

export enum OperationName {
  CreateView = 'createView',
  DeleteView = 'deleteView',
  UpdateView = 'updateView',
  CreateRecords = 'createRecords',
  DeleteRecords = 'deleteRecords',
  UpdateRecords = 'updateRecords',
  UpdateRecordsOrder = 'updateRecordsOrder',
  CreateFields = 'createFields',
  ConvertField = 'convertField',
  ConvertFieldV2 = 'convertFieldV2',
  DeleteFields = 'deleteFields',
  PasteSelection = 'pasteSelection',
}

export interface IUndoRedoOperationBase {
  name: OperationName;
  params: Record<string, unknown>;
  result?: unknown;
  userId?: string;
  operationId?: string;
}

export interface IUpdateRecordsOperation extends IUndoRedoOperationBase {
  name: OperationName.UpdateRecords;
  params: {
    tableId: string;
    recordIds: string[];
    fieldIds: string[];
  };
  result: {
    cellContexts?: ICellContext[];
    ordersMap?: {
      [recordId: string]: {
        newOrder?: Record<string, number>;
        oldOrder?: Record<string, number>;
      };
    };
  };
}

export interface IUpdateRecordsOrderOperation extends IUndoRedoOperationBase {
  name: OperationName.UpdateRecordsOrder;
  params: {
    tableId: string;
    viewId: string;
    recordIds: string[];
  };
  result: {
    ordersMap?: {
      [recordId: string]: {
        newOrder?: Record<string, number>;
        oldOrder?: Record<string, number>;
      };
    };
  };
}

export interface ICreateRecordsOperation extends IUndoRedoOperationBase {
  name: OperationName.CreateRecords;
  params: {
    tableId: string;
  };
  result: {
    records: (IRecord & { order?: Record<string, number> })[];
  };
}

export interface IDeleteRecordsOperation extends Omit<ICreateRecordsOperation, 'name'> {
  name: OperationName.DeleteRecords;
}

export interface IConvertFieldOperation extends IUndoRedoOperationBase {
  name: OperationName.ConvertField;
  params: {
    tableId: string;
  };
  result: {
    oldField: IFieldVo;
    newField: IFieldVo;
    modifiedOps?: IOpsMap;
    references?: string[];
    supplementChange?: {
      tableId: string;
      newField: IFieldVo;
      oldField: IFieldVo;
    };
  };
}

export interface IConvertFieldV2Operation extends IUndoRedoOperationBase {
  name: OperationName.ConvertFieldV2;
  params: {
    tableId: string;
  };
  result: {
    oldField: IFieldVo;
    newField: IFieldVo;
    modifiedOps?: IOpsMap;
    references?: string[];
  };
}

export interface ICreateFieldsOperation extends IUndoRedoOperationBase {
  name: OperationName.CreateFields;
  params: {
    tableId: string;
  };
  result: {
    fields: (IFieldVo & { columnMeta?: IColumnMeta; references?: string[] })[];
    records?: {
      id: string;
      fields: Record<string, unknown>;
    }[];
  };
}

export interface IDeleteFieldsOperation extends Omit<ICreateFieldsOperation, 'name'> {
  name: OperationName.DeleteFields;
}

export interface IPasteSelectionOperation extends IUndoRedoOperationBase {
  name: OperationName.PasteSelection;
  params: {
    tableId: string;
  };
  result: {
    updateRecords?: {
      recordIds: string[];
      fieldIds: string[];
      cellContexts: ICellContext[];
    };
    newFields?: (IFieldVo & { columnMeta?: IColumnMeta; references?: string[] })[];
    newRecords?: (IRecord & { order?: Record<string, number> })[];
  };
}

export interface ICreateViewOperation extends IUndoRedoOperationBase {
  name: OperationName.CreateView;
  params: {
    tableId: string;
  };
  result: {
    view: IViewVo;
  };
}

export interface IDeleteViewOperation extends IUndoRedoOperationBase {
  name: OperationName.DeleteView;
  params: {
    tableId: string;
    viewId: string;
  };
}

export interface IUpdateViewOperation extends IUndoRedoOperationBase {
  name: OperationName.UpdateView;
  params: {
    tableId: string;
    viewId: string;
  };
  result: {
    byKey?: {
      key: IViewPropertyKeys;
      newValue: unknown;
      oldValue: unknown;
    };
    byOps?: IOtOperation[];
  };
}

export type IUndoRedoOperation =
  | IUpdateRecordsOperation
  | ICreateRecordsOperation
  | IDeleteRecordsOperation
  | IUpdateRecordsOrderOperation
  | ICreateFieldsOperation
  | IDeleteFieldsOperation
  | IConvertFieldOperation
  | IConvertFieldV2Operation
  | IPasteSelectionOperation
  | ICreateViewOperation
  | IDeleteViewOperation
  | IUpdateViewOperation;
export interface IPluginAuthStore {
  baseId: string;
  pluginId: string;
}


================================================
FILE: apps/nestjs-backend/src/configs/auth.config.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import { Inject } from '@nestjs/common';
import type { ConfigType } from '@nestjs/config';
import { registerAs } from '@nestjs/config';

const getCookieSecure = (value: string | undefined) => {
  if (!value) {
    return undefined;
  }
  if (value === 'auto') {
    return 'auto' as const;
  }
  return value === 'true';
};

export const authConfig = registerAs('auth', () => ({
  jwt: {
    secret:
      process.env.BACKEND_JWT_SECRET ?? process.env.SECRET_KEY ?? '533Cr3tK3yF0rH4sh1nGJ4W773k3n$',
    expiresIn: process.env.BACKEND_JWT_EXPIRES_IN ?? '20d',
  },
  session: {
    secret:
      process.env.BACKEND_SESSION_SECRET ??
      process.env.SECRET_KEY ??
      'dafea6be69af1c1c3b8caf2b609342f6eb4540b554e19539f7643b75b480c932',
    expiresIn: process.env.BACKEND_SESSION_EXPIRES_IN ?? '7d',
    cookie: {
      secure: getCookieSecure(process.env.BACKEND_SESSION_COOKIE_SECURE),
    },
  },
  accessToken: {
    prefix: 'teable',
    encryption: {
      algorithm: process.env.BACKEND_ACCESS_TOKEN_ENCRYPTION_ALGORITHM ?? 'aes-128-cbc',
      key: process.env.BACKEND_ACCESS_TOKEN_ENCRYPTION_KEY ?? 'ie21hOKjlXUiGDx9',
      iv: process.env.BACKEND_ACCESS_TOKEN_ENCRYPTION_IV ?? 'i0vKGXBWkzyAoGf4',
    },
  },
  resetPasswordEmailExpiresIn:
    process.env.BACKEND_EMAIL_CODE_EXPIRES_IN ??
    process.env.BACKEND_RESET_PASSWORD_EMAIL_EXPIRES_IN ??
    '30m',
  signupVerificationExpiresIn:
    process.env.BACKEND_EMAIL_CODE_EXPIRES_IN ??
    process.env.BACKEND_SIGNUP_VERIFICATION_EXPIRES_IN ??
    '30m',
  socialAuthProviders: process.env.SOCIAL_AUTH_PROVIDERS?.split(',') ?? [],
  github: {
    clientID: process.env.BACKEND_GITHUB_CLIENT_ID,
    clientSecret: process.env.BACKEND_GITHUB_CLIENT_SECRET,
    callbackURL: process.env.BACKEND_GITHUB_CALLBACK_URL,
  },
  google: {
    clientID: process.env.BACKEND_GOOGLE_CLIENT_ID,
    clientSecret: process.env.BACKEND_GOOGLE_CLIENT_SECRET,
    callbackURL: process.env.BACKEND_GOOGLE_CALLBACK_URL,
  },
  oidc: {
    issuer: process.env.BACKEND_OIDC_ISSUER,
    authorizationURL: process.env.BACKEND_OIDC_AUTHORIZATION_URL,
    tokenURL: process.env.BACKEND_OIDC_TOKEN_URL,
    userInfoURL: process.env.BACKEND_OIDC_USER_INFO_URL,
    clientID: process.env.BACKEND_OIDC_CLIENT_ID,
    clientSecret: process.env.BACKEND_OIDC_CLIENT_SECRET,
    callbackURL: process.env.BACKEND_OIDC_CALLBACK_URL,
    other: process.env.BACKEND_OIDC_OTHER ? JSON.parse(process.env.BACKEND_OIDC_OTHER) : {},
  },
  signin: {
    maxLoginAttempts: process.env.SIGNIN_MAX_LOGIN_ATTEMPTS
      ? Number(process.env.SIGNIN_MAX_LOGIN_ATTEMPTS)
      : undefined,
    accountLockoutMinutes: process.env.SIGNIN_ACCOUNT_LOCKOUT_MINUTES
      ? Number(process.env.SIGNIN_ACCOUNT_LOCKOUT_MINUTES)
      : undefined,
  },
}));

export const AuthConfig = () => Inject(authConfig.KEY);

export type IAuthConfig = ConfigType<typeof authConfig>;


================================================
FILE: apps/nestjs-backend/src/configs/base.config.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import { Inject } from '@nestjs/common';
import type { ConfigType } from '@nestjs/config';
import { registerAs } from '@nestjs/config';

export const baseConfig = registerAs('base', () => ({
  isCloud: process.env.NEXT_BUILD_ENV_EDITION?.toUpperCase() === 'CLOUD',
  publicOrigin: process.env.PUBLIC_ORIGIN,
  storagePrefix: process.env.STORAGE_PREFIX ?? process.env.PUBLIC_ORIGIN,
  secretKey: process.env.SECRET_KEY ?? 'defaultSecretKey',
  publicDatabaseProxy: process.env.PUBLIC_DATABASE_PROXY,
  defaultMaxBaseDBConnections: Number(process.env.DEFAULT_MAX_BASE_DB_CONNECTIONS ?? 20),
  templateSpaceId: process.env.TEMPLATE_SPACE_ID,
  recordHistoryDisabled: process.env.RECORD_HISTORY_DISABLED === 'true',
  pluginServerPort: process.env.PLUGIN_SERVER_PORT || '3002',
  enableEmailCodeConsole: process.env.ENABLE_EMAIL_CODE_CONSOLE === 'true',
  emailCodeExpiresIn: process.env.BACKEND_EMAIL_CODE_EXPIRES_IN ?? '30m',
  chatContextAttachmentSize: Number(process.env.CHAT_CONTEXT_ATTACHMENT_SIZE ?? 10),
}));

export const BaseConfig = () => Inject(baseConfig.KEY);

export type IBaseConfig = ConfigType<typeof baseConfig>;


================================================
FILE: apps/nestjs-backend/src/configs/bootstrap.config.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import type { ConfigType } from '@nestjs/config';
import { registerAs } from '@nestjs/config';

export const nextJsConfig = registerAs('nextJs', () => ({
  dir: process.env.NEXTJS_DIR ?? '../nextjs-app',
}));

export const securityWebConfig = registerAs('security.web', () => ({
  cors: {
    enabled: true,
  },
}));

export const tracingConfig = registerAs('tracing', () => ({
  enabled: process.env.TRACING_ENABLED === 'true',
}));

export const apiDocConfig = registerAs('apiDoc', () => ({
  disabled: process.env.API_DOC_DISENABLED === 'true',
  enabledSnippet: process.env.API_DOC_ENABLED_SNIPPET === 'true',
}));

export type INextJsConfig = ConfigType<typeof nextJsConfig>;
export type ISecurityWebConfig = ConfigType<typeof securityWebConfig>;
export type IApiDocConfig = ConfigType<typeof apiDocConfig>;
export const bootstrapConfigs = [nextJsConfig, securityWebConfig, apiDocConfig];


================================================
FILE: apps/nestjs-backend/src/configs/cache.config.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import { Inject } from '@nestjs/common';
import type { ConfigType } from '@nestjs/config';
import { registerAs } from '@nestjs/config';

export const cacheConfig = registerAs('cache', () => ({
  provider: (process.env.BACKEND_CACHE_PROVIDER ?? 'sqlite') as 'memory' | 'sqlite' | 'redis',
  sqlite: {
    uri: process.env.BACKEND_CACHE_SQLITE_URI ?? 'sqlite://.assets/.cache.db',
  },
  redis: {
    uri: process.env.BACKEND_CACHE_REDIS_URI,
  },
}));

export const CacheConfig = () => Inject(cacheConfig.KEY);

export type ICacheConfig = ConfigType<typeof cacheConfig>;


================================================
FILE: apps/nestjs-backend/src/configs/config.module.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import path from 'path';
import type { DynamicModule } from '@nestjs/common';
import { Logger, Module } from '@nestjs/common';
import { ConfigModule as BaseConfigModule } from '@nestjs/config';
import { authConfig } from './auth.config';
import { baseConfig } from './base.config';
import { bootstrapConfigs, nextJsConfig } from './bootstrap.config';
import { cacheConfig } from './cache.config';
import { envValidationSchema } from './env.validation.schema';
import { loggerConfig } from './logger.config';
import { mailConfig } from './mail.config';
import { oauthConfig } from './oauth.config';
import { storageConfig } from './storage';
import { thresholdConfig } from './threshold.config';
import { trashConfig } from './trash.config';

const configurations = [
  ...bootstrapConfigs,
  loggerConfig,
  mailConfig,
  authConfig,
  baseConfig,
  storageConfig,
  thresholdConfig,
  cacheConfig,
  oauthConfig,
  trashConfig,
];

@Module({})
export class ConfigModule {
  static register(): DynamicModule {
    return BaseConfigModule.forRoot({
      isGlobal: true,
      cache: true,
      expandVariables: true,
      load: configurations,
      envFilePath: ['.env.development.local', '.env.development', '.env'].map((str) => {
        const nextJsDir = nextJsConfig().dir;
        const envDir = nextJsDir ? path.join(process.cwd(), nextJsDir, str) : str;

        Logger.attachBuffer();
        Logger.log(`[Env File Path]: ${envDir}`);
        Logger.detachBuffer();
        return envDir;
      }),
      validationSchema: envValidationSchema,
    });
  }
}


================================================
FILE: apps/nestjs-backend/src/configs/config.spec.ts
================================================
import { ConfigService } from '@nestjs/config';
import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';
import { vi } from 'vitest';

type IMockConfigService = Partial<ConfigService>;

export const createMockConfigService = (
  mockValues: Record<string, unknown> = {}
): IMockConfigService => {
  return {
    get: vi.fn().mockImplementation((key: string) => mockValues[key]),
  };
};

describe('ConfigService', () => {
  let configService: ConfigService;

  beforeAll(async () => {
    const mockConfigService = createMockConfigService({ PORT: 3001 });

    const app: TestingModule = await Test.createTestingModule({
      providers: [
        {
          provide: ConfigService,
          useValue: mockConfigService,
        },
      ],
    }).compile();

    configService = app.get<ConfigService>(ConfigService);
  });

  it('should be defined', () => {
    expect(configService).toBeDefined();
  });

  it('should return port value', () => {
    expect(configService.get<number>('PORT')).toStrictEqual(3001);
  });
});


================================================
FILE: apps/nestjs-backend/src/configs/env.validation.schema.ts
================================================
/* eslint-disable @typescript-eslint/naming-convention */
import Joi from 'joi';

export const envValidationSchema = Joi.object({
  NODE_ENV: Joi.string().valid('test', 'development', 'production').default('development'),
  PORT: Joi.number().default(3000),

  NEXTJS_DIR: Joi.string(),

  SWAGGER_DISABLED: Joi.string().equal('true').optional(),

  // logger
  LOG_LEVEL: Joi.string().valid('fatal', 'error', 'warn', 'info', 'debug', 'trace').default('info'),

  // database_url
  PRISMA_DATABASE_URL: Joi.string().required(),

  STORAGE_PREFIX: Joi.string().uri().optional(),

  PUBLIC_ORIGIN: Joi.string().uri().required(),

  // cache
  BACKEND_CACHE_PROVIDER: Joi.string().valid('memory', 'sqlite', 'redis').default('sqlite'),
  // cache-sqlite
  BACKEND_CACHE_SQLITE_URI: Joi.when('BACKEND_CACHE_PROVIDER', {
    is: 'sqlite',
    then: Joi.string()
      .pattern(/^sqlite:\/\//)
      .message('Cache `sqlite` the URI must start with the protocol `sqlite://`'),
  }),
  // cache-redis
  BACKEND_CACHE_REDIS_URI: Joi.when('BACKEND_CACHE_PROVIDER', {
    is: 'redis',
    then: Joi.string()
      .
Download .txt
Showing preview only (341K chars total). Download the full file or copy to clipboard to get everything.
gitextract_74g3z0fs/

├── .codeclimate.yml
├── .dockerignore
├── .gitattributes
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   ├── actions/
│   │   ├── docker-build-push/
│   │   │   └── action.yml
│   │   └── pnpm-install/
│   │       └── action.yml
│   └── workflows/
│       ├── docker-push.yml
│       ├── integration-tests.yml
│       ├── issue-id-check.yml
│       ├── linting.yml
│       ├── manual-preview.yml
│       ├── preview-cleanup.yml
│       ├── templates/
│       │   └── preview-template.yaml
│       ├── trigger-sync-to-ee.yml
│       ├── unit-tests.yml
│       ├── v2-benchmark-tests.yml
│       └── v2-core-tests.yml
├── .gitignore
├── .gitpod.yml
├── .husky/
│   ├── commit-msg
│   ├── install.mjs
│   └── pre-commit
├── .idea/
│   ├── modules.xml
│   └── teable.iml
├── .ncurc.yml
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── .vscode/
│   ├── extensions.json
│   ├── launch.json
│   └── settings.json
├── AGPL_LICENSE
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── agents.md
├── apps/
│   ├── nestjs-backend/
│   │   ├── .eslintrc.js
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── nestjs-backend.iml
│   │   ├── README.md
│   │   ├── nest-cli.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── app.module.ts
│   │   │   ├── bootstrap.ts
│   │   │   ├── cache/
│   │   │   │   ├── cache.module.ts
│   │   │   │   ├── cache.provider.ts
│   │   │   │   ├── cache.service.ts
│   │   │   │   └── types.ts
│   │   │   ├── configs/
│   │   │   │   ├── auth.config.ts
│   │   │   │   ├── base.config.ts
│   │   │   │   ├── bootstrap.config.ts
│   │   │   │   ├── cache.config.ts
│   │   │   │   ├── config.module.ts
│   │   │   │   ├── config.spec.ts
│   │   │   │   ├── env.validation.schema.ts
│   │   │   │   ├── logger.config.ts
│   │   │   │   ├── mail.config.ts
│   │   │   │   ├── oauth.config.ts
│   │   │   │   ├── storage.ts
│   │   │   │   ├── threshold.config.ts
│   │   │   │   └── trash.config.ts
│   │   │   ├── const.ts
│   │   │   ├── custom.exception.ts
│   │   │   ├── db-provider/
│   │   │   │   ├── aggregation-query/
│   │   │   │   │   ├── aggregation-function.abstract.ts
│   │   │   │   │   ├── aggregation-function.interface.ts
│   │   │   │   │   ├── aggregation-query.abstract.ts
│   │   │   │   │   ├── aggregation-query.interface.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   │   └── multiple-value-aggregation.adapter.spec.ts
│   │   │   │   │   │   ├── aggregation-function.postgres.ts
│   │   │   │   │   │   ├── aggregation-query.postgres.ts
│   │   │   │   │   │   ├── multiple-value/
│   │   │   │   │   │   │   └── multiple-value-aggregation.adapter.ts
│   │   │   │   │   │   └── single-value/
│   │   │   │   │   │       └── single-value-aggregation.adapter.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── aggregation-function.sqlite.ts
│   │   │   │   │       ├── aggregation-query.sqlite.ts
│   │   │   │   │       ├── multiple-value/
│   │   │   │   │       │   └── multiple-value-aggregation.adapter.ts
│   │   │   │   │       └── single-value/
│   │   │   │   │           └── single-value-aggregation.adapter.ts
│   │   │   │   ├── base-query/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── base-query.postgres.ts
│   │   │   │   │   └── base-query.sqlite.ts
│   │   │   │   ├── create-database-column-query/
│   │   │   │   │   ├── create-database-column-field-visitor.interface.ts
│   │   │   │   │   ├── create-database-column-field-visitor.postgres.ts
│   │   │   │   │   ├── create-database-column-field-visitor.sqlite.ts
│   │   │   │   │   ├── create-database-column-field.util.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── db.provider.interface.ts
│   │   │   │   ├── db.provider.ts
│   │   │   │   ├── drop-database-column-query/
│   │   │   │   │   ├── drop-database-column-field-visitor.interface.ts
│   │   │   │   │   ├── drop-database-column-field-visitor.postgres.ts
│   │   │   │   │   ├── drop-database-column-field-visitor.sqlite.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── duplicate-table/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── duplicate-attachment-table-query.abstract.ts
│   │   │   │   │   ├── duplicate-attachment-table-query.postgres.ts
│   │   │   │   │   ├── duplicate-attachment-table-query.sqlite.ts
│   │   │   │   │   ├── duplicate-query.postgres.ts
│   │   │   │   │   └── duplicate-query.sqlite.ts
│   │   │   │   ├── filter-query/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── field-reference.spec.ts
│   │   │   │   │   ├── cell-value-filter.abstract.ts
│   │   │   │   │   ├── cell-value-filter.interface.ts
│   │   │   │   │   ├── filter-query.abstract.ts
│   │   │   │   │   ├── filter-query.interface.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── cell-value-filter/
│   │   │   │   │   │   │   ├── cell-value-filter.postgres.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── multiple-value/
│   │   │   │   │   │   │   │   ├── multiple-boolean-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   ├── multiple-datetime-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   ├── multiple-json-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   ├── multiple-number-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   │   └── multiple-string-cell-value-filter.adapter.ts
│   │   │   │   │   │   │   └── single-value/
│   │   │   │   │   │   │       ├── boolean-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       ├── datetime-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       ├── json-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       ├── number-cell-value-filter.adapter.ts
│   │   │   │   │   │   │       └── string-cell-value-filter.adapter.ts
│   │   │   │   │   │   └── filter-query.postgres.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── cell-value-filter/
│   │   │   │   │       │   ├── cell-value-filter.sqlite.ts
│   │   │   │   │       │   ├── index.ts
│   │   │   │   │       │   ├── multiple-value/
│   │   │   │   │       │   │   ├── multiple-boolean-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   ├── multiple-datetime-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   ├── multiple-json-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   ├── multiple-number-cell-value-filter.adapter.ts
│   │   │   │   │       │   │   └── multiple-string-cell-value-filter.adapter.ts
│   │   │   │   │       │   └── single-value/
│   │   │   │   │       │       ├── boolean-cell-value-filter.adapter.ts
│   │   │   │   │       │       ├── datetime-cell-value-filter.adapter.ts
│   │   │   │   │       │       ├── json-cell-value-filter.adapter.ts
│   │   │   │   │       │       ├── number-cell-value-filter.adapter.ts
│   │   │   │   │       │       └── string-cell-value-filter.adapter.ts
│   │   │   │   │       └── filter-query.sqlite.ts
│   │   │   │   ├── generated-column-query/
│   │   │   │   │   ├── __snapshots__/
│   │   │   │   │   │   ├── formula-query.spec.ts.snap
│   │   │   │   │   │   ├── generated-column-query.spec.ts.snap
│   │   │   │   │   │   └── sql-conversion.spec.ts.snap
│   │   │   │   │   ├── generated-column-query-support-validator.spec.ts
│   │   │   │   │   ├── generated-column-query.abstract.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── generated-column-query-support-validator.postgres.ts
│   │   │   │   │   │   ├── generated-column-query.postgres.spec.ts
│   │   │   │   │   │   └── generated-column-query.postgres.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── generated-column-query-support-validator.sqlite.ts
│   │   │   │   │       ├── generated-column-query.sqlite.spec.ts
│   │   │   │   │       └── generated-column-query.sqlite.ts
│   │   │   │   ├── group-query/
│   │   │   │   │   ├── format-string.ts
│   │   │   │   │   ├── group-query.abstract.ts
│   │   │   │   │   ├── group-query.interface.ts
│   │   │   │   │   ├── group-query.postgres.ts
│   │   │   │   │   └── group-query.sqlite.ts
│   │   │   │   ├── index-query/
│   │   │   │   │   └── index-abstract-builder.ts
│   │   │   │   ├── integrity-query/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── integrity-query.postgres.ts
│   │   │   │   │   └── integrity-query.sqlite.ts
│   │   │   │   ├── postgres.provider.ts
│   │   │   │   ├── search-query/
│   │   │   │   │   ├── abstract.ts
│   │   │   │   │   ├── get-offset.ts
│   │   │   │   │   ├── search-index-builder.postgres.ts
│   │   │   │   │   ├── search-index-builder.sqlite.ts
│   │   │   │   │   ├── search-query.postgres.ts
│   │   │   │   │   ├── search-query.sqlite.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── select-query/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── select-query.postgres.spec.ts
│   │   │   │   │   │   └── select-query.postgres.ts
│   │   │   │   │   ├── select-query.abstract.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── select-query.sqlite.spec.ts
│   │   │   │   │       └── select-query.sqlite.ts
│   │   │   │   ├── sort-query/
│   │   │   │   │   ├── function/
│   │   │   │   │   │   ├── sort-function.abstract.ts
│   │   │   │   │   │   └── sort-function.interface.ts
│   │   │   │   │   ├── postgres/
│   │   │   │   │   │   ├── multiple-value/
│   │   │   │   │   │   │   ├── multiple-datetime-sort.adapter.ts
│   │   │   │   │   │   │   ├── multiple-json-sort.adapter.ts
│   │   │   │   │   │   │   └── multiple-number-sort.adapter.ts
│   │   │   │   │   │   ├── single-value/
│   │   │   │   │   │   │   ├── date-sort.adapter.ts
│   │   │   │   │   │   │   ├── json-sort.adapter.ts
│   │   │   │   │   │   │   └── string-sort.adapter.ts
│   │   │   │   │   │   ├── sort-query.function.ts
│   │   │   │   │   │   └── sort-query.postgres.ts
│   │   │   │   │   ├── sort-query.abstract.ts
│   │   │   │   │   ├── sort-query.interface.ts
│   │   │   │   │   └── sqlite/
│   │   │   │   │       ├── multiple-value/
│   │   │   │   │       │   ├── multiple-datetime-sort.adapter.ts
│   │   │   │   │       │   ├── multiple-json-sort.adapter.ts
│   │   │   │   │       │   └── multiple-number-sort.adapter.ts
│   │   │   │   │       ├── single-value/
│   │   │   │   │       │   ├── date-sort.adapter.ts
│   │   │   │   │       │   ├── json-sort.adapter.ts
│   │   │   │   │       │   └── string-sort.adapter.ts
│   │   │   │   │       ├── sort-query.function.ts
│   │   │   │   │       └── sort-query.sqlite.ts
│   │   │   │   ├── sqlite.provider.ts
│   │   │   │   └── utils/
│   │   │   │       ├── datetime-format.util.ts
│   │   │   │       ├── default-datetime-parse-pattern.spec.ts
│   │   │   │       ├── default-datetime-parse-pattern.ts
│   │   │   │       └── formula-param-metadata.util.ts
│   │   │   ├── event-emitter/
│   │   │   │   ├── decorators/
│   │   │   │   │   └── emit-controller-event.decorator.ts
│   │   │   │   ├── event-emitter.module.ts
│   │   │   │   ├── event-emitter.service.ts
│   │   │   │   ├── event-job/
│   │   │   │   │   ├── event-job.module.ts
│   │   │   │   │   └── fallback/
│   │   │   │   │       ├── event-emitter.ts
│   │   │   │   │       ├── fallback-queue.module.ts
│   │   │   │   │       ├── fallback-queue.service.ts
│   │   │   │   │       └── local-queue.provider.ts
│   │   │   │   ├── events/
│   │   │   │   │   ├── app/
│   │   │   │   │   │   └── app.event.ts
│   │   │   │   │   ├── base/
│   │   │   │   │   │   ├── base-node.event.ts
│   │   │   │   │   │   ├── base.event.ts
│   │   │   │   │   │   └── folder/
│   │   │   │   │   │       └── base.folder.event.ts
│   │   │   │   │   ├── core-event.ts
│   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   └── dashboard.event.ts
│   │   │   │   │   ├── event.enum.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── last-visit/
│   │   │   │   │   │   └── last-visit.event.ts
│   │   │   │   │   ├── op-event.ts
│   │   │   │   │   ├── space/
│   │   │   │   │   │   ├── collaborator.event.ts
│   │   │   │   │   │   └── space.event.ts
│   │   │   │   │   ├── table/
│   │   │   │   │   │   ├── button.event.ts
│   │   │   │   │   │   ├── field.event.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── record.event.ts
│   │   │   │   │   │   ├── table.event.ts
│   │   │   │   │   │   └── view.event.ts
│   │   │   │   │   ├── user/
│   │   │   │   │   │   └── user.event.ts
│   │   │   │   │   └── workflow/
│   │   │   │   │       └── workflow.event.ts
│   │   │   │   ├── interceptor/
│   │   │   │   │   └── event.Interceptor.ts
│   │   │   │   └── listeners/
│   │   │   │       ├── action-trigger.listener.ts
│   │   │   │       ├── attachment.listener.ts
│   │   │   │       ├── base-permission-update.listener.ts
│   │   │   │       ├── collaborator-notification.listener.ts
│   │   │   │       ├── pin.listener.ts
│   │   │   │       ├── record-history.listener.ts
│   │   │   │       └── trash.listener.ts
│   │   │   ├── features/
│   │   │   │   ├── access-token/
│   │   │   │   │   ├── access-token.controller.spec.ts
│   │   │   │   │   ├── access-token.controller.ts
│   │   │   │   │   ├── access-token.encryptor.ts
│   │   │   │   │   ├── access-token.module.ts
│   │   │   │   │   ├── access-token.service.spec.ts
│   │   │   │   │   └── access-token.service.ts
│   │   │   │   ├── aggregation/
│   │   │   │   │   ├── aggregation.module.ts
│   │   │   │   │   ├── aggregation.service.interface.ts
│   │   │   │   │   ├── aggregation.service.provider.ts
│   │   │   │   │   ├── aggregation.service.spec.ts
│   │   │   │   │   ├── aggregation.service.symbol.ts
│   │   │   │   │   ├── aggregation.service.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── open-api/
│   │   │   │   │       ├── aggregation-open-api.controller.spec.ts
│   │   │   │   │       ├── aggregation-open-api.controller.ts
│   │   │   │   │       ├── aggregation-open-api.module.ts
│   │   │   │   │       ├── aggregation-open-api.service.spec.ts
│   │   │   │   │       └── aggregation-open-api.service.ts
│   │   │   │   ├── ai/
│   │   │   │   │   ├── ai.controller.ts
│   │   │   │   │   ├── ai.module.ts
│   │   │   │   │   ├── ai.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   └── util.ts
│   │   │   │   ├── attachments/
│   │   │   │   │   ├── attachments-crop.module.ts
│   │   │   │   │   ├── attachments-crop.processor.ts
│   │   │   │   │   ├── attachments-storage.module.ts
│   │   │   │   │   ├── attachments-storage.service.ts
│   │   │   │   │   ├── attachments-table.module.ts
│   │   │   │   │   ├── attachments-table.service.spec.ts
│   │   │   │   │   ├── attachments-table.service.ts
│   │   │   │   │   ├── attachments.controller.spec.ts
│   │   │   │   │   ├── attachments.controller.ts
│   │   │   │   │   ├── attachments.module.ts
│   │   │   │   │   ├── attachments.service.spec.ts
│   │   │   │   │   ├── attachments.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   └── auth.guard.ts
│   │   │   │   │   ├── plugins/
│   │   │   │   │   │   ├── adapter.ts
│   │   │   │   │   │   ├── aliyun.ts
│   │   │   │   │   │   ├── local.spec.ts
│   │   │   │   │   │   ├── local.ts
│   │   │   │   │   │   ├── minio.ts
│   │   │   │   │   │   ├── s3.ts
│   │   │   │   │   │   ├── storage.module.ts
│   │   │   │   │   │   ├── storage.ts
│   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── auth/
│   │   │   │   │   ├── auth.controller.spec.ts
│   │   │   │   │   ├── auth.controller.ts
│   │   │   │   │   ├── auth.module.ts
│   │   │   │   │   ├── auth.service.spec.ts
│   │   │   │   │   ├── auth.service.ts
│   │   │   │   │   ├── decorators/
│   │   │   │   │   │   ├── allow-anonymous.decorator.ts
│   │   │   │   │   │   ├── base-node-permissions.decorator.ts
│   │   │   │   │   │   ├── disabled-permission.decorator.ts
│   │   │   │   │   │   ├── ensure-login.decorator.ts
│   │   │   │   │   │   ├── permissions.decorator.ts
│   │   │   │   │   │   ├── public.decorator.ts
│   │   │   │   │   │   ├── resource_meta.decorator.ts
│   │   │   │   │   │   └── token.decorator.ts
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   ├── auth.guard.ts
│   │   │   │   │   │   ├── base-node-permission.guard.ts
│   │   │   │   │   │   ├── github.guard.ts
│   │   │   │   │   │   ├── google.guard.ts
│   │   │   │   │   │   ├── local-auth.guard.ts
│   │   │   │   │   │   ├── oidc.guard.ts
│   │   │   │   │   │   ├── permission.guard.ts
│   │   │   │   │   │   └── social.guard.ts
│   │   │   │   │   ├── local-auth/
│   │   │   │   │   │   ├── local-auth.controller.ts
│   │   │   │   │   │   ├── local-auth.module.ts
│   │   │   │   │   │   └── local-auth.service.ts
│   │   │   │   │   ├── oauth/
│   │   │   │   │   │   └── oauth.store.ts
│   │   │   │   │   ├── permission.module.ts
│   │   │   │   │   ├── permission.service.spec.ts
│   │   │   │   │   ├── permission.service.ts
│   │   │   │   │   ├── session/
│   │   │   │   │   │   ├── session-handle.module.ts
│   │   │   │   │   │   ├── session-handle.service.ts
│   │   │   │   │   │   ├── session-store.service.spec.ts
│   │   │   │   │   │   ├── session-store.service.ts
│   │   │   │   │   │   ├── session.module.ts
│   │   │   │   │   │   ├── session.serializer.ts
│   │   │   │   │   │   └── session.service.ts
│   │   │   │   │   ├── social/
│   │   │   │   │   │   ├── controller.adapter.ts
│   │   │   │   │   │   ├── github/
│   │   │   │   │   │   │   ├── github.controller.ts
│   │   │   │   │   │   │   └── github.module.ts
│   │   │   │   │   │   ├── google/
│   │   │   │   │   │   │   ├── google.controller.ts
│   │   │   │   │   │   │   └── google.module.ts
│   │   │   │   │   │   ├── oidc/
│   │   │   │   │   │   │   ├── oidc.controller.ts
│   │   │   │   │   │   │   └── oidc.module.ts
│   │   │   │   │   │   └── social.module.ts
│   │   │   │   │   ├── strategies/
│   │   │   │   │   │   ├── access-token.passport.ts
│   │   │   │   │   │   ├── access-token.strategy.ts
│   │   │   │   │   │   ├── anonymous/
│   │   │   │   │   │   │   ├── anonymous.passport.ts
│   │   │   │   │   │   │   └── anonymous.strategy.ts
│   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   ├── github.strategy.ts
│   │   │   │   │   │   ├── google.strategy.ts
│   │   │   │   │   │   ├── jwt.strategy.ts
│   │   │   │   │   │   ├── local.strategy.spec.ts
│   │   │   │   │   │   ├── local.strategy.ts
│   │   │   │   │   │   ├── oidc.strategy.ts
│   │   │   │   │   │   ├── session.passport.ts
│   │   │   │   │   │   ├── session.strategy.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── turnstile/
│   │   │   │   │   │   ├── turnstile.module.ts
│   │   │   │   │   │   └── turnstile.service.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── base/
│   │   │   │   │   ├── BatchProcessor.class.ts
│   │   │   │   │   ├── base-duplicate.service.spec.ts
│   │   │   │   │   ├── base-duplicate.service.ts
│   │   │   │   │   ├── base-export.service.ts
│   │   │   │   │   ├── base-import-processor/
│   │   │   │   │   │   ├── base-import-attachments-csv.module.ts
│   │   │   │   │   │   ├── base-import-attachments-csv.processor.ts
│   │   │   │   │   │   ├── base-import-attachments.module.ts
│   │   │   │   │   │   ├── base-import-attachments.processor.ts
│   │   │   │   │   │   ├── base-import-csv.module.ts
│   │   │   │   │   │   ├── base-import-csv.processor.ts
│   │   │   │   │   │   ├── base-import-junction-csv.module.ts
│   │   │   │   │   │   └── base-import-junction.processor.ts
│   │   │   │   │   ├── base-import.service.ts
│   │   │   │   │   ├── base-query/
│   │   │   │   │   │   ├── base-query.service.ts
│   │   │   │   │   │   └── parse/
│   │   │   │   │   │       ├── aggregation.ts
│   │   │   │   │   │       ├── filter.ts
│   │   │   │   │   │       ├── group.ts
│   │   │   │   │   │       ├── order.ts
│   │   │   │   │   │       ├── select.ts
│   │   │   │   │   │       └── utils.ts
│   │   │   │   │   ├── base.controller.ts
│   │   │   │   │   ├── base.module.ts
│   │   │   │   │   ├── base.service.spec.ts
│   │   │   │   │   ├── base.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── db-connection.service.spec.ts
│   │   │   │   │   ├── db-connection.service.ts
│   │   │   │   │   ├── utils.spec.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── base-node/
│   │   │   │   │   ├── base-node.controller.ts
│   │   │   │   │   ├── base-node.listener.ts
│   │   │   │   │   ├── base-node.module.ts
│   │   │   │   │   ├── base-node.permission.helper.ts
│   │   │   │   │   ├── base-node.service.spec.ts
│   │   │   │   │   ├── base-node.service.ts
│   │   │   │   │   ├── folder/
│   │   │   │   │   │   ├── base-node-folder.controller.ts
│   │   │   │   │   │   ├── base-node-folder.module.ts
│   │   │   │   │   │   └── base-node-folder.service.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── base-share/
│   │   │   │   │   ├── base-share-auth.service.ts
│   │   │   │   │   ├── base-share-open.controller.ts
│   │   │   │   │   ├── base-share.controller.ts
│   │   │   │   │   ├── base-share.module.ts
│   │   │   │   │   ├── base-share.service.ts
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   ├── base-share-auth-local.guard.ts
│   │   │   │   │   │   ├── base-share-auth.guard.ts
│   │   │   │   │   │   └── constant.ts
│   │   │   │   │   └── strategies/
│   │   │   │   │       └── jwt.strategy.ts
│   │   │   │   ├── base-sql-executor/
│   │   │   │   │   ├── base-sql-executor.module.ts
│   │   │   │   │   ├── base-sql-executor.service.ts
│   │   │   │   │   ├── const.ts
│   │   │   │   │   ├── utils.spec.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── builtin-assets-init/
│   │   │   │   │   ├── builtin-assets-init.module.ts
│   │   │   │   │   ├── builtin-assets-init.service.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── calculation/
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── batch.service.spec.ts
│   │   │   │   │   ├── batch.service.ts
│   │   │   │   │   ├── calculation.module.ts
│   │   │   │   │   ├── field-calculation.service.spec.ts
│   │   │   │   │   ├── field-calculation.service.ts
│   │   │   │   │   ├── link.service.spec.ts
│   │   │   │   │   ├── link.service.ts
│   │   │   │   │   ├── reference.service.ts
│   │   │   │   │   ├── system-field.service.ts
│   │   │   │   │   └── utils/
│   │   │   │   │       ├── changes.spec.ts
│   │   │   │   │       ├── changes.ts
│   │   │   │   │       ├── compose-maps.spec.ts
│   │   │   │   │       ├── compose-maps.ts
│   │   │   │   │       ├── detect-link.spec.ts
│   │   │   │   │       ├── detect-link.ts
│   │   │   │   │       ├── dfs.spec.ts
│   │   │   │   │       ├── dfs.ts
│   │   │   │   │       └── name-console.ts
│   │   │   │   ├── canary/
│   │   │   │   │   ├── canary.module.ts
│   │   │   │   │   ├── canary.service.ts
│   │   │   │   │   ├── decorators/
│   │   │   │   │   │   └── use-v2-feature.decorator.ts
│   │   │   │   │   ├── guards/
│   │   │   │   │   │   └── v2-feature.guard.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── interceptors/
│   │   │   │   │       └── v2-indicator.interceptor.ts
│   │   │   │   ├── chat/
│   │   │   │   │   ├── chart-completion.ro.ts
│   │   │   │   │   ├── chat.controller.spec.ts
│   │   │   │   │   ├── chat.controller.ts
│   │   │   │   │   ├── chat.module.ts
│   │   │   │   │   ├── chat.service.spec.ts
│   │   │   │   │   └── chat.service.ts
│   │   │   │   ├── collaborator/
│   │   │   │   │   ├── collaborator.controller.spec.ts
│   │   │   │   │   ├── collaborator.controller.ts
│   │   │   │   │   ├── collaborator.module.ts
│   │   │   │   │   ├── collaborator.service.spec.ts
│   │   │   │   │   └── collaborator.service.ts
│   │   │   │   ├── comment/
│   │   │   │   │   ├── comment-open-api.controller.spec.ts
│   │   │   │   │   ├── comment-open-api.controller.ts
│   │   │   │   │   ├── comment-open-api.module.ts
│   │   │   │   │   └── comment-open-api.service.ts
│   │   │   │   ├── dashboard/
│   │   │   │   │   ├── dashboard.controller.spec.ts
│   │   │   │   │   ├── dashboard.controller.ts
│   │   │   │   │   ├── dashboard.module.ts
│   │   │   │   │   ├── dashboard.service.spec.ts
│   │   │   │   │   └── dashboard.service.ts
│   │   │   │   ├── data-loader/
│   │   │   │   │   ├── data-loader.module.ts
│   │   │   │   │   ├── data-loader.service.ts
│   │   │   │   │   └── resource/
│   │   │   │   │       ├── field-loader.service.ts
│   │   │   │   │       ├── table-common-loader.ts
│   │   │   │   │       ├── table-loader.service.ts
│   │   │   │   │       ├── utils.ts
│   │   │   │   │       └── view-loader.service.ts
│   │   │   │   ├── database-view/
│   │   │   │   │   ├── database-view.interface.ts
│   │   │   │   │   ├── database-view.module.ts
│   │   │   │   │   └── database-view.service.ts
│   │   │   │   ├── export/
│   │   │   │   │   ├── metrics/
│   │   │   │   │   │   ├── export-metrics.module.ts
│   │   │   │   │   │   ├── export-metrics.service.ts
│   │   │   │   │   │   └── export-tracing.service.ts
│   │   │   │   │   └── open-api/
│   │   │   │   │       ├── export-open-api.controller.ts
│   │   │   │   │       ├── export-open-api.module.ts
│   │   │   │   │       └── export-open-api.service.ts
│   │   │   │   ├── field/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── field-calculate/
│   │   │   │   │   │   ├── field-calculate.module.ts
│   │   │   │   │   │   ├── field-converting-link.service.spec.ts
│   │   │   │   │   │   ├── field-converting-link.service.ts
│   │   │   │   │   │   ├── field-converting.service.spec.ts
│   │   │   │   │   │   ├── field-converting.service.ts
│   │   │   │   │   │   ├── field-creating.service.spec.ts
│   │   │   │   │   │   ├── field-creating.service.ts
│   │   │   │   │   │   ├── field-deleting.service.spec.ts
│   │   │   │   │   │   ├── field-deleting.service.ts
│   │   │   │   │   │   ├── field-supplement.service.ts
│   │   │   │   │   │   ├── field-view-sync.service.ts
│   │   │   │   │   │   ├── formula-field.service.spec.ts
│   │   │   │   │   │   ├── formula-field.service.ts
│   │   │   │   │   │   └── link-field-query.service.ts
│   │   │   │   │   ├── field-duplicate/
│   │   │   │   │   │   ├── field-duplicate.module.ts
│   │   │   │   │   │   └── field-duplicate.service.ts
│   │   │   │   │   ├── field.module.ts
│   │   │   │   │   ├── field.service.spec.ts
│   │   │   │   │   ├── field.service.ts
│   │   │   │   │   ├── fields-utils.ts
│   │   │   │   │   ├── model/
│   │   │   │   │   │   ├── factory.spec.ts
│   │   │   │   │   │   ├── factory.ts
│   │   │   │   │   │   ├── field-base.ts
│   │   │   │   │   │   └── field-dto/
│   │   │   │   │   │       ├── attachment-field.dto.ts
│   │   │   │   │   │       ├── auto-number-field.dto.ts
│   │   │   │   │   │       ├── button-field.dto.ts
│   │   │   │   │   │       ├── checkbox-field.dto.ts
│   │   │   │   │   │       ├── conditional-rollup-field.dto.ts
│   │   │   │   │   │       ├── created-by-field.dto.ts
│   │   │   │   │   │       ├── created-time-field.dto.ts
│   │   │   │   │   │       ├── date-field.dto.ts
│   │   │   │   │   │       ├── formula-field.dto.ts
│   │   │   │   │   │       ├── last-modified-by-field.dto.ts
│   │   │   │   │   │       ├── last-modified-time-field.dto.ts
│   │   │   │   │   │       ├── link-field.dto.ts
│   │   │   │   │   │       ├── long-text-field.dto.ts
│   │   │   │   │   │       ├── multiple-select-field.dto.ts
│   │   │   │   │   │       ├── number-field.dto.ts
│   │   │   │   │   │       ├── rating-field.dto.ts
│   │   │   │   │   │       ├── rollup-field.dto.ts
│   │   │   │   │   │       ├── single-line-text-field.dto.ts
│   │   │   │   │   │       ├── single-select-field.dto.ts
│   │   │   │   │   │       └── user-field.dto.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── field-open-api-v2.service.spec.ts
│   │   │   │   │   │   ├── field-open-api-v2.service.ts
│   │   │   │   │   │   ├── field-open-api.controller.ts
│   │   │   │   │   │   ├── field-open-api.module.ts
│   │   │   │   │   │   ├── field-open-api.service.spec.ts
│   │   │   │   │   │   └── field-open-api.service.ts
│   │   │   │   │   └── util.ts
│   │   │   │   ├── graph/
│   │   │   │   │   ├── graph.module.ts
│   │   │   │   │   ├── graph.service.spec.ts
│   │   │   │   │   └── graph.service.ts
│   │   │   │   ├── health/
│   │   │   │   │   ├── health.controller.spec.ts
│   │   │   │   │   ├── health.controller.ts
│   │   │   │   │   ├── health.module.ts
│   │   │   │   │   └── health.service.ts
│   │   │   │   ├── import/
│   │   │   │   │   ├── metrics/
│   │   │   │   │   │   ├── import-metrics.module.ts
│   │   │   │   │   │   ├── import-metrics.service.ts
│   │   │   │   │   │   └── import-tracing.service.ts
│   │   │   │   │   └── open-api/
│   │   │   │   │       ├── NOTICE.md
│   │   │   │   │       ├── delimiter-stream.ts
│   │   │   │   │       ├── import-csv-chunk.module.ts
│   │   │   │   │       ├── import-csv-chunk.processor.ts
│   │   │   │   │       ├── import-csv.module.ts
│   │   │   │   │       ├── import-csv.processor.ts
│   │   │   │   │       ├── import-error-classifier.ts
│   │   │   │   │       ├── import-error-collector.ts
│   │   │   │   │       ├── import-open-api-v2.service.ts
│   │   │   │   │       ├── import-open-api.controller.ts
│   │   │   │   │       ├── import-open-api.module.ts
│   │   │   │   │       ├── import-open-api.service.ts
│   │   │   │   │       ├── import-result-manifest.ts
│   │   │   │   │       ├── import-result.processor.ts
│   │   │   │   │       └── import.class.ts
│   │   │   │   ├── integrity/
│   │   │   │   │   ├── foreign-key.service.ts
│   │   │   │   │   ├── integrity.controller.ts
│   │   │   │   │   ├── integrity.module.ts
│   │   │   │   │   ├── link-field.service.ts
│   │   │   │   │   ├── link-integrity.service.ts
│   │   │   │   │   └── unique-index.service.ts
│   │   │   │   ├── invitation/
│   │   │   │   │   ├── invitation.controller.spec.ts
│   │   │   │   │   ├── invitation.controller.ts
│   │   │   │   │   ├── invitation.module.ts
│   │   │   │   │   ├── invitation.service.spec.ts
│   │   │   │   │   └── invitation.service.ts
│   │   │   │   ├── mail-sender/
│   │   │   │   │   ├── mail-helpers.ts
│   │   │   │   │   ├── mail-sender.module.ts
│   │   │   │   │   ├── mail-sender.service.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── mail-sender-open-api.controller.ts
│   │   │   │   │   │   ├── mail-sender-open-api.module.ts
│   │   │   │   │   │   ├── mail-sender-open-api.service.ts
│   │   │   │   │   │   ├── mail-sender.merge.module.ts
│   │   │   │   │   │   └── mail-sender.merge.processor.ts
│   │   │   │   │   └── templates/
│   │   │   │   │       ├── pages/
│   │   │   │   │       │   └── normal.hbs
│   │   │   │   │       └── partials/
│   │   │   │   │           ├── collaborator-cell-tag.hbs
│   │   │   │   │           ├── collaborator-multi-row-tag.hbs
│   │   │   │   │           ├── common-body.hbs
│   │   │   │   │           ├── email-verify-code.hbs
│   │   │   │   │           ├── footer.hbs
│   │   │   │   │           ├── header.hbs
│   │   │   │   │           ├── html-body.hbs
│   │   │   │   │           ├── invite.hbs
│   │   │   │   │           ├── notify-merge-body.hbs
│   │   │   │   │           └── reset-password.hbs
│   │   │   │   ├── model/
│   │   │   │   │   ├── access-token.ts
│   │   │   │   │   ├── collaborator.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── model.module.ts
│   │   │   │   │   ├── setting.ts
│   │   │   │   │   ├── template.ts
│   │   │   │   │   └── user.ts
│   │   │   │   ├── next/
│   │   │   │   │   ├── next.controller.ts
│   │   │   │   │   ├── next.module.ts
│   │   │   │   │   ├── next.service.ts
│   │   │   │   │   └── plugin/
│   │   │   │   │       ├── plugin-proxy.middleware.ts
│   │   │   │   │       ├── plugin-proxy.module.ts
│   │   │   │   │       └── plugin.module.ts
│   │   │   │   ├── notification/
│   │   │   │   │   ├── notification.controller.ts
│   │   │   │   │   ├── notification.module.ts
│   │   │   │   │   └── notification.service.ts
│   │   │   │   ├── oauth/
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   └── oauth2-client.guard.ts
│   │   │   │   │   ├── oauth-server.controller.ts
│   │   │   │   │   ├── oauth-server.service.spec.ts
│   │   │   │   │   ├── oauth-server.service.ts
│   │   │   │   │   ├── oauth-tx-store.ts
│   │   │   │   │   ├── oauth.controller.spec.ts
│   │   │   │   │   ├── oauth.controller.ts
│   │   │   │   │   ├── oauth.module.ts
│   │   │   │   │   ├── oauth.service.spec.ts
│   │   │   │   │   ├── oauth.service.ts
│   │   │   │   │   ├── pkce.service.ts
│   │   │   │   │   ├── strategies/
│   │   │   │   │   │   ├── oauth2-client.strategies.ts
│   │   │   │   │   │   └── oauth2-pkce-client.strategy.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── organization/
│   │   │   │   │   ├── organization.controller.ts
│   │   │   │   │   └── organization.module.ts
│   │   │   │   ├── pin/
│   │   │   │   │   ├── pin.controller.ts
│   │   │   │   │   ├── pin.module.ts
│   │   │   │   │   └── pin.service.ts
│   │   │   │   ├── plugin/
│   │   │   │   │   ├── official/
│   │   │   │   │   │   ├── chart/
│   │   │   │   │   │   │   ├── plugin-chart.controller.ts
│   │   │   │   │   │   │   ├── plugin-chart.module.ts
│   │   │   │   │   │   │   └── plugin-chart.service.ts
│   │   │   │   │   │   ├── config/
│   │   │   │   │   │   │   ├── chart.ts
│   │   │   │   │   │   │   ├── sheet-form-view.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   └── official-plugin-init.service.ts
│   │   │   │   │   ├── plugin-auth.service.ts
│   │   │   │   │   ├── plugin.controller.spec.ts
│   │   │   │   │   ├── plugin.controller.ts
│   │   │   │   │   ├── plugin.module.ts
│   │   │   │   │   ├── plugin.service.spec.ts
│   │   │   │   │   ├── plugin.service.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── plugin-context-menu/
│   │   │   │   │   ├── plugin-context-menu.controller.ts
│   │   │   │   │   ├── plugin-context-menu.module.ts
│   │   │   │   │   └── plugin-context-menu.service.ts
│   │   │   │   ├── plugin-panel/
│   │   │   │   │   ├── plugin-panel.controller.ts
│   │   │   │   │   ├── plugin-panel.module.ts
│   │   │   │   │   └── plugin-panel.service.ts
│   │   │   │   ├── record/
│   │   │   │   │   ├── computed/
│   │   │   │   │   │   ├── computed.module.ts
│   │   │   │   │   │   └── services/
│   │   │   │   │   │       ├── computed-dependency-collector.service.ts
│   │   │   │   │   │       ├── computed-evaluator.service.ts
│   │   │   │   │   │       ├── computed-orchestrator.service.ts
│   │   │   │   │   │       ├── computed-pagination.strategy.ts
│   │   │   │   │   │       ├── computed-utils.ts
│   │   │   │   │   │       ├── link-cascade-resolver.ts
│   │   │   │   │   │       └── record-computed-update.service.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── field-key.pipe.ts
│   │   │   │   │   │   ├── record-open-api-v2.service.spec.ts
│   │   │   │   │   │   ├── record-open-api-v2.service.ts
│   │   │   │   │   │   ├── record-open-api.controller.ts
│   │   │   │   │   │   ├── record-open-api.module.ts
│   │   │   │   │   │   ├── record-open-api.service.spec.ts
│   │   │   │   │   │   ├── record-open-api.service.ts
│   │   │   │   │   │   ├── record-undo-redo-service.ts
│   │   │   │   │   │   └── tql.pipe.ts
│   │   │   │   │   ├── query-builder/
│   │   │   │   │   │   ├── field-cte-visitor.ts
│   │   │   │   │   │   ├── field-formatting-visitor.ts
│   │   │   │   │   │   ├── field-select-visitor.ts
│   │   │   │   │   │   ├── field-select.type.ts
│   │   │   │   │   │   ├── formula-support-generated-column-validator.spec.ts
│   │   │   │   │   │   ├── formula-support-generated-column-validator.ts
│   │   │   │   │   │   ├── formula-validation.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── providers/
│   │   │   │   │   │   │   ├── pg-record-query-dialect.spec.ts
│   │   │   │   │   │   │   ├── pg-record-query-dialect.ts
│   │   │   │   │   │   │   └── sqlite-record-query-dialect.ts
│   │   │   │   │   │   ├── record-query-builder.interface.ts
│   │   │   │   │   │   ├── record-query-builder.manager.ts
│   │   │   │   │   │   ├── record-query-builder.module.ts
│   │   │   │   │   │   ├── record-query-builder.provider.ts
│   │   │   │   │   │   ├── record-query-builder.service.ts
│   │   │   │   │   │   ├── record-query-builder.symbol.ts
│   │   │   │   │   │   ├── record-query-builder.util.ts
│   │   │   │   │   │   ├── record-query-dialect.interface.ts
│   │   │   │   │   │   └── sql-conversion.visitor.ts
│   │   │   │   │   ├── record-modify/
│   │   │   │   │   │   ├── record-create.service.ts
│   │   │   │   │   │   ├── record-delete.service.ts
│   │   │   │   │   │   ├── record-duplicate.service.ts
│   │   │   │   │   │   ├── record-modify.module.ts
│   │   │   │   │   │   ├── record-modify.service.ts
│   │   │   │   │   │   ├── record-modify.shared.service.ts
│   │   │   │   │   │   └── record-update.service.ts
│   │   │   │   │   ├── record-permission.service.ts
│   │   │   │   │   ├── record-query.service.ts
│   │   │   │   │   ├── record.module.ts
│   │   │   │   │   ├── record.service.spec.ts
│   │   │   │   │   ├── record.service.ts
│   │   │   │   │   ├── type.ts
│   │   │   │   │   ├── typecast.validate.spec.ts
│   │   │   │   │   ├── typecast.validate.ts
│   │   │   │   │   └── user-name.listener.service.ts
│   │   │   │   ├── selection/
│   │   │   │   │   ├── selection.controller.spec.ts
│   │   │   │   │   ├── selection.controller.ts
│   │   │   │   │   ├── selection.module.ts
│   │   │   │   │   ├── selection.service.spec.ts
│   │   │   │   │   └── selection.service.ts
│   │   │   │   ├── setting/
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── admin-open-api.controller.ts
│   │   │   │   │   │   ├── admin-open-api.module.ts
│   │   │   │   │   │   ├── admin-open-api.service.ts
│   │   │   │   │   │   ├── setting-open-api.controller.ts
│   │   │   │   │   │   ├── setting-open-api.module.ts
│   │   │   │   │   │   └── setting-open-api.service.ts
│   │   │   │   │   ├── setting.module.ts
│   │   │   │   │   └── setting.service.ts
│   │   │   │   ├── share/
│   │   │   │   │   ├── guard/
│   │   │   │   │   │   ├── auth.guard.ts
│   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   ├── link-view.decorator.ts
│   │   │   │   │   │   ├── share-auth-local.guard.ts
│   │   │   │   │   │   └── submit.decorator.ts
│   │   │   │   │   ├── share-auth.module.ts
│   │   │   │   │   ├── share-auth.service.ts
│   │   │   │   │   ├── share-socket.service.ts
│   │   │   │   │   ├── share.controller.spec.ts
│   │   │   │   │   ├── share.controller.ts
│   │   │   │   │   ├── share.module.ts
│   │   │   │   │   ├── share.service.spec.ts
│   │   │   │   │   ├── share.service.ts
│   │   │   │   │   └── strategies/
│   │   │   │   │       └── jwt.strategy.ts
│   │   │   │   ├── space/
│   │   │   │   │   ├── space.controller.spec.ts
│   │   │   │   │   ├── space.controller.ts
│   │   │   │   │   ├── space.module.ts
│   │   │   │   │   ├── space.service.spec.ts
│   │   │   │   │   ├── space.service.ts
│   │   │   │   │   └── template-space-init/
│   │   │   │   │       └── template-space.init.service.ts
│   │   │   │   ├── table/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── table-open-api-v2.mapper.spec.ts
│   │   │   │   │   │   ├── table-open-api-v2.mapper.ts
│   │   │   │   │   │   ├── table-open-api-v2.service.spec.ts
│   │   │   │   │   │   ├── table-open-api-v2.service.ts
│   │   │   │   │   │   ├── table-open-api.controller.ts
│   │   │   │   │   │   ├── table-open-api.module.ts
│   │   │   │   │   │   ├── table-open-api.server.spec.ts
│   │   │   │   │   │   ├── table-open-api.service.spec.ts
│   │   │   │   │   │   ├── table-open-api.service.ts
│   │   │   │   │   │   ├── table.pipe.helper.ts
│   │   │   │   │   │   └── table.pipe.ts
│   │   │   │   │   ├── table-duplicate.service.ts
│   │   │   │   │   ├── table-index.service.ts
│   │   │   │   │   ├── table-permission.service.ts
│   │   │   │   │   ├── table.module.ts
│   │   │   │   │   ├── table.service.spec.ts
│   │   │   │   │   └── table.service.ts
│   │   │   │   ├── table-domain/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── table-domain-query.module.ts
│   │   │   │   │   └── table-domain-query.service.ts
│   │   │   │   ├── template/
│   │   │   │   │   ├── template-open-api.controller.spec.ts
│   │   │   │   │   ├── template-open-api.controller.ts
│   │   │   │   │   ├── template-open-api.module.ts
│   │   │   │   │   ├── template-open-api.service.ts
│   │   │   │   │   └── template-permalink.service.ts
│   │   │   │   ├── trash/
│   │   │   │   │   ├── listener/
│   │   │   │   │   │   └── table-trash.listener.ts
│   │   │   │   │   ├── trash.controller.ts
│   │   │   │   │   ├── trash.module.ts
│   │   │   │   │   ├── trash.service.ts
│   │   │   │   │   ├── v2-table-trash.service.spec.ts
│   │   │   │   │   ├── v2-table-trash.service.ts
│   │   │   │   │   └── v2-trash-record-name.ts
│   │   │   │   ├── undo-redo/
│   │   │   │   │   ├── open-api/
│   │   │   │   │   │   ├── undo-redo.controller.ts
│   │   │   │   │   │   ├── undo-redo.module.ts
│   │   │   │   │   │   └── undo-redo.service.ts
│   │   │   │   │   ├── operations/
│   │   │   │   │   │   ├── convert-field-v2.operation.ts
│   │   │   │   │   │   ├── convert-field.operation.ts
│   │   │   │   │   │   ├── create-fields.operation.ts
│   │   │   │   │   │   ├── create-records.operation.ts
│   │   │   │   │   │   ├── create-view.operation.ts
│   │   │   │   │   │   ├── delete-fields.operation.ts
│   │   │   │   │   │   ├── delete-records.operation.ts
│   │   │   │   │   │   ├── delete-view.operation.ts
│   │   │   │   │   │   ├── paste-selection.operation.ts
│   │   │   │   │   │   ├── update-records-order.operation.ts
│   │   │   │   │   │   ├── update-records.operation.ts
│   │   │   │   │   │   └── update-view.operation.ts
│   │   │   │   │   └── stack/
│   │   │   │   │       ├── undo-redo-operation.service.ts
│   │   │   │   │       ├── undo-redo-stack.module.ts
│   │   │   │   │       └── undo-redo-stack.service.ts
│   │   │   │   ├── user/
│   │   │   │   │   ├── delete-user/
│   │   │   │   │   │   ├── delete-user.module.ts
│   │   │   │   │   │   └── delete-user.service.ts
│   │   │   │   │   ├── last-visit/
│   │   │   │   │   │   ├── last-visit.controller.ts
│   │   │   │   │   │   ├── last-visit.module.ts
│   │   │   │   │   │   └── last-visit.service.ts
│   │   │   │   │   ├── user.controller.spec.ts
│   │   │   │   │   ├── user.controller.ts
│   │   │   │   │   ├── user.module.ts
│   │   │   │   │   ├── user.service.spec.ts
│   │   │   │   │   └── user.service.ts
│   │   │   │   ├── v2/
│   │   │   │   │   ├── v2-action-trigger.service.spec.ts
│   │   │   │   │   ├── v2-action-trigger.service.ts
│   │   │   │   │   ├── v2-audit-log.constants.ts
│   │   │   │   │   ├── v2-command-bus-tracing.middleware.ts
│   │   │   │   │   ├── v2-container.service.ts
│   │   │   │   │   ├── v2-create-table-compat.constants.ts
│   │   │   │   │   ├── v2-execution-context.factory.ts
│   │   │   │   │   ├── v2-field-delete-compat.constants.ts
│   │   │   │   │   ├── v2-field-delete-compat.service.ts
│   │   │   │   │   ├── v2-logger.adapter.ts
│   │   │   │   │   ├── v2-openapi.controller.ts
│   │   │   │   │   ├── v2-projection-registrar.ts
│   │   │   │   │   ├── v2-query-bus-tracing.middleware.ts
│   │   │   │   │   ├── v2-record-history.service.ts
│   │   │   │   │   ├── v2-tracer.adapter.ts
│   │   │   │   │   ├── v2-undo-redo.constants.ts
│   │   │   │   │   ├── v2-user-rename-propagation.service.spec.ts
│   │   │   │   │   ├── v2-user-rename-propagation.service.ts
│   │   │   │   │   ├── v2.controller.ts
│   │   │   │   │   └── v2.module.ts
│   │   │   │   └── view/
│   │   │   │       ├── constant.ts
│   │   │   │       ├── model/
│   │   │   │       │   ├── calendar-view.dto.ts
│   │   │   │       │   ├── factory.ts
│   │   │   │       │   ├── form-view.dto.ts
│   │   │   │       │   ├── gallery-view.dto.ts
│   │   │   │       │   ├── grid-view.dto.ts
│   │   │   │       │   ├── kanban-view.dto.ts
│   │   │   │       │   └── plugin-view.dto.ts
│   │   │   │       ├── open-api/
│   │   │   │       │   ├── view-open-api-v2.service.ts
│   │   │   │       │   ├── view-open-api.controller.ts
│   │   │   │       │   ├── view-open-api.module.ts
│   │   │   │       │   ├── view-open-api.service.spec.ts
│   │   │   │       │   └── view-open-api.service.ts
│   │   │   │       ├── utils/
│   │   │   │       │   └── derive-frozen-fields.ts
│   │   │   │       ├── view.module.ts
│   │   │   │       ├── view.service.spec.ts
│   │   │   │       └── view.service.ts
│   │   │   ├── filter/
│   │   │   │   └── global-exception.filter.ts
│   │   │   ├── global/
│   │   │   │   ├── global.module.ts
│   │   │   │   ├── init-bootstrap.provider.ts
│   │   │   │   ├── init-bootstrap.service.ts
│   │   │   │   └── knex/
│   │   │   │       ├── index.ts
│   │   │   │       ├── knex.extend.ts
│   │   │   │       └── knex.module.ts
│   │   │   ├── index.ts
│   │   │   ├── instrument.ts
│   │   │   ├── logger/
│   │   │   │   └── logger.module.ts
│   │   │   ├── middleware/
│   │   │   │   └── request-info.middleware.ts
│   │   │   ├── observability/
│   │   │   │   ├── observability.module.ts
│   │   │   │   └── profiling/
│   │   │   │       ├── profiler.module.ts
│   │   │   │       └── profiler.service.ts
│   │   │   ├── performance-cache/
│   │   │   │   ├── cache-metrics/
│   │   │   │   │   ├── metrics.module.ts
│   │   │   │   │   └── metrics.service.ts
│   │   │   │   ├── decorator.ts
│   │   │   │   ├── generate-keys.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── module.ts
│   │   │   │   ├── performance-cache.decorator.spec.ts
│   │   │   │   ├── service.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── utils.ts
│   │   │   ├── share-db/
│   │   │   │   ├── auth.middleware.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── metrics/
│   │   │   │   │   ├── realtime-metrics.module.ts
│   │   │   │   │   └── realtime-metrics.service.ts
│   │   │   │   ├── readonly/
│   │   │   │   │   ├── field-readonly.service.ts
│   │   │   │   │   ├── readonly.module.ts
│   │   │   │   │   ├── readonly.service.ts
│   │   │   │   │   ├── record-readonly.service.ts
│   │   │   │   │   ├── table-readonly.service.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── view-readonly.service.ts
│   │   │   │   ├── repair-attachment-op/
│   │   │   │   │   ├── repair-attachment-op.module.ts
│   │   │   │   │   └── repair-attachment-op.service.ts
│   │   │   │   ├── share-db.adapter.ts
│   │   │   │   ├── share-db.module.ts
│   │   │   │   ├── share-db.service.ts
│   │   │   │   ├── share-db.spec.ts
│   │   │   │   ├── sharedb-redis.pubsub.ts
│   │   │   │   └── utils.ts
│   │   │   ├── swagger.ts
│   │   │   ├── tracing/
│   │   │   │   ├── base-tracing.service.ts
│   │   │   │   ├── decorators/
│   │   │   │   │   └── span.ts
│   │   │   │   └── route-tracing.interceptor.ts
│   │   │   ├── tracing.ts
│   │   │   ├── types/
│   │   │   │   ├── cls.ts
│   │   │   │   ├── data-loader.ts
│   │   │   │   ├── i18n.generated.ts
│   │   │   │   ├── redlock.d.ts
│   │   │   │   └── session.ts
│   │   │   ├── utils/
│   │   │   │   ├── code-generate.ts
│   │   │   │   ├── convert-view-vo-attachment-url.ts
│   │   │   │   ├── date-to-iso.ts
│   │   │   │   ├── db-helpers.ts
│   │   │   │   ├── db-validation-error.ts
│   │   │   │   ├── encryptor.ts
│   │   │   │   ├── exception-parse.ts
│   │   │   │   ├── extract-field-reference.ts
│   │   │   │   ├── file-utils.spec.ts
│   │   │   │   ├── file-utils.ts
│   │   │   │   ├── filter-has-me.ts
│   │   │   │   ├── filter.spec.ts
│   │   │   │   ├── filter.ts
│   │   │   │   ├── generate-thumbnail-path.ts
│   │   │   │   ├── get-max-level-role.ts
│   │   │   │   ├── i18n.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── is-not-hidden-field.ts
│   │   │   │   ├── is-user-or-link.ts
│   │   │   │   ├── major-field-keys-changed.spec.ts
│   │   │   │   ├── major-field-keys-changed.ts
│   │   │   │   ├── metadata.ts
│   │   │   │   ├── name-conversion.ts
│   │   │   │   ├── postgres-regex-escape.ts
│   │   │   │   ├── retry-decorator.spec.ts
│   │   │   │   ├── retry-decorator.ts
│   │   │   │   ├── second.ts
│   │   │   │   ├── sql-like-escape.ts
│   │   │   │   ├── string-hash.ts
│   │   │   │   ├── timing.ts
│   │   │   │   ├── update-order.spec.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   └── value-convert.ts
│   │   │   ├── worker/
│   │   │   │   └── parse.ts
│   │   │   ├── ws/
│   │   │   │   ├── ws.gateway.dev.spec.ts
│   │   │   │   ├── ws.gateway.dev.ts
│   │   │   │   ├── ws.gateway.spec.ts
│   │   │   │   ├── ws.gateway.ts
│   │   │   │   ├── ws.module.ts
│   │   │   │   ├── ws.service.spec.ts
│   │   │   │   └── ws.service.ts
│   │   │   ├── zod.validation.pipe.spec.ts
│   │   │   └── zod.validation.pipe.ts
│   │   ├── test/
│   │   │   ├── access-token.e2e-spec.ts
│   │   │   ├── aggregation-search-count-question-mark.e2e-spec.ts
│   │   │   ├── aggregation-search.e2e-spec.ts
│   │   │   ├── aggregation.e2e-spec.ts
│   │   │   ├── attachment.e2e-spec.ts
│   │   │   ├── audit-user-fields.e2e-spec.ts
│   │   │   ├── auth.e2e-spec.ts
│   │   │   ├── auto-number.e2e-spec.ts
│   │   │   ├── base-duplicate.e2e-spec.ts
│   │   │   ├── base-export-sentry.e2e-spec.ts
│   │   │   ├── base-node-folder.e2e-spec.ts
│   │   │   ├── base-node.e2e-spec.ts
│   │   │   ├── base-query.e2e-spec.ts
│   │   │   ├── base-share.e2e-spec.ts
│   │   │   ├── base-sql-executor.e2e-spec.ts
│   │   │   ├── base.e2e-spec.ts
│   │   │   ├── basic-link.e2e-spec.ts
│   │   │   ├── bidirectional-formula-link.e2e-spec.ts
│   │   │   ├── canary.e2e-spec.ts
│   │   │   ├── collaboration.e2e-spec.ts
│   │   │   ├── comment-count-collapsed-group.e2e-spec.ts
│   │   │   ├── comment.e2e-spec.ts
│   │   │   ├── comprehensive-aggregation.e2e-spec.ts
│   │   │   ├── comprehensive-field-filter.e2e-spec.ts
│   │   │   ├── comprehensive-field-sort.e2e-spec.ts
│   │   │   ├── computed-orchestrator.e2e-spec.ts
│   │   │   ├── computed-user-field.e2e-spec.ts
│   │   │   ├── computed-version-regression.e2e-spec.ts
│   │   │   ├── conditional-lookup.e2e-spec.ts
│   │   │   ├── conditional-rollup.e2e-spec.ts
│   │   │   ├── convert-field-transaction.e2e-spec.ts
│   │   │   ├── credit.e2e-spec.ts
│   │   │   ├── dashboard.e2e-spec.ts
│   │   │   ├── data-helpers/
│   │   │   │   ├── 20x-link.ts
│   │   │   │   ├── 20x.ts
│   │   │   │   └── caces/
│   │   │   │       ├── aggregation-query/
│   │   │   │       │   ├── checkbox-field.ts
│   │   │   │       │   ├── date-field.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── multiple-select-field.ts
│   │   │   │       │   ├── number-field.ts
│   │   │   │       │   ├── single-select-field.ts
│   │   │   │       │   ├── text-field.ts
│   │   │   │       │   └── user-field.ts
│   │   │   │       ├── record-filter-query/
│   │   │   │       │   ├── checkbox-field.ts
│   │   │   │       │   ├── date-field/
│   │   │   │       │   │   ├── date-field.ts
│   │   │   │       │   │   ├── date-range-sets.ts
│   │   │   │       │   │   ├── index.ts
│   │   │   │       │   │   ├── is-after-sets.ts
│   │   │   │       │   │   ├── is-before-sets.ts
│   │   │   │       │   │   ├── is-not-sets.ts
│   │   │   │       │   │   ├── is-on-or-after-sets.ts
│   │   │   │       │   │   ├── is-on-or-before-sets.ts
│   │   │   │       │   │   ├── is-sets.ts
│   │   │   │       │   │   ├── is-with-in-sets.ts
│   │   │   │       │   │   └── utils.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── multiple-select-field.ts
│   │   │   │       │   ├── number-field.ts
│   │   │   │       │   ├── single-select-field.ts
│   │   │   │       │   ├── text-field.ts
│   │   │   │       │   └── user-field.ts
│   │   │   │       └── view-default-share-meta.ts
│   │   │   ├── db-connection.e2e-spec.ts
│   │   │   ├── dead-lock.e2e-spec.ts
│   │   │   ├── delete-field.e2e-spec.ts
│   │   │   ├── duplicate-field-transaction.e2e-spec.ts
│   │   │   ├── field-calculation.e2e-spec.ts
│   │   │   ├── field-converting.e2e-spec.ts
│   │   │   ├── field-delete-references.e2e-spec.ts
│   │   │   ├── field-duplicate.e2e-spec.ts
│   │   │   ├── field-physical-columns.e2e-spec.ts
│   │   │   ├── field-reference.e2e-spec.ts
│   │   │   ├── field-view-sync.e2e-spec.ts
│   │   │   ├── field.e2e-spec.ts
│   │   │   ├── filter.e2e-spec.ts
│   │   │   ├── formula-boolean-numeric-coercion.e2e-spec.ts
│   │   │   ├── formula-conditional-lookup-numeric-if.e2e-spec.ts
│   │   │   ├── formula-conditional-numeric-cast-regression.e2e-spec.ts
│   │   │   ├── formula-counta-lookup-ancestry.e2e-spec.ts
│   │   │   ├── formula-countall-user-link-lookup.e2e-spec.ts
│   │   │   ├── formula-datetime-format.e2e-spec.ts
│   │   │   ├── formula-datetime-parse-update.e2e-spec.ts
│   │   │   ├── formula-delete-chain.e2e-spec.ts
│   │   │   ├── formula-field.e2e-spec.ts
│   │   │   ├── formula-fromnow-tonow.e2e-spec.ts
│   │   │   ├── formula-int-search-link-regression.e2e-spec.ts
│   │   │   ├── formula-left-array-flatten.e2e-spec.ts
│   │   │   ├── formula-lookup-sum-regression.e2e-spec.ts
│   │   │   ├── formula-meta.e2e-spec.ts
│   │   │   ├── formula-metadata-coercion.e2e-spec.ts
│   │   │   ├── formula-numeric-blank-regression.e2e-spec.ts
│   │   │   ├── formula-single-select-regression.e2e-spec.ts
│   │   │   ├── formula-timezone-convert.e2e-spec.ts
│   │   │   ├── formula.e2e-spec.ts
│   │   │   ├── generated-column-blank-if.e2e-spec.ts
│   │   │   ├── generated-column-numeric-coercion.e2e-spec.ts
│   │   │   ├── graph.e2e-spec.ts
│   │   │   ├── group.e2e-spec.ts
│   │   │   ├── import-base.e2e-spec.ts
│   │   │   ├── integrity.e2e-spec.ts
│   │   │   ├── invitation.e2e-spec.ts
│   │   │   ├── large-table-operations.e2e-spec.ts
│   │   │   ├── legacy-created-time-create.e2e-spec.ts
│   │   │   ├── lin-field-not-null.e2e-spec.ts
│   │   │   ├── link-api.e2e-spec.ts
│   │   │   ├── link-bulk-conversion.e2e-spec.ts
│   │   │   ├── link-events.e2e-spec.ts
│   │   │   ├── link-field-null-handling.e2e-spec.ts
│   │   │   ├── link-formula-if-boolean-context.e2e-spec.ts
│   │   │   ├── link-formula-recursion.e2e-spec.ts
│   │   │   ├── link-multi-config-toggle-collaboration.e2e-spec.ts
│   │   │   ├── link-multi-config-toggle.e2e-spec.ts
│   │   │   ├── link-view-user-filter.e2e-spec.ts
│   │   │   ├── lookup-cross-base-tiering.e2e-spec.ts
│   │   │   ├── lookup-nested-link-lookup.e2e-spec.ts
│   │   │   ├── lookup-to-link.e2e-spec.ts
│   │   │   ├── lookup.e2e-spec.ts
│   │   │   ├── mail.e2e-spec.ts
│   │   │   ├── nested-lookup-formula.e2e-spec.ts
│   │   │   ├── nested-lookup.e2e-spec.ts
│   │   │   ├── not-null-validation.e2e-spec.ts
│   │   │   ├── number-precision.e2e-spec.ts
│   │   │   ├── oauth-server.e2e-spec.ts
│   │   │   ├── oauth.e2e-spec.ts
│   │   │   ├── one-many-formula-symmetric-link.e2e-spec.ts
│   │   │   ├── opportunity-rollup-regression.e2e-spec.ts
│   │   │   ├── order-update.e2e-spec.ts
│   │   │   ├── performance.e2e-spec.ts
│   │   │   ├── personal-income-tax.e2e-spec.ts
│   │   │   ├── pin.e2e-spec.ts
│   │   │   ├── plugin-chart.e2e-spec.ts
│   │   │   ├── plugin-context-menu.e2e-spec.ts
│   │   │   ├── plugin-panel.e2e-spec.ts
│   │   │   ├── plugin.e2e-spec.ts
│   │   │   ├── record-bulk-delete.e2e-spec.ts
│   │   │   ├── record-delete-link-cleanup.e2e-spec.ts
│   │   │   ├── record-field-key.e2e-spec.ts
│   │   │   ├── record-filter-lookup-number-param.e2e-spec.ts
│   │   │   ├── record-filter-lookup-string-question-mark.e2e-spec.ts
│   │   │   ├── record-filter-query-issues.e2e-spec.ts
│   │   │   ├── record-filter-query.e2e-spec.ts
│   │   │   ├── record-group-datetime-timezone.e2e-spec.ts
│   │   │   ├── record-history.e2e-spec.ts
│   │   │   ├── record-link-select-query.e2e-spec.ts
│   │   │   ├── record-query-builder.e2e-spec.ts
│   │   │   ├── record-search-query.e2e-spec.ts
│   │   │   ├── record-search-question-mark.e2e-spec.ts
│   │   │   ├── record-typecast.e2e-spec.ts
│   │   │   ├── record-unary-filter.e2e-spec.ts
│   │   │   ├── record.e2e-spec.ts
│   │   │   ├── rollup.e2e-spec.ts
│   │   │   ├── scheduled-computing.e2e-spec.ts
│   │   │   ├── select-formula-numeric-coercion.e2e-spec.ts
│   │   │   ├── selection.e2e-spec.ts
│   │   │   ├── set-column-meta.e2e-spec.ts
│   │   │   ├── share-socket.e2e-spec.ts
│   │   │   ├── share.e2e-spec.ts
│   │   │   ├── sort.e2e-spec.ts
│   │   │   ├── space.e2e-spec.ts
│   │   │   ├── table-concurrency.e2e-spec.ts
│   │   │   ├── table-duplicate.e2e-spec.ts
│   │   │   ├── table-export.e2e-spec.ts
│   │   │   ├── table-import.e2e-spec.ts
│   │   │   ├── table-lifecycle-full.e2e-spec.ts
│   │   │   ├── table-trash.e2e-spec.ts
│   │   │   ├── table.e2e-spec.ts
│   │   │   ├── template-cover-crop.e2e-spec.ts
│   │   │   ├── template-preview.e2e-spec.ts
│   │   │   ├── template.e2e-spec.ts
│   │   │   ├── trash.e2e-spec.ts
│   │   │   ├── undo-redo.e2e-spec.ts
│   │   │   ├── user-last-visit.e2e-spec.ts
│   │   │   ├── utils/
│   │   │   │   ├── axios-instance/
│   │   │   │   │   ├── anonymous-user.ts
│   │   │   │   │   └── new-user.ts
│   │   │   │   ├── data.generator.ts
│   │   │   │   ├── event-promise.ts
│   │   │   │   ├── field-mock.ts
│   │   │   │   ├── get-error.ts
│   │   │   │   ├── init-app.ts
│   │   │   │   ├── record-mock.ts
│   │   │   │   ├── seed.ts
│   │   │   │   ├── testing-logger.ts
│   │   │   │   └── wait.ts
│   │   │   ├── v2-action-trigger-field-conversion.e2e-spec.ts
│   │   │   ├── v2-update-records.e2e-spec.ts
│   │   │   ├── view-option.e2e-spec.ts
│   │   │   ├── view.e2e-spec.ts
│   │   │   └── waitlist.e2e-spec.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── vitest-bench.config.ts
│   │   ├── vitest-e2e.config.ts
│   │   ├── vitest-e2e.setup.ts
│   │   ├── vitest.config.ts
│   │   ├── webpack.config.js
│   │   ├── webpack.dev.js
│   │   └── webpack.swc.js
│   ├── nextjs-app/
│   │   ├── .escheckrc
│   │   ├── .eslintrc.js
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── nextjs-app.iml
│   │   ├── .size-limit.js
│   │   ├── README.md
│   │   ├── babel.config.backup.js
│   │   ├── components.json
│   │   ├── config/
│   │   │   └── tests/
│   │   │       ├── AppTestProviders.tsx
│   │   │       ├── I18nextTestStubProvider.tsx
│   │   │       ├── ReactSvgrMock.tsx
│   │   │       ├── setupVitest.ts
│   │   │       └── test-utils.tsx
│   │   ├── e2e/
│   │   │   └── pages/
│   │   │       ├── index/
│   │   │       │   ├── index-chinese.spec.ts
│   │   │       │   └── index.spec.ts
│   │   │       └── system/
│   │   │           └── 404.spec.ts
│   │   ├── instrumentation.ts
│   │   ├── lint-staged.config.js
│   │   ├── next-i18next.config.js
│   │   ├── next.config.js
│   │   ├── package.json
│   │   ├── playwright.config.ts
│   │   ├── postcss.config.js
│   │   ├── public/
│   │   │   ├── images/
│   │   │   │   └── favicon/
│   │   │   │       ├── .readme
│   │   │   │       ├── browserconfig.xml
│   │   │   │       └── site.webmanifest
│   │   │   ├── robots.txt
│   │   │   └── streamsaver/
│   │   │       ├── mitm.html
│   │   │       └── sw.js
│   │   ├── sentry.client.config.ts
│   │   ├── sentry.server.config.ts
│   │   ├── src/
│   │   │   ├── AppProviders.tsx
│   │   │   ├── backend/
│   │   │   │   └── api/
│   │   │   │       └── rest/
│   │   │   │           ├── axios.ts
│   │   │   │           ├── get-user.ts
│   │   │   │           └── ssr-api.ts
│   │   │   ├── components/
│   │   │   │   ├── Banner.tsx
│   │   │   │   ├── Guide.tsx
│   │   │   │   ├── Metrics.tsx
│   │   │   │   ├── RouterProgress.tsx
│   │   │   │   ├── Selector.tsx
│   │   │   │   ├── TeableLogo.tsx
│   │   │   │   ├── changelog/
│   │   │   │   │   ├── ChangelogNotification.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── google-ads.tsx
│   │   │   │   ├── layout/
│   │   │   │   │   ├── MainFooter.tsx
│   │   │   │   │   ├── MainLayout.tsx
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── MainLayout.test.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   └── store/
│   │   │   │       ├── guide.ts
│   │   │   │       └── index.ts
│   │   │   ├── features/
│   │   │   │   ├── app/
│   │   │   │   │   ├── automation/
│   │   │   │   │   │   ├── Pages.tsx
│   │   │   │   │   │   └── workflow-panel/
│   │   │   │   │   │       ├── WorkFlowPanel.tsx
│   │   │   │   │   │       ├── WorkFlowPanelModal.tsx
│   │   │   │   │   │       └── useWorkFlowPaneStore.ts
│   │   │   │   │   ├── base/
│   │   │   │   │   │   └── CommunityPage.tsx
│   │   │   │   │   ├── base-node/
│   │   │   │   │   │   ├── BasePage.tsx
│   │   │   │   │   │   ├── DashBoardPage.tsx
│   │   │   │   │   │   ├── TablePage.tsx
│   │   │   │   │   │   ├── WorkflowPage.tsx
│   │   │   │   │   │   ├── helper.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── blocks/
│   │   │   │   │   │   ├── App.tsx
│   │   │   │   │   │   ├── AuthorityMatrix.tsx
│   │   │   │   │   │   ├── Error.tsx
│   │   │   │   │   │   ├── admin/
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── setting/
│   │   │   │   │   │   │   │   ├── SettingPage.tsx
│   │   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   │   ├── Branding.tsx
│   │   │   │   │   │   │   │   │   ├── BrandingLogo.tsx
│   │   │   │   │   │   │   │   │   ├── ConfigurationList.tsx
│   │   │   │   │   │   │   │   │   ├── CopyInstance.tsx
│   │   │   │   │   │   │   │   │   ├── ai-config/
│   │   │   │   │   │   │   │   │   │   ├── AIConfigurationStatus.tsx
│   │   │   │   │   │   │   │   │   │   ├── AIControlCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AIModelPreferencesCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AIProviderCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AISetupWizard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AiFormWizard.tsx
│   │   │   │   │   │   │   │   │   │   ├── AiModelSelect.tsx
│   │   │   │   │   │   │   │   │   │   ├── BatchTestModels.tsx
│   │   │   │   │   │   │   │   │   │   ├── CodingModels.tsx
│   │   │   │   │   │   │   │   │   │   ├── DefaultModelsStep.tsx
│   │   │   │   │   │   │   │   │   │   ├── GatewayModelPickerDialog.tsx
│   │   │   │   │   │   │   │   │   │   ├── GatewayModelsStep.tsx
│   │   │   │   │   │   │   │   │   │   ├── LLMApiConfigStep.tsx
│   │   │   │   │   │   │   │   │   │   ├── LlmProviderForm.tsx
│   │   │   │   │   │   │   │   │   │   ├── LlmproviderManage.tsx
│   │   │   │   │   │   │   │   │   │   ├── SetupStepCard.tsx
│   │   │   │   │   │   │   │   │   │   ├── TestButton.tsx
│   │   │   │   │   │   │   │   │   │   ├── ai-model-select/
│   │   │   │   │   │   │   │   │   │   │   ├── GatewayModelOption.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ModelSelectTrigger.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ProviderModelOption.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   │   │   │   │   ├── useGatewayModels.ts
│   │   │   │   │   │   │   │   │   │   │   ├── useModelCategories.ts
│   │   │   │   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   │   │   │   │   ├── gateway-models-step/
│   │   │   │   │   │   │   │   │   │   │   ├── AddModelDialog.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ModelCard.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── ModelSearchPopover.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── PricingSection.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── QuickAddButtons.tsx
│   │   │   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   │   │   │   └── utils.tsx
│   │   │   │   │   │   │   │   │   ├── canary/
│   │   │   │   │   │   │   │   │   │   ├── CanarySettings.tsx
│   │   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   ├── mail-config/
│   │   │   │   │   │   │   │   │   │   ├── MailConfig.tsx
│   │   │   │   │   │   │   │   │   │   └── MailConfigForm.tsx
│   │   │   │   │   │   │   │   │   └── waitlist/
│   │   │   │   │   │   │   │   │       ├── InviteCodeManage.tsx
│   │   │   │   │   │   │   │   │       └── WaitlistManage.tsx
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   └── template/
│   │   │   │   │   │   │       ├── TemplatePage.tsx
│   │   │   │   │   │   │       ├── components/
│   │   │   │   │   │   │       │   ├── BaseSelectPanel.tsx
│   │   │   │   │   │   │       │   ├── CategorySettingDialog.tsx
│   │   │   │   │   │   │       │   ├── MarkdownEditor.tsx
│   │   │   │   │   │   │       │   ├── MarkdownPreviewButton.tsx
│   │   │   │   │   │   │       │   ├── TemplateCategorySelect.tsx
│   │   │   │   │   │   │       │   ├── TemplateCover.tsx
│   │   │   │   │   │   │       │   ├── TemplateTable.tsx
│   │   │   │   │   │   │       │   ├── TemplateTooltips.tsx
│   │   │   │   │   │   │       │   ├── TextEditor.tsx
│   │   │   │   │   │   │       │   ├── TextEditorDialog.tsx
│   │   │   │   │   │   │       │   ├── index.ts
│   │   │   │   │   │   │       │   └── upload-panel/
│   │   │   │   │   │   │       │       ├── Process.tsx
│   │   │   │   │   │   │       │       ├── TemplateCoverPreview.tsx
│   │   │   │   │   │   │       │       ├── Trigger.tsx
│   │   │   │   │   │   │       │       ├── UploadPanel.tsx
│   │   │   │   │   │   │       │       └── index.ts
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── base/
│   │   │   │   │   │   │   ├── BasePermissionListener.tsx
│   │   │   │   │   │   │   ├── base-node/
│   │   │   │   │   │   │   │   ├── BaseNodeContext.ts
│   │   │   │   │   │   │   │   ├── BaseNodeProvider.tsx
│   │   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │   │       ├── helper.spec.ts
│   │   │   │   │   │   │   │       ├── helper.ts
│   │   │   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │   │   │       ├── useBaseNode.ts
│   │   │   │   │   │   │   │       ├── useBaseNodeContext.ts
│   │   │   │   │   │   │   │       └── useBaseNodeCrud.ts
│   │   │   │   │   │   │   ├── base-side-bar/
│   │   │   │   │   │   │   │   ├── BaseNodeAddResourceButton.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeMore.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeShareIndicator.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeStarButton.tsx
│   │   │   │   │   │   │   │   ├── BaseNodeTree.tsx
│   │   │   │   │   │   │   │   ├── BasePageRouter.tsx
│   │   │   │   │   │   │   │   ├── BaseSideBar.tsx
│   │   │   │   │   │   │   │   ├── BaseSidebarHeaderLeft.tsx
│   │   │   │   │   │   │   │   ├── NodeShareContent.tsx
│   │   │   │   │   │   │   │   ├── NodeShareDialog.tsx
│   │   │   │   │   │   │   │   └── QuickAction.tsx
│   │   │   │   │   │   │   ├── duplicate/
│   │   │   │   │   │   │   │   ├── DuplicateBaseModal.tsx
│   │   │   │   │   │   │   │   ├── TemplateCreateBaseModal.tsx
│   │   │   │   │   │   │   │   ├── useDuplicateBaseStore.ts
│   │   │   │   │   │   │   │   ├── useTemplateCreateBaseStore.ts
│   │   │   │   │   │   │   │   └── useTemplateMonitor.ts
│   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │   │       └── useLastVisitBase.ts
│   │   │   │   │   │   ├── billing/
│   │   │   │   │   │   │   ├── SpaceSubscriptionModal.tsx
│   │   │   │   │   │   │   ├── useSpaceSubscriptionMonitor.ts
│   │   │   │   │   │   │   └── useSpaceSubscriptionStore.ts
│   │   │   │   │   │   ├── chart/
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── Chart.tsx
│   │   │   │   │   │   │   │   ├── ChartProvider.tsx
│   │   │   │   │   │   │   │   ├── EnvProvider.tsx
│   │   │   │   │   │   │   │   └── chart/
│   │   │   │   │   │   │   │       ├── ChartLayout.tsx
│   │   │   │   │   │   │   │       ├── ChartPage.tsx
│   │   │   │   │   │   │   │       ├── ChartQuery.tsx
│   │   │   │   │   │   │   │       ├── chart-config/
│   │   │   │   │   │   │   │       │   ├── ChartForm.tsx
│   │   │   │   │   │   │   │       │   ├── ChartSetting.tsx
│   │   │   │   │   │   │   │       │   ├── QueryStatus.tsx
│   │   │   │   │   │   │   │       │   ├── TypeSelector.tsx
│   │   │   │   │   │   │   │       │   ├── common/
│   │   │   │   │   │   │   │       │   │   ├── AxisDisplayBaseContent.tsx
│   │   │   │   │   │   │   │       │   │   ├── ColumnSelector.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboLineStyleEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboTypeEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboXAxisDisplayEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ComboYAisxDisplayEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── ConfigItem.tsx
│   │   │   │   │   │   │   │       │   │   ├── GoalLineEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── NumberInput.tsx
│   │   │   │   │   │   │   │       │   │   ├── PaddingEditor.tsx
│   │   │   │   │   │   │   │       │   │   ├── SwitchEditor.tsx
│   │   │   │   │   │   │   │       │   │   └── YAxisPositionEditor.tsx
│   │   │   │   │   │   │   │       │   └── form/
│   │   │   │   │   │   │   │       │       ├── AreaForm.tsx
│   │   │   │   │   │   │   │       │       ├── BarForm.tsx
│   │   │   │   │   │   │   │       │       ├── ComboForm.tsx
│   │   │   │   │   │   │   │       │       ├── ComboXAxisEditor.tsx
│   │   │   │   │   │   │   │       │       ├── ComboYAxisEditor.tsx
│   │   │   │   │   │   │   │       │       ├── LineForm.tsx
│   │   │   │   │   │   │   │       │       ├── PieForm.tsx
│   │   │   │   │   │   │   │       │       ├── TableForm.tsx
│   │   │   │   │   │   │   │       │       └── utils.ts
│   │   │   │   │   │   │   │       ├── chart-show/
│   │   │   │   │   │   │   │       │   ├── ChartDisplay.tsx
│   │   │   │   │   │   │   │       │   ├── combo/
│   │   │   │   │   │   │   │       │   │   ├── Combo.tsx
│   │   │   │   │   │   │   │       │   │   ├── TooltipItem.tsx
│   │   │   │   │   │   │   │       │   │   └── useComboConfig.ts
│   │   │   │   │   │   │   │       │   ├── pie/
│   │   │   │   │   │   │   │       │   │   ├── Pie.tsx
│   │   │   │   │   │   │   │       │   │   ├── PieLegendContent.tsx
│   │   │   │   │   │   │   │       │   │   ├── usePieConfig.tsx
│   │   │   │   │   │   │   │       │   │   └── useRefObserve.ts
│   │   │   │   │   │   │   │       │   ├── table/
│   │   │   │   │   │   │   │       │   │   └── ChartTable.tsx
│   │   │   │   │   │   │   │       │   ├── types.ts
│   │   │   │   │   │   │   │       │   └── utils.ts
│   │   │   │   │   │   │   │       └── utils.ts
│   │   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   │   ├── globals.css
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── useBaseQueryData.ts
│   │   │   │   │   │   │   │   ├── useEnv.ts
│   │   │   │   │   │   │   │   ├── useFilterNumberColumns.ts
│   │   │   │   │   │   │   │   ├── usePluginInstall.ts
│   │   │   │   │   │   │   │   └── useUIConfig.ts
│   │   │   │   │   │   │   ├── query.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   │   └── Dashboard.tsx
│   │   │   │   │   │   ├── db-connection/
│   │   │   │   │   │   │   ├── Panel.tsx
│   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │       ├── index.ts
│   │   │   │   │   │   │       └── useDbConnection.ts
│   │   │   │   │   │   ├── design/
│   │   │   │   │   │   │   ├── BaseDetail.tsx
│   │   │   │   │   │   │   ├── Design.tsx
│   │   │   │   │   │   │   ├── TableDetail.tsx
│   │   │   │   │   │   │   ├── TableTabs.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── Actions.tsx
│   │   │   │   │   │   │   │   ├── FieldPropertyEditor.tsx
│   │   │   │   │   │   │   │   └── Integrity.tsx
│   │   │   │   │   │   │   └── data-table/
│   │   │   │   │   │   │       ├── DataTable.tsx
│   │   │   │   │   │   │       ├── FieldGraph.tsx
│   │   │   │   │   │   │       └── useDataColumns.tsx
│   │   │   │   │   │   ├── erd/
│   │   │   │   │   │   │   ├── BaseErd.tsx
│   │   │   │   │   │   │   ├── BaseErdTableNode.tsx
│   │   │   │   │   │   │   ├── CustomMakers.tsx
│   │   │   │   │   │   │   ├── DynamicBaseErd.tsx
│   │   │   │   │   │   │   └── SelfConnectingEdge.tsx
│   │   │   │   │   │   ├── graph/
│   │   │   │   │   │   │   ├── DynamicFieldGraph.tsx
│   │   │   │   │   │   │   ├── FieldGraph.tsx
│   │   │   │   │   │   │   ├── ProgressBar.tsx
│   │   │   │   │   │   │   └── usePlan.ts
│   │   │   │   │   │   ├── import-table/
│   │   │   │   │   │   │   ├── TableImport.tsx
│   │   │   │   │   │   │   ├── UrlPanel.tsx
│   │   │   │   │   │   │   ├── field-config-panel/
│   │   │   │   │   │   │   │   ├── CollapsePanel.tsx
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   ├── inplace-panel/
│   │   │   │   │   │   │   │   │   ├── FieldSelector.tsx
│   │   │   │   │   │   │   │   │   ├── InplaceFieldConfigPanel.tsx
│   │   │   │   │   │   │   │   │   └── InplacePreviewColumn.tsx
│   │   │   │   │   │   │   │   └── new-create-panel/
│   │   │   │   │   │   │   │       ├── FieldConfigPanel.tsx
│   │   │   │   │   │   │   │       └── PreviewColumn.tsx
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── upload-panel/
│   │   │   │   │   │   │       ├── Process.tsx
│   │   │   │   │   │   │       ├── Trigger.tsx
│   │   │   │   │   │   │       ├── UploadPanel.tsx
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── setting/
│   │   │   │   │   │   │   ├── SettingRight.tsx
│   │   │   │   │   │   │   ├── SettingRightTitle.tsx
│   │   │   │   │   │   │   ├── access-token/
│   │   │   │   │   │   │   │   ├── AccessTokenList.tsx
│   │   │   │   │   │   │   │   ├── PersonAccessTokenForm.tsx
│   │   │   │   │   │   │   │   ├── PersonAccessTokenPage.tsx
│   │   │   │   │   │   │   │   └── form/
│   │   │   │   │   │   │   │       ├── AccessList.tsx
│   │   │   │   │   │   │   │       ├── AccessSelect.tsx
│   │   │   │   │   │   │   │       ├── AccessTokenForm.tsx
│   │   │   │   │   │   │   │       ├── AccessTokenFormEdit.tsx
│   │   │   │   │   │   │   │       ├── ExpirationSelect.tsx
│   │   │   │   │   │   │   │       └── RefreshToken.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── FormItem.tsx
│   │   │   │   │   │   │   │   ├── FormPageLayout.tsx
│   │   │   │   │   │   │   │   ├── RequireCom.tsx
│   │   │   │   │   │   │   │   └── ScopesSelect.tsx
│   │   │   │   │   │   │   ├── oauth-app/
│   │   │   │   │   │   │   │   ├── OAuthAppDecisionPage.tsx
│   │   │   │   │   │   │   │   ├── OAuthAppPage.tsx
│   │   │   │   │   │   │   │   ├── constant.ts
│   │   │   │   │   │   │   │   └── manage/
│   │   │   │   │   │   │   │       ├── CallbackEditor.tsx
│   │   │   │   │   │   │   │       ├── List.tsx
│   │   │   │   │   │   │   │       ├── OAuthAppEdit.tsx
│   │   │   │   │   │   │   │       ├── OAuthAppForm.tsx
│   │   │   │   │   │   │   │       └── OAuthAppNew.tsx
│   │   │   │   │   │   │   ├── plugin/
│   │   │   │   │   │   │   │   ├── MarkDownEditor.tsx
│   │   │   │   │   │   │   │   ├── PluginEdit.tsx
│   │   │   │   │   │   │   │   ├── PluginList.tsx
│   │   │   │   │   │   │   │   ├── PluginNew.tsx
│   │   │   │   │   │   │   │   ├── PluginPage.tsx
│   │   │   │   │   │   │   │   ├── component/
│   │   │   │   │   │   │   │   │   ├── JsonEditor.tsx
│   │   │   │   │   │   │   │   │   ├── LogoEditor.tsx
│   │   │   │   │   │   │   │   │   ├── NewSecret.tsx
│   │   │   │   │   │   │   │   │   ├── PositionSelector.tsx
│   │   │   │   │   │   │   │   │   ├── StatusBadge.tsx
│   │   │   │   │   │   │   │   │   └── StatusDot.tsx
│   │   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │   │       └── useStatusStatic.ts
│   │   │   │   │   │   │   └── query-builder/
│   │   │   │   │   │   │       ├── AIContextPanel.tsx
│   │   │   │   │   │   │       ├── FilterBuilder.tsx
│   │   │   │   │   │   │       ├── PreviewScript.tsx
│   │   │   │   │   │   │       ├── PreviewTable.tsx
│   │   │   │   │   │   │       ├── QueryBuilder.tsx
│   │   │   │   │   │   │       ├── SearchBuilder.tsx
│   │   │   │   │   │   │       ├── SortBuilder.tsx
│   │   │   │   │   │   │       ├── ViewBuilder.tsx
│   │   │   │   │   │   │       └── useTransformFieldKey.ts
│   │   │   │   │   │   ├── share/
│   │   │   │   │   │   │   ├── base/
│   │   │   │   │   │   │   │   ├── BaseShareAuthPage.tsx
│   │   │   │   │   │   │   │   └── share-base-ssr.ts
│   │   │   │   │   │   │   └── view/
│   │   │   │   │   │   │       ├── AuthPage.tsx
│   │   │   │   │   │   │       ├── EmbedFooter.tsx
│   │   │   │   │   │   │       ├── ShareTablePermissionProvider.tsx
│   │   │   │   │   │   │       ├── ShareView.tsx
│   │   │   │   │   │   │       ├── ShareViewPage.tsx
│   │   │   │   │   │   │       └── component/
│   │   │   │   │   │   │           ├── calendar/
│   │   │   │   │   │   │           │   ├── CalendarView.tsx
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── form/
│   │   │   │   │   │   │           │   ├── FormView.tsx
│   │   │   │   │   │   │           │   └── FormViewBase.tsx
│   │   │   │   │   │   │           ├── gallery/
│   │   │   │   │   │   │           │   ├── GalleryView.tsx
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── grid/
│   │   │   │   │   │   │           │   ├── GridView.tsx
│   │   │   │   │   │   │           │   ├── GridViewBase.tsx
│   │   │   │   │   │   │           │   ├── aggregation/
│   │   │   │   │   │   │           │   │   ├── AggregationProvider.tsx
│   │   │   │   │   │   │           │   │   ├── GroupPointProvider.tsx
│   │   │   │   │   │   │           │   │   └── index.ts
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Sort.tsx
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── kanban/
│   │   │   │   │   │   │           │   ├── KanbanView.tsx
│   │   │   │   │   │   │           │   └── toolbar/
│   │   │   │   │   │   │           │       ├── Toolbar.tsx
│   │   │   │   │   │   │           │       └── index.ts
│   │   │   │   │   │   │           ├── plugin/
│   │   │   │   │   │   │           │   └── SharePluginView.tsx
│   │   │   │   │   │   │           └── share-view-filter/
│   │   │   │   │   │   │               ├── FilterUser.tsx
│   │   │   │   │   │   │               ├── ShareViewFilter.tsx
│   │   │   │   │   │   │               ├── filter-link/
│   │   │   │   │   │   │               │   ├── FilterLink.tsx
│   │   │   │   │   │   │               │   ├── FilterLinkSelectList.tsx
│   │   │   │   │   │   │               │   ├── FilterLinkSelectTrigger.tsx
│   │   │   │   │   │   │               │   └── index.ts
│   │   │   │   │   │   │               └── index.ts
│   │   │   │   │   │   ├── space/
│   │   │   │   │   │   │   ├── BaseCard.tsx
│   │   │   │   │   │   │   ├── BaseItem.tsx
│   │   │   │   │   │   │   ├── BaseList.tsx
│   │   │   │   │   │   │   ├── ColorBg.tsx
│   │   │   │   │   │   │   ├── DraggableBaseGrid.tsx
│   │   │   │   │   │   │   ├── DraggableBaseRows.tsx
│   │   │   │   │   │   │   ├── FreshSettingGuideDialog.tsx
│   │   │   │   │   │   │   ├── NoBasesPlaceholder.tsx
│   │   │   │   │   │   │   ├── NoSpacesPlaceholder.tsx
│   │   │   │   │   │   │   ├── RecentlyBase.tsx
│   │   │   │   │   │   │   ├── SharedBasePage.tsx
│   │   │   │   │   │   │   ├── SpaceCard.tsx
│   │   │   │   │   │   │   ├── SpaceInnerPage.tsx
│   │   │   │   │   │   │   ├── SpacePage.tsx
│   │   │   │   │   │   │   ├── component/
│   │   │   │   │   │   │   │   ├── BaseActionTrigger.tsx
│   │   │   │   │   │   │   │   ├── EditableSpaceSelect.tsx
│   │   │   │   │   │   │   │   ├── SpaceActionTrigger.tsx
│   │   │   │   │   │   │   │   └── upload-panel/
│   │   │   │   │   │   │   │       ├── ImportLogPanel.tsx
│   │   │   │   │   │   │   │       ├── Process.tsx
│   │   │   │   │   │   │   │       ├── Trigger.tsx
│   │   │   │   │   │   │   │       ├── UploadPanel.tsx
│   │   │   │   │   │   │   │       ├── UploadPanelDialog.tsx
│   │   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   └── useSpaceList.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── space-side-bar/
│   │   │   │   │   │   │   │   ├── ItemButton.tsx
│   │   │   │   │   │   │   │   ├── PinItem.tsx
│   │   │   │   │   │   │   │   ├── PinList.tsx
│   │   │   │   │   │   │   │   ├── SpaceInnerSideBar.tsx
│   │   │   │   │   │   │   │   ├── SpaceItem.tsx
│   │   │   │   │   │   │   │   ├── SpaceList.tsx
│   │   │   │   │   │   │   │   ├── SpaceOperation.tsx
│   │   │   │   │   │   │   │   ├── SpaceQuickSearch.tsx
│   │   │   │   │   │   │   │   ├── SpaceSideBar.tsx
│   │   │   │   │   │   │   │   ├── SpaceSwitcher.tsx
│   │   │   │   │   │   │   │   └── StarButton.tsx
│   │   │   │   │   │   │   ├── useBaseList.tsx
│   │   │   │   │   │   │   ├── usePinMap.ts
│   │   │   │   │   │   │   └── useSpaceListOrdered.tsx
│   │   │   │   │   │   ├── space-setting/
│   │   │   │   │   │   │   ├── SpaceInnerSettingModal.tsx
│   │   │   │   │   │   │   ├── collaborator/
│   │   │   │   │   │   │   │   ├── CollaboratorPage.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── general/
│   │   │   │   │   │   │   │   ├── GeneralPage.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── integration/
│   │   │   │   │   │   │       └── components/
│   │   │   │   │   │   │           ├── AiConfig.tsx
│   │   │   │   │   │   │           ├── IntegrationCard.tsx
│   │   │   │   │   │   │           └── index.ts
│   │   │   │   │   │   ├── table/
│   │   │   │   │   │   │   ├── FailAlert.tsx
│   │   │   │   │   │   │   ├── Table.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── use-aggregations-query.ts
│   │   │   │   │   │   │   │   ├── use-import-status.ts
│   │   │   │   │   │   │   │   ├── use-row-count-query.ts
│   │   │   │   │   │   │   │   └── use-view-error-handler.tsx
│   │   │   │   │   │   │   ├── store/
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   └── use-locked-view-tip-store.ts
│   │   │   │   │   │   │   └── table-header/
│   │   │   │   │   │   │       ├── AddPluginView.tsx
│   │   │   │   │   │   │       ├── AddView.tsx
│   │   │   │   │   │   │       ├── BaseShare.tsx
│   │   │   │   │   │   │       ├── Collaborators.tsx
│   │   │   │   │   │   │       ├── LockedViewTip.tsx
│   │   │   │   │   │   │       ├── TableHeader.tsx
│   │   │   │   │   │   │       ├── TableInfo.tsx
│   │   │   │   │   │   │       └── publish-base/
│   │   │   │   │   │   │           ├── AppPublishContext.tsx
│   │   │   │   │   │   │           ├── NodeSelect.tsx
│   │   │   │   │   │   │           ├── NodeTreeSelect.tsx
│   │   │   │   │   │   │           ├── PublishBaseDialog.tsx
│   │   │   │   │   │   │           └── UnpublishedAppsDialog.tsx
│   │   │   │   │   │   ├── table-list/
│   │   │   │   │   │   │   ├── DraggableList.tsx
│   │   │   │   │   │   │   ├── NoDraggableList.tsx
│   │   │   │   │   │   │   ├── TableList.tsx
│   │   │   │   │   │   │   ├── TableListItem.tsx
│   │   │   │   │   │   │   ├── TableOperation.tsx
│   │   │   │   │   │   │   ├── useAddTable.ts
│   │   │   │   │   │   │   └── useTableHref.tsx
│   │   │   │   │   │   ├── trash/
│   │   │   │   │   │   │   ├── BaseTrashPage.tsx
│   │   │   │   │   │   │   ├── SpaceInnerTrashModal.tsx
│   │   │   │   │   │   │   ├── SpaceTrashPage.tsx
│   │   │   │   │   │   │   └── components/
│   │   │   │   │   │   │       ├── TableTrash.tsx
│   │   │   │   │   │   │       └── TableTrashDialog.tsx
│   │   │   │   │   │   └── view/
│   │   │   │   │   │       ├── View.tsx
│   │   │   │   │   │       ├── calendar/
│   │   │   │   │   │       │   ├── CalendarView.tsx
│   │   │   │   │   │       │   ├── CalendarViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── AddDateFieldDialog.tsx
│   │   │   │   │   │       │   │   ├── AddEventButton.tsx
│   │   │   │   │   │       │   │   ├── Calendar.tsx
│   │   │   │   │   │       │   │   ├── CalendarConfig.tsx
│   │   │   │   │   │       │   │   ├── EventList.tsx
│   │   │   │   │   │       │   │   ├── EventListContainer.tsx
│   │   │   │   │   │       │   │   └── EventMenu.tsx
│   │   │   │   │   │       │   ├── context/
│   │   │   │   │   │       │   │   ├── CalendarContext.ts
│   │   │   │   │   │       │   │   ├── CalendarProvider.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useCalendar.ts
│   │   │   │   │   │       │   │   ├── useCalendarFields.ts
│   │   │   │   │   │       │   │   └── useEventMenuStore.ts
│   │   │   │   │   │       │   ├── type.ts
│   │   │   │   │   │       │   └── util.ts
│   │   │   │   │   │       ├── constant.ts
│   │   │   │   │   │       ├── field/
│   │   │   │   │   │       │   ├── FieldSetting.tsx
│   │   │   │   │   │       │   └── useFieldSettingStore.ts
│   │   │   │   │   │       ├── form/
│   │   │   │   │   │       │   ├── FormView.tsx
│   │   │   │   │   │       │   ├── FormViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── BrandFooter.tsx
│   │   │   │   │   │       │   │   ├── Drag.tsx
│   │   │   │   │   │       │   │   ├── FormCellEditor.tsx
│   │   │   │   │   │       │   │   ├── FormEditor.tsx
│   │   │   │   │   │       │   │   ├── FormEditorMain.tsx
│   │   │   │   │   │       │   │   ├── FormField.tsx
│   │   │   │   │   │       │   │   ├── FormFieldEditor.tsx
│   │   │   │   │   │       │   │   ├── FormPreviewer.tsx
│   │   │   │   │   │       │   │   ├── FormSidebar.tsx
│   │   │   │   │   │       │   │   ├── FromBody.tsx
│   │   │   │   │   │       │   │   ├── ShareUserEditor.tsx
│   │   │   │   │   │       │   │   ├── SortableItem.tsx
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── share-link-editor/
│   │   │   │   │   │       │   │       ├── FormLinkEditor.tsx
│   │   │   │   │   │       │   │       └── LinkRecordList.tsx
│   │   │   │   │   │       │   ├── constant.ts
│   │   │   │   │   │       │   └── util.ts
│   │   │   │   │   │       ├── gallery/
│   │   │   │   │   │       │   ├── GalleryView.tsx
│   │   │   │   │   │       │   ├── GalleryViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── Card.tsx
│   │   │   │   │   │       │   │   ├── CardCarousel.tsx
│   │   │   │   │   │       │   │   ├── SortableItem.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── context/
│   │   │   │   │   │       │   │   ├── GalleryContext.ts
│   │   │   │   │   │       │   │   ├── GalleryProvider.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useCacheRecords.ts
│   │   │   │   │   │       │   │   └── useGallery.ts
│   │   │   │   │   │       │   ├── type.ts
│   │   │   │   │   │       │   └── utils/
│   │   │   │   │   │       │       ├── card.ts
│   │   │   │   │   │       │       ├── columns.ts
│   │   │   │   │   │       │       └── index.ts
│   │   │   │   │   │       ├── grid/
│   │   │   │   │   │       │   ├── DomBox.tsx
│   │   │   │   │   │       │   ├── GridView.tsx
│   │   │   │   │   │       │   ├── GridViewBase.tsx
│   │   │   │   │   │       │   ├── GridViewBaseInner.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── AiAutoFillDialogContainer.tsx
│   │   │   │   │   │       │   │   ├── AiGenerateButton.tsx
│   │   │   │   │   │       │   │   ├── ConfirmNewRecords.tsx
│   │   │   │   │   │       │   │   ├── FieldMenu.tsx
│   │   │   │   │   │       │   │   ├── GroupHeaderMenu.tsx
│   │   │   │   │   │       │   │   ├── PluginMenu.tsx
│   │   │   │   │   │       │   │   ├── PrefillingRowContainer.tsx
│   │   │   │   │   │       │   │   ├── PresortRowContainer.tsx
│   │   │   │   │   │       │   │   ├── RecordMenu.tsx
│   │   │   │   │   │       │   │   ├── ResetClickCountButton.tsx
│   │   │   │   │   │       │   │   ├── StatisticMenu.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── const.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useCollaborate.ts
│   │   │   │   │   │       │   │   ├── useIsSelectionLoaded.ts
│   │   │   │   │   │       │   │   ├── useSelectionOperation.ts
│   │   │   │   │   │       │   │   └── useSelectionStore.ts
│   │   │   │   │   │       │   ├── useGridSearchStore.ts
│   │   │   │   │   │       │   └── utils/
│   │   │   │   │   │       │       ├── computeFrozenFields.ts
│   │   │   │   │   │       │       ├── copyAndPaste.ts
│   │   │   │   │   │       │       ├── fill.ts
│   │   │   │   │   │       │       ├── getSyncCopyData.ts
│   │   │   │   │   │       │       ├── index.ts
│   │   │   │   │   │       │       ├── selection.ts
│   │   │   │   │   │       │       ├── selectionViewQuery.spec.ts
│   │   │   │   │   │       │       └── selectionViewQuery.ts
│   │   │   │   │   │       ├── hooks/
│   │   │   │   │   │       │   ├── useContextMenu.ts
│   │   │   │   │   │       │   └── useToolbarChange.ts
│   │   │   │   │   │       ├── kanban/
│   │   │   │   │   │       │   ├── KanbanView.tsx
│   │   │   │   │   │       │   ├── KanbanViewBase.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── KanbanCard.tsx
│   │   │   │   │   │       │   │   ├── KanbanContainer.tsx
│   │   │   │   │   │       │   │   ├── KanbanStack.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackContainer.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackCreator.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackHeader.tsx
│   │   │   │   │   │       │   │   ├── KanbanStackTitle.tsx
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── interface.ts
│   │   │   │   │   │       │   ├── constant.ts
│   │   │   │   │   │       │   ├── context/
│   │   │   │   │   │       │   │   ├── KanbanContext.ts
│   │   │   │   │   │       │   │   ├── KanbanProvider.tsx
│   │   │   │   │   │       │   │   └── index.ts
│   │   │   │   │   │       │   ├── hooks/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   ├── useInView.ts
│   │   │   │   │   │       │   │   └── useKanban.ts
│   │   │   │   │   │       │   ├── store/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useKanbanStackCollapsed.ts
│   │   │   │   │   │       │   ├── type.ts
│   │   │   │   │   │       │   └── utils/
│   │   │   │   │   │       │       ├── card.ts
│   │   │   │   │   │       │       ├── drag.ts
│   │   │   │   │   │       │       ├── filter.ts
│   │   │   │   │   │       │       └── index.ts
│   │   │   │   │   │       ├── list/
│   │   │   │   │   │       │   ├── DraggableWrapper.tsx
│   │   │   │   │   │       │   ├── ExpandViewList.tsx
│   │   │   │   │   │       │   ├── PinViewItem.tsx
│   │   │   │   │   │       │   ├── ViewList.tsx
│   │   │   │   │   │       │   ├── ViewListItem.tsx
│   │   │   │   │   │       │   ├── useAddView.ts
│   │   │   │   │   │       │   └── useDeleteView.ts
│   │   │   │   │   │       ├── plugin/
│   │   │   │   │   │       │   └── PluginView.tsx
│   │   │   │   │   │       ├── search/
│   │   │   │   │   │       │   ├── SearchButton.tsx
│   │   │   │   │   │       │   ├── SearchCommand.tsx
│   │   │   │   │   │       │   └── SearchCountPagination.tsx
│   │   │   │   │   │       ├── tool-bar/
│   │   │   │   │   │       │   ├── APIDialog.tsx
│   │   │   │   │   │       │   ├── APIDialogContent.tsx
│   │   │   │   │   │       │   ├── CalendarToolBar.tsx
│   │   │   │   │   │       │   ├── FormToolBar.tsx
│   │   │   │   │   │       │   ├── GalleryToolBar.tsx
│   │   │   │   │   │       │   ├── GridToolBar.tsx
│   │   │   │   │   │       │   ├── KanbanToolBar.tsx
│   │   │   │   │   │       │   ├── Others.tsx
│   │   │   │   │   │       │   ├── SharePopover.tsx
│   │   │   │   │   │       │   ├── ShareViewContent.tsx
│   │   │   │   │   │       │   ├── ToolBarButton.tsx
│   │   │   │   │   │       │   ├── UnifiedShareDialog.tsx
│   │   │   │   │   │       │   ├── components/
│   │   │   │   │   │       │   │   ├── CalendarViewOperators.tsx
│   │   │   │   │   │       │   │   ├── CoverFieldSelect.tsx
│   │   │   │   │   │       │   │   ├── GalleryViewOperators.tsx
│   │   │   │   │   │       │   │   ├── GridViewOperators.tsx
│   │   │   │   │   │       │   │   ├── KanbanViewOperators.tsx
│   │   │   │   │   │       │   │   ├── PersonalViewSwitch.tsx
│   │   │   │   │   │       │   │   ├── UndoRedoButtons.tsx
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useToolBarStore.tsx
│   │   │   │   │   │       │   ├── hook/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useViewConfigurable.ts
│   │   │   │   │   │       │   ├── store/
│   │   │   │   │   │       │   │   ├── index.ts
│   │   │   │   │   │       │   │   └── useFormModeStore.ts
│   │   │   │   │   │       │   └── useViewFilterLinkContext.ts
│   │   │   │   │   │       └── types.ts
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── Chart/
│   │   │   │   │   │   │   ├── Chart.tsx
│   │   │   │   │   │   │   ├── bar.ts
│   │   │   │   │   │   │   ├── base.ts
│   │   │   │   │   │   │   ├── createChart.ts
│   │   │   │   │   │   │   ├── line.tsx
│   │   │   │   │   │   │   ├── pie.tsx
│   │   │   │   │   │   │   └── type.ts
│   │   │   │   │   │   ├── CopyButton.tsx
│   │   │   │   │   │   ├── DownloadProgressToast.tsx
│   │   │   │   │   │   ├── LanguagePicker.tsx
│   │   │   │   │   │   ├── LicenseExpiryBanner.tsx
│   │   │   │   │   │   ├── MenuDeleteItem.tsx
│   │   │   │   │   │   ├── PublicOperateButton.tsx
│   │   │   │   │   │   ├── ShareSelectSpaceDialog.tsx
│   │   │   │   │   │   ├── SideBarFooter.tsx
│   │   │   │   │   │   ├── SpaceSettingContainer.tsx
│   │   │   │   │   │   ├── TemplateSelectSpaceDialog.tsx
│   │   │   │   │   │   ├── ThemePicker.tsx
│   │   │   │   │   │   ├── Welcom.tsx
│   │   │   │   │   │   ├── billing/
│   │   │   │   │   │   │   ├── Level.tsx
│   │   │   │   │   │   │   ├── LevelWithUpgrade.tsx
│   │   │   │   │   │   │   ├── Status.tsx
│   │   │   │   │   │   │   ├── UpgradeWrapper.tsx
│   │   │   │   │   │   │   └── UsageLimitModal.tsx
│   │   │   │   │   │   ├── collaborator/
│   │   │   │   │   │   │   ├── share/
│   │   │   │   │   │   │   │   ├── CollaboratorsDialog.tsx
│   │   │   │   │   │   │   │   ├── ShareBaseContent.tsx
│   │   │   │   │   │   │   │   ├── ShareBaseDialog.tsx
│   │   │   │   │   │   │   │   ├── ShareBasePopover.tsx
│   │   │   │   │   │   │   │   └── common/
│   │   │   │   │   │   │   │       ├── AuthorityTips.tsx
│   │   │   │   │   │   │   │       ├── CollaboratorButton.tsx
│   │   │   │   │   │   │   │       ├── CollaboratorTable.tsx
│   │   │   │   │   │   │   │       ├── DebounceInput.tsx
│   │   │   │   │   │   │   │       ├── EmailContent.tsx
│   │   │   │   │   │   │   │       ├── Header.tsx
│   │   │   │   │   │   │   │       ├── InviteEmailButton.tsx
│   │   │   │   │   │   │   │       ├── InviteLinkButton.tsx
│   │   │   │   │   │   │   │       ├── InviteOrgButton.tsx
│   │   │   │   │   │   │   │       ├── LinkContent.tsx
│   │   │   │   │   │   │   │       ├── OrgContent.tsx
│   │   │   │   │   │   │   │       └── PreviewCollaborators.tsx
│   │   │   │   │   │   │   └── space/
│   │   │   │   │   │   │       ├── InviteSpaceContent.tsx
│   │   │   │   │   │   │       └── InviteSpacePopover.tsx
│   │   │   │   │   │   ├── collaborator-manage/
│   │   │   │   │   │   │   ├── base/
│   │   │   │   │   │   │   │   ├── BaseInvite.tsx
│   │   │   │   │   │   │   │   ├── BaseInviteLink.tsx
│   │   │   │   │   │   │   │   └── useFilteredRoleStatic.ts
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── Collaborator.tsx
│   │   │   │   │   │   │   │   ├── CollaboratorAdd.tsx
│   │   │   │   │   │   │   │   ├── CollaboratorItem.tsx
│   │   │   │   │   │   │   │   ├── CollaboratorList.tsx
│   │   │   │   │   │   │   │   ├── Invite.tsx
│   │   │   │   │   │   │   │   ├── InviteLinkItem.tsx
│   │   │   │   │   │   │   │   └── RoleSelect.tsx
│   │   │   │   │   │   │   ├── space/
│   │   │   │   │   │   │   │   ├── Collaborators.tsx
│   │   │   │   │   │   │   │   ├── SpaceInvite.tsx
│   │   │   │   │   │   │   │   ├── SpaceInviteLink.tsx
│   │   │   │   │   │   │   │   └── useFilteredRoleStatic.ts
│   │   │   │   │   │   │   ├── space-inner/
│   │   │   │   │   │   │   │   └── Collaborators.tsx
│   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   ├── useRoleStatic.ts
│   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   ├── download-attachments/
│   │   │   │   │   │   │   ├── CellDownloadHandler.tsx
│   │   │   │   │   │   │   ├── DownloadAllAttachmentsDialog.tsx
│   │   │   │   │   │   │   ├── DownloadContent.tsx
│   │   │   │   │   │   │   ├── DynamicDownloadContent.tsx
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── useDownloadAttachmentsStore.ts
│   │   │   │   │   │   ├── emoji/
│   │   │   │   │   │   │   ├── Emoji.tsx
│   │   │   │   │   │   │   └── EmojiPicker.tsx
│   │   │   │   │   │   ├── expand-record-container/
│   │   │   │   │   │   │   ├── ExpandRecordContainer.tsx
│   │   │   │   │   │   │   ├── ExpandRecordContainerBase.tsx
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── field-setting/
│   │   │   │   │   │   │   ├── DefaultValue.tsx
│   │   │   │   │   │   │   ├── DynamicFieldEditor.tsx
│   │   │   │   │   │   │   ├── FieldEditor.spec.tsx
│   │   │   │   │   │   │   ├── FieldEditor.tsx
│   │   │   │   │   │   │   ├── FieldOptions.tsx
│   │   │   │   │   │   │   ├── FieldSetting.tsx
│   │   │   │   │   │   │   ├── SelectFieldType.tsx
│   │   │   │   │   │   │   ├── SelectTable.tsx
│   │   │   │   │   │   │   ├── SystemInfo.tsx
│   │   │   │   │   │   │   ├── dialog/
│   │   │   │   │   │   │   │   └── AiAutoFillDialog.tsx
│   │   │   │   │   │   │   ├── field-ai-config/
│   │   │   │   │   │   │   │   ├── AttachmentFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── DateFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── FieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── MultipleSelectFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── RatingFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── SingleSelectFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── TextFieldAiConfig.tsx
│   │   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   │   ├── field-select/
│   │   │   │   │   │   │   │   │   │   ├── FieldSelect.tsx
│   │   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   │   └── prompt-editor/
│   │   │   │   │   │   │   │   │       ├── PromptEditor.tsx
│   │   │   │   │   │   │   │   │       ├── PromptEditorContainer.tsx
│   │   │   │   │   │   │   │   │       ├── extensions/
│   │   │   │   │   │   │   │   │       │   ├── index.ts
│   │   │   │   │   │   │   │   │       │   ├── theme.ts
│   │   │   │   │   │   │   │   │       │   └── variable.ts
│   │   │   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── field-delete-confirm-dialog/
│   │   │   │   │   │   │   │   ├── AffectedFieldsList.tsx
│   │   │   │   │   │   │   │   ├── FieldDeleteConfirmDialog.tsx
│   │   │   │   │   │   │   │   ├── FieldSelectionList.tsx
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   │   └── useDeleteAnalysis.ts
│   │   │   │   │   │   │   ├── field-validation/
│   │   │   │   │   │   │   │   └── FieldValidation.tsx
│   │   │   │   │   │   │   ├── formatting/
│   │   │   │   │   │   │   │   ├── DatetimeFormatting.tsx
│   │   │   │   │   │   │   │   ├── NumberFormatting.tsx
│   │   │   │   │   │   │   │   ├── TimeZoneFormatting.tsx
│   │   │   │   │   │   │   │   └── UnionFormatting.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── useDefaultFieldName.ts
│   │   │   │   │   │   │   │   ├── useUpdateConditionalLookupOptions.ts
│   │   │   │   │   │   │   │   ├── useUpdateLookupOptions.spec.ts
│   │   │   │   │   │   │   │   └── useUpdateLookupOptions.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── lookup-options/
│   │   │   │   │   │   │   │   ├── LookupFilterOptions.tsx
│   │   │   │   │   │   │   │   └── LookupOptions.tsx
│   │   │   │   │   │   │   ├── options/
│   │   │   │   │   │   │   │   ├── ButtonOptions.tsx
│   │   │   │   │   │   │   │   ├── CheckboxOptions.tsx
│   │   │   │   │   │   │   │   ├── ConditionalLookupOptions.tsx
│   │   │   │   │   │   │   │   ├── ConditionalRollupOptions.tsx
│   │   │   │   │   │   │   │   ├── CreatedTimeOptions.tsx
│   │   │   │   │   │   │   │   ├── DateOptions.tsx
│   │   │   │   │   │   │   │   ├── FormulaOptions.tsx
│   │   │   │   │   │   │   │   ├── LastModifiedByOptions.tsx
│   │   │   │   │   │   │   │   ├── LastModifiedTimeOptions.tsx
│   │   │   │   │   │   │   │   ├── LinkOptions/
│   │   │   │   │   │   │   │   │   ├── LinkOptions.tsx
│   │   │   │   │   │   │   │   │   ├── MoreLinkOptions.tsx
│   │   │   │   │   │   │   │   │   ├── SelectTable.tsx
│   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   ├── LinkedRecordSortLimitConfig.tsx
│   │   │   │   │   │   │   │   ├── LongTextOptions.tsx
│   │   │   │   │   │   │   │   ├── NumberOptions.tsx
│   │   │   │   │   │   │   │   ├── RatingOptions.tsx
│   │   │   │   │   │   │   │   ├── RollupOptions.tsx
│   │   │   │   │   │   │   │   ├── SelectOptions/
│   │   │   │   │   │   │   │   │   ├── ChoiceItem.tsx
│   │   │   │   │   │   │   │   │   ├── ColorPicker.tsx
│   │   │   │   │   │   │   │   │   ├── SelectDefaultValue.tsx
│   │   │   │   │   │   │   │   │   ├── SelectOptions.tsx
│   │   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   │   ├── SingleLineTextOptions.tsx
│   │   │   │   │   │   │   │   └── UserOptions.tsx
│   │   │   │   │   │   │   ├── show-as/
│   │   │   │   │   │   │   │   ├── MultiNumberShowAs.tsx
│   │   │   │   │   │   │   │   ├── SingleLineTextShowAs.tsx
│   │   │   │   │   │   │   │   ├── SingleNumberShowAs.tsx
│   │   │   │   │   │   │   │   └── UnionShowAs.tsx
│   │   │   │   │   │   │   ├── type.ts
│   │   │   │   │   │   │   └── useFieldTypeSubtitle.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── notifications/
│   │   │   │   │   │   │   ├── NotificationActionBar.tsx
│   │   │   │   │   │   │   ├── NotificationIcon.tsx
│   │   │   │   │   │   │   ├── NotificationItem.tsx
│   │   │   │   │   │   │   ├── NotificationList.tsx
│   │   │   │   │   │   │   ├── NotificationsManage.tsx
│   │   │   │   │   │   │   └── notification-component/
│   │   │   │   │   │   │       ├── LinkNotification.tsx
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── oauth/
│   │   │   │   │   │   │   ├── OAuthLogo.tsx
│   │   │   │   │   │   │   └── OAuthScope.tsx
│   │   │   │   │   │   ├── plugin/
│   │   │   │   │   │   │   ├── ComponentPluginRender.tsx
│   │   │   │   │   │   │   ├── IframePluginRender.tsx
│   │   │   │   │   │   │   ├── PluginCenterDialog.tsx
│   │   │   │   │   │   │   ├── PluginContent.tsx
│   │   │   │   │   │   │   ├── PluginDetail.tsx
│   │   │   │   │   │   │   ├── PluginHeader.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── iframe-url/
│   │   │   │   │   │   │   │   │   ├── useIframeUrl.tsx
│   │   │   │   │   │   │   │   │   └── utils.ts
│   │   │   │   │   │   │   │   ├── useIframeSize.tsx
│   │   │   │   │   │   │   │   ├── useSelection.ts
│   │   │   │   │   │   │   │   ├── useSyncBasePermissions.ts
│   │   │   │   │   │   │   │   ├── useSyncSelection.ts
│   │   │   │   │   │   │   │   ├── useSyncUIConfig.ts
│   │   │   │   │   │   │   │   ├── useSyncUrlParams.tsx
│   │   │   │   │   │   │   │   ├── useUIConfig.ts
│   │   │   │   │   │   │   │   ├── useUIEvent.ts
│   │   │   │   │   │   │   │   ├── useUrlParams.ts
│   │   │   │   │   │   │   │   ├── useUtilsEvent.ts
│   │   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │   │       └── getSelectionRecords.ts
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── plugin-context-menu/
│   │   │   │   │   │   │   ├── PluginContextMenu.tsx
│   │   │   │   │   │   │   ├── PluginContextMenuManageDialog.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── FloatPlugin.tsx
│   │   │   │   │   │   │   │   ├── useFloatPluginPosition.tsx
│   │   │   │   │   │   │   │   └── utils/
│   │   │   │   │   │   │   │       └── position.ts
│   │   │   │   │   │   │   └── useActiveMenuPlugin.ts
│   │   │   │   │   │   ├── plugin-panel/
│   │   │   │   │   │   │   ├── PluginLayout.tsx
│   │   │   │   │   │   │   ├── PluginPanel.tsx
│   │   │   │   │   │   │   ├── PluginPanelContainer.tsx
│   │   │   │   │   │   │   ├── PluginPanelEmpty.tsx
│   │   │   │   │   │   │   ├── PluginPanelHeader.tsx
│   │   │   │   │   │   │   ├── PluginPanelSelector.tsx
│   │   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   │   ├── CreatePluginDialog.tsx
│   │   │   │   │   │   │   │   ├── CreatePluginPanelDialog.tsx
│   │   │   │   │   │   │   │   └── PluginItem.tsx
│   │   │   │   │   │   │   └── hooks/
│   │   │   │   │   │   │       ├── useActivePluginPanelId.tsx
│   │   │   │   │   │   │       ├── usePluginPanelStorage.ts
│   │   │   │   │   │   │       └── usePluginPanelStore.ts
│   │   │   │   │   │   ├── setting/
│   │   │   │   │   │   │   ├── Account.tsx
│   │   │   │   │   │   │   ├── InteractionSelect.tsx
│   │   │   │   │   │   │   ├── Notifications.tsx
│   │   │   │   │   │   │   ├── SettingDialog.tsx
│   │   │   │   │   │   │   ├── SettingTabShell.tsx
│   │   │   │   │   │   │   ├── System.tsx
│   │   │   │   │   │   │   ├── account/
│   │   │   │   │   │   │   │   ├── AddPassword.tsx
│   │   │   │   │   │   │   │   ├── ChangeEmailDialog.tsx
│   │   │   │   │   │   │   │   ├── ChangePasswordDialog.tsx
│   │   │   │   │   │   │   │   └── DeleteAccountDialog.tsx
│   │   │   │   │   │   │   ├── integration/
│   │   │   │   │   │   │   │   ├── Integration.tsx
│   │   │   │   │   │   │   │   ├── common/
│   │   │   │   │   │   │   │   │   ├── Container.tsx
│   │   │   │   │   │   │   │   │   └── Header.tsx
│   │   │   │   │   │   │   │   ├── third-party-integrations/
│   │   │   │   │   │   │   │   │   ├── Content.tsx
│   │   │   │   │   │   │   │   │   ├── Detail.tsx
│   │   │   │   │   │   │   │   │   ├── List.tsx
│   │   │   │   │   │   │   │   │   └── RevokeButton.tsx
│   │   │   │   │   │   │   │   └── user-integration/
│   │   │   │   │   │   │   │       ├── ActionMenu.tsx
│   │   │   │   │   │   │   │       ├── Content.tsx
│   │   │   │   │   │   │   │       ├── List.tsx
│   │   │   │   │   │   │   │       ├── NewIntegration.tsx
│   │   │   │   │   │   │   │       ├── Rename.tsx
│   │   │   │   │   │   │   │       └── provider/
│   │   │   │   │   │   │   │           ├── EmailItem.tsx
│   │   │   │   │   │   │   │           └── SlackItem.tsx
│   │   │   │   │   │   │   ├── oauth-app/
│   │   │   │   │   │   │   │   ├── OAuthAppSection.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── personal-access-token/
│   │   │   │   │   │   │   │   ├── PersonalAccessTokenSection.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   └── useSettingStore.ts
│   │   │   │   │   │   ├── sidebar/
│   │   │   │   │   │   │   ├── SideBarScript.tsx
│   │   │   │   │   │   │   ├── Sidebar.tsx
│   │   │   │   │   │   │   ├── SidebarContent.tsx
│   │   │   │   │   │   │   ├── SidebarHeader.tsx
│   │   │   │   │   │   │   ├── SidebarHeaderLeft.tsx
│   │   │   │   │   │   │   ├── useChatPanelStore.ts
│   │   │   │   │   │   │   └── useSidebarStore.ts
│   │   │   │   │   │   ├── space/
│   │   │   │   │   │   │   ├── CollaboratorAvatars.tsx
│   │   │   │   │   │   │   ├── CreateBaseModal.tsx
│   │   │   │   │   │   │   ├── DeleteSpaceConfirm.tsx
│   │   │   │   │   │   │   ├── SpaceActionBar.tsx
│   │   │   │   │   │   │   ├── SpaceAvatar.tsx
│   │   │   │   │   │   │   ├── SpaceRenaming.tsx
│   │   │   │   │   │   │   └── template/
│   │   │   │   │   │   │       ├── CategoryMenu.tsx
│   │   │   │   │   │   │       ├── CategoryMenuItem.tsx
│   │   │   │   │   │   │       ├── RecommendTemplate.tsx
│   │   │   │   │   │   │       ├── TemplateCard.tsx
│   │   │   │   │   │   │       ├── TemplateDetail.tsx
│   │   │   │   │   │   │       ├── TemplateList.tsx
│   │   │   │   │   │   │       ├── TemplateMain.tsx
│   │   │   │   │   │   │       ├── TemplateModal.tsx
│   │   │   │   │   │   │       ├── TemplatePreview.tsx
│   │   │   │   │   │   │       ├── TemplatePreviewSheet.tsx
│   │   │   │   │   │   │       ├── TemplateSheet.tsx
│   │   │   │   │   │   │       ├── context.ts
│   │   │   │   │   │   │       ├── hooks/
│   │   │   │   │   │   │       │   └── use-space-id.ts
│   │   │   │   │   │   │       └── index.ts
│   │   │   │   │   │   ├── toggle-side-bar/
│   │   │   │   │   │   │   ├── HoverWrapper.tsx
│   │   │   │   │   │   │   ├── SheetWrapper.tsx
│   │   │   │   │   │   │   └── constant.ts
│   │   │   │   │   │   ├── upload-progress-panel/
│   │   │   │   │   │   │   ├── TaskItem.tsx
│   │   │   │   │   │   │   ├── UploadProgressBubble.tsx
│   │   │   │   │   │   │   ├── UploadProgressPanel.tsx
│   │   │   │   │   │   │   ├── UploadTaskList.tsx
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── user/
│   │   │   │   │   │   │   ├── UserAvatar.tsx
│   │   │   │   │   │   │   └── UserNav.tsx
│   │   │   │   │   │   └── user-integration/
│   │   │   │   │   │       ├── ProviderLogo.tsx
│   │   │   │   │   │       └── utils.ts
│   │   │   │   │   ├── context/
│   │   │   │   │   │   ├── ShareContext.tsx
│   │   │   │   │   │   └── StaticTextRegistryProvider.tsx
│   │   │   │   │   ├── dashboard/
│   │   │   │   │   │   ├── DashboardGrid.tsx
│   │   │   │   │   │   ├── DashboardHeader.tsx
│   │   │   │   │   │   ├── DashboardMain.tsx
│   │   │   │   │   │   ├── EmptyDashboard.tsx
│   │   │   │   │   │   ├── Pages.tsx
│   │   │   │   │   │   ├── TestBaseQuery.tsx
│   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   ├── AddPluginDialog.tsx
│   │   │   │   │   │   │   ├── CreateDashboardDialog.tsx
│   │   │   │   │   │   │   ├── DashboardSwitcher.tsx
│   │   │   │   │   │   │   └── PluginItem.tsx
│   │   │   │   │   │   └── hooks/
│   │   │   │   │   │       └── useIsExpandPlugin.ts
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── useAI.ts
│   │   │   │   │   │   ├── useAutoFavicon.tsx
│   │   │   │   │   │   ├── useBaseResource.ts
│   │   │   │   │   │   ├── useBaseUsage.ts
│   │   │   │   │   │   ├── useBillingLevel.ts
│   │   │   │   │   │   ├── useBillingLevelConfig.ts
│   │   │   │   │   │   ├── useBrand.tsx
│   │   │   │   │   │   ├── useCutDown.ts
│   │   │   │   │   │   ├── useDisableAIAction.ts
│   │   │   │   │   │   ├── useDownLoad.ts
│   │   │   │   │   │   ├── useEnv.ts
│   │   │   │   │   │   ├── useInitializationZodI18n.ts
│   │   │   │   │   │   ├── useIsCloud.ts
│   │   │   │   │   │   ├── useIsCommunity.ts
│   │   │   │   │   │   ├── useIsEE.ts
│   │   │   │   │   │   ├── useIsInIframe.ts
│   │   │   │   │   │   ├── usePreviewUrl.ts
│   │   │   │   │   │   ├── useSdkLocale.ts
│   │   │   │   │   │   └── useSetting.ts
│   │   │   │   │   ├── layouts/
│   │   │   │   │   │   ├── AdminLayout.tsx
│   │   │   │   │   │   ├── AppLayout.tsx
│   │   │   │   │   │   ├── BaseLayout.tsx
│   │   │   │   │   │   ├── SettingLayout.tsx
│   │   │   │   │   │   ├── ShareBaseLayout.tsx
│   │   │   │   │   │   ├── SharedBaseLayout.tsx
│   │   │   │   │   │   ├── SpaceInnerLayout.tsx
│   │   │   │   │   │   ├── SpaceLayout.tsx
│   │   │   │   │   │   ├── SpacePageTitle.tsx
│   │   │   │   │   │   ├── SpaceSettingLayout.tsx
│   │   │   │   │   │   ├── SpaceTrashLayout.tsx
│   │   │   │   │   │   ├── TemplateBaseLayout.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── useSettingRoute.tsx
│   │   │   │   │   ├── utils/
│   │   │   │   │   │   ├── clipboard.spec.ts
│   │   │   │   │   │   ├── clipboard.ts
│   │   │   │   │   │   ├── download-all-attachments.ts
│   │   │   │   │   │   ├── file.ts
│   │   │   │   │   │   ├── get-mod-key-str.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── init-axios.ts
│   │   │   │   │   │   ├── is-https.ts
│   │   │   │   │   │   ├── is-local.ts
│   │   │   │   │   │   └── uploadFile.ts
│   │   │   │   │   └── waitlist/
│   │   │   │   │       └── WaitlistPage.tsx
│   │   │   │   ├── auth/
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── DescContent.tsx
│   │   │   │   │   │   ├── LayoutMain.tsx
│   │   │   │   │   │   ├── Rectangles.tsx
│   │   │   │   │   │   ├── SendVerificationButton.tsx
│   │   │   │   │   │   ├── SignForm.tsx
│   │   │   │   │   │   ├── SocialAuth.tsx
│   │   │   │   │   │   ├── TeableFooter.tsx
│   │   │   │   │   │   ├── Terms.tsx
│   │   │   │   │   │   └── TurnstileWidget.tsx
│   │   │   │   │   ├── pages/
│   │   │   │   │   │   ├── ForgetPasswordPage.tsx
│   │   │   │   │   │   ├── LoginPage.tsx
│   │   │   │   │   │   └── ResetPasswordPage.tsx
│   │   │   │   │   └── useDisallowSignUp.ts
│   │   │   │   ├── i18n/
│   │   │   │   │   ├── auth.config.ts
│   │   │   │   │   ├── automation.tsx
│   │   │   │   │   ├── base-all.config.ts
│   │   │   │   │   ├── base.config.ts
│   │   │   │   │   ├── dashboard.config.ts
│   │   │   │   │   ├── developer.config.ts
│   │   │   │   │   ├── oauth-app.config.ts
│   │   │   │   │   ├── personal-access-token.config.ts
│   │   │   │   │   ├── setting-plugin.config.ts
│   │   │   │   │   ├── setting.config.ts
│   │   │   │   │   ├── share.config.ts
│   │   │   │   │   ├── space.config.ts
│   │   │   │   │   ├── system.config.ts
│   │   │   │   │   └── table.config.ts
│   │   │   │   └── system/
│   │   │   │       └── pages/
│   │   │   │           ├── ErrorPage.tsx
│   │   │   │           ├── ForbiddenPage.tsx
│   │   │   │           ├── HttpErrorPage.tsx
│   │   │   │           ├── IllustrationPage.tsx
│   │   │   │           ├── NotFoundPage.tsx
│   │   │   │           ├── PaymentRequired.tsx
│   │   │   │           ├── __tests__/
│   │   │   │           │   ├── ErrorPage.test.tsx
│   │   │   │           │   └── NotFoundPage.test.tsx
│   │   │   │           └── index.ts
│   │   │   ├── lib/
│   │   │   │   ├── emoji-color.ts
│   │   │   │   ├── ensureLogin.ts
│   │   │   │   ├── get-brand.ts
│   │   │   │   ├── handleBase.ts
│   │   │   │   ├── i18n/
│   │   │   │   │   ├── I18nNamespace.types.ts
│   │   │   │   │   ├── acceptHeader.ts
│   │   │   │   │   ├── getLocale.ts
│   │   │   │   │   ├── getServerSideTranslations.ts
│   │   │   │   │   ├── getTranslationsProps.ts
│   │   │   │   │   ├── helper.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── staticPageLocale.ts
│   │   │   │   ├── server-env.ts
│   │   │   │   ├── space-role-checker.ts
│   │   │   │   ├── type.ts
│   │   │   │   ├── view-pages-data.ts
│   │   │   │   ├── withAuthSSR.ts
│   │   │   │   └── withEnv.ts
│   │   │   ├── pages/
│   │   │   │   ├── 402.tsx
│   │   │   │   ├── 403.tsx
│   │   │   │   ├── 404.tsx
│   │   │   │   ├── _app.tsx
│   │   │   │   ├── _document.tsx
│   │   │   │   ├── _error.tsx
│   │   │   │   ├── _monitor/
│   │   │   │   │   ├── preview/
│   │   │   │   │   │   └── error-page.tsx
│   │   │   │   │   └── sentry/
│   │   │   │   │       ├── csr-page.tsx
│   │   │   │   │       └── ssr-page.tsx
│   │   │   │   ├── admin/
│   │   │   │   │   ├── setting.tsx
│   │   │   │   │   └── template.tsx
│   │   │   │   ├── api/
│   │   │   │   │   └── _monitor/
│   │   │   │   │       ├── healthcheck.ts
│   │   │   │   │       └── sentry.ts
│   │   │   │   ├── auth/
│   │   │   │   │   ├── forget-password.tsx
│   │   │   │   │   ├── login.tsx
│   │   │   │   │   ├── reset-password.tsx
│   │   │   │   │   └── signup.tsx
│   │   │   │   ├── base/
│   │   │   │   │   └── [baseId]/
│   │   │   │   │       ├── [[...slug]].tsx
│   │   │   │   │       ├── authority-matrix.tsx
│   │   │   │   │       ├── design.tsx
│   │   │   │   │       └── trash.tsx
│   │   │   │   ├── developer/
│   │   │   │   │   └── tool/
│   │   │   │   │       └── query-builder.tsx
│   │   │   │   ├── index.tsx
│   │   │   │   ├── invite/
│   │   │   │   │   └── index.tsx
│   │   │   │   ├── oauth/
│   │   │   │   │   └── decision.tsx
│   │   │   │   ├── setting/
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── oauth-app.tsx
│   │   │   │   │   ├── personal-access-token.tsx
│   │   │   │   │   └── plugin.tsx
│   │   │   │   ├── share/
│   │   │   │   │   └── [shareId]/
│   │   │   │   │       ├── base/
│   │   │   │   │       │   ├── [baseId]/
│   │   │   │   │       │   │   └── [[...slug]].tsx
│   │   │   │   │       │   ├── auth.tsx
│   │   │   │   │       │   └── index.tsx
│   │   │   │   │       └── view/
│   │   │   │   │           ├── auth.tsx
│   │   │   │   │           └── index.tsx
│   │   │   │   ├── space/
│   │   │   │   │   ├── [spaceId]/
│   │   │   │   │   │   └── setting/
│   │   │   │   │   │       ├── collaborator.tsx
│   │   │   │   │   │       └── general.tsx
│   │   │   │   │   ├── [spaceId].tsx
│   │   │   │   │   ├── index.tsx
│   │   │   │   │   ├── shared-base.tsx
│   │   │   │   │   └── trash.tsx
│   │   │   │   ├── t/
│   │   │   │   │   └── [identifier].tsx
│   │   │   │   └── waitlist/
│   │   │   │       └── index.tsx
│   │   │   ├── proxy.ts
│   │   │   ├── store/
│   │   │   │   ├── message.ts
│   │   │   │   └── user.ts
│   │   │   ├── styles/
│   │   │   │   ├── github-markdown.css
│   │   │   │   └── global.css
│   │   │   ├── themes/
│   │   │   │   ├── colors/
│   │   │   │   │   └── index.ts
│   │   │   │   ├── shared/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── colors.test.ts
│   │   │   │   │   ├── browser-fonts.js
│   │   │   │   │   └── colors.js
│   │   │   │   ├── tailwind/
│   │   │   │   │   └── tailwind.theme.js
│   │   │   │   ├── type.ts
│   │   │   │   └── utils.ts
│   │   │   └── types.d/
│   │   │       ├── i18next.d.ts
│   │   │       ├── next-i18next.d.ts
│   │   │       ├── react-svgr.d.ts
│   │   │       └── umami.d.ts
│   │   ├── tailwind.config.js
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── tsconfig.scripts.json
│   │   ├── turbopack-empty-stub.js
│   │   └── vitest.config.ts
│   └── playground/
│       ├── .cta.json
│       ├── .cursorrules
│       ├── .gitignore
│       ├── .vscode/
│       │   └── settings.json
│       ├── README.md
│       ├── components.json
│       ├── package.json
│       ├── src/
│       │   ├── components/
│       │   │   ├── playground/
│       │   │   │   ├── ComputedTasksPanel.tsx
│       │   │   │   ├── CreateTableDropdown.tsx
│       │   │   │   ├── ExplainResultPanel.tsx
│       │   │   │   ├── FieldCreateDialog.tsx
│       │   │   │   ├── FieldForm.tsx
│       │   │   │   ├── FieldFormOptions.tsx
│       │   │   │   ├── ImportCsvDialog.tsx
│       │   │   │   ├── LinkFieldLabel.tsx
│       │   │   │   ├── LogPanel.tsx
│       │   │   │   ├── MetaCheckPanel.tsx
│       │   │   │   ├── PlaygroundRecordRoute.tsx
│       │   │   │   ├── PlaygroundShell.tsx
│       │   │   │   ├── PlaygroundTableRoute.tsx
│       │   │   │   ├── RecordCreateDialog.tsx
│       │   │   │   ├── RecordDeleteDialog.tsx
│       │   │   │   ├── RecordUpdateDialog.tsx
│       │   │   │   ├── SchemaCheckPanel.tsx
│       │   │   │   ├── TableMetaPage.tsx
│       │   │   │   ├── UnderlyingDataPanel.tsx
│       │   │   │   ├── field-inputs/
│       │   │   │   │   ├── CheckboxFieldInput.tsx
│       │   │   │   │   ├── DateFieldInput.tsx
│       │   │   │   │   ├── DisabledFieldInput.tsx
│       │   │   │   │   ├── LinkFieldInput.tsx
│       │   │   │   │   ├── NumberFieldInput.tsx
│       │   │   │   │   ├── RatingFieldInput.tsx
│       │   │   │   │   ├── SelectFieldInput.tsx
│       │   │   │   │   ├── TextFieldInput.tsx
│       │   │   │   │   ├── index.tsx
│       │   │   │   │   └── types.ts
│       │   │   │   ├── field-options/
│       │   │   │   │   ├── ButtonOptions.tsx
│       │   │   │   │   ├── CheckboxOptions.tsx
│       │   │   │   │   ├── ConditionBuilder.tsx
│       │   │   │   │   ├── ConditionalLookupOptions.tsx
│       │   │   │   │   ├── ConditionalRollupOptions.tsx
│       │   │   │   │   ├── DateOptions.tsx
│       │   │   │   │   ├── FormulaOptions.tsx
│       │   │   │   │   ├── LinkOptions.tsx
│       │   │   │   │   ├── LookupOptions.tsx
│       │   │   │   │   ├── NumberOptions.tsx
│       │   │   │   │   ├── RatingOptions.tsx
│       │   │   │   │   ├── RollupOptions.tsx
│       │   │   │   │   ├── SelectOptions.tsx
│       │   │   │   │   ├── SingleLineTextOptions.tsx
│       │   │   │   │   └── UserOptions.tsx
│       │   │   │   ├── fieldOptionsVisitor.tsx
│       │   │   │   └── recordValueVisitor.tsx
│       │   │   └── ui/
│       │   │       ├── alert-dialog.tsx
│       │   │       ├── badge.tsx
│       │   │       ├── button.tsx
│       │   │       ├── calendar.tsx
│       │   │       ├── card.tsx
│       │   │       ├── checkbox.tsx
│       │   │       ├── command.tsx
│       │   │       ├── context-menu.tsx
│       │   │       ├── data-table.tsx
│       │   │       ├── date-picker.tsx
│       │   │       ├── dialog.tsx
│       │   │       ├── dropdown-menu.tsx
│       │   │       ├── form.tsx
│       │   │       ├── input.tsx
│       │   │       ├── label.tsx
│       │   │       ├── popover.tsx
│       │   │       ├── radio-group.tsx
│       │   │       ├── scroll-area.tsx
│       │   │       ├── select.tsx
│       │   │       ├── separator.tsx
│       │   │       ├── sheet.tsx
│       │   │       ├── sidebar.tsx
│       │   │       ├── skeleton.tsx
│       │   │       ├── slider.tsx
│       │   │       ├── switch.tsx
│       │   │       ├── table.tsx
│       │   │       ├── tabs.tsx
│       │   │       ├── textarea.tsx
│       │   │       └── tooltip.tsx
│       │   ├── hooks/
│       │   │   ├── use-mobile.ts
│       │   │   ├── useLogStream.ts
│       │   │   ├── useRecord.ts
│       │   │   └── useRecords.ts
│       │   ├── integrations/
│       │   │   ├── otel/
│       │   │   │   └── client.ts
│       │   │   └── tanstack-query/
│       │   │       ├── devtools.tsx
│       │   │       └── root-provider.tsx
│       │   ├── lib/
│       │   │   ├── broadcastChannel.ts
│       │   │   ├── fieldTypeIcons.ts
│       │   │   ├── nuqs/
│       │   │   │   └── tanstackRouterAdapter.tsx
│       │   │   ├── orpc/
│       │   │   │   ├── OrpcClientContext.tsx
│       │   │   │   ├── RemoteOrpcProvider.tsx
│       │   │   │   └── SandboxOrpcProvider.tsx
│       │   │   ├── orpcClient.ts
│       │   │   ├── playground/
│       │   │   │   ├── constants.ts
│       │   │   │   ├── databaseUrl.ts
│       │   │   │   └── environment.ts
│       │   │   ├── sandboxContainer.ts
│       │   │   ├── sandboxOrpcClient.ts
│       │   │   ├── shareDb.ts
│       │   │   └── utils.ts
│       │   ├── polyfill.ts
│       │   ├── router.tsx
│       │   ├── routes/
│       │   │   ├── $baseId.$tableId.$recordId.tsx
│       │   │   ├── $baseId.$tableId.tsx
│       │   │   ├── $baseId.tsx
│       │   │   ├── __root.tsx
│       │   │   ├── api.computed-tasks.$taskId.retry-now.ts
│       │   │   ├── api.computed-tasks.dead-letters.$taskId.replay.ts
│       │   │   ├── api.computed-tasks.dead-letters.$taskId.ts
│       │   │   ├── api.computed-tasks.dead-letters.ts
│       │   │   ├── api.computed-tasks.outbox.ts
│       │   │   ├── api.db.check.ts
│       │   │   ├── api.logs.stream.ts
│       │   │   ├── api.meta.$tableId.check.stream.ts
│       │   │   ├── api.rpc.$.ts
│       │   │   ├── api.schema.$tableId.check.stream.ts
│       │   │   ├── api.underlying.$tableId.ts
│       │   │   ├── computed-tasks.tsx
│       │   │   ├── index.tsx
│       │   │   └── sandbox/
│       │   │       ├── $baseId.$tableId.$recordId.tsx
│       │   │       ├── $baseId.$tableId.tsx
│       │   │       ├── $baseId.tsx
│       │   │       └── index.tsx
│       │   ├── server/
│       │   │   ├── otel.ts
│       │   │   ├── playgroundContainer.ts
│       │   │   ├── playgroundDbContext.ts
│       │   │   ├── playgroundLogger.ts
│       │   │   ├── shareDbServer.ts
│       │   │   ├── traceContext.ts
│       │   │   ├── traceResponseHeaders.ts
│       │   │   └── v2OrpcRouter.ts
│       │   ├── server.ts
│       │   ├── styles.css
│       │   └── types/
│       │       └── sharedb-pubsub.d.ts
│       ├── tsconfig.json
│       └── vite.config.ts
├── commitlint.config.js
├── crowdin.yml
├── docker-bake.hcl
├── dockers/
│   ├── cache-redis.yml
│   ├── database-postgres.yml
│   ├── examples/
│   │   ├── cluster/
│   │   │   ├── README.md
│   │   │   ├── docker-compose.yaml
│   │   │   └── gateway/
│   │   │       └── conf.d/
│   │   │           ├── default.conf
│   │   │           └── minio.conf
│   │   ├── docker-swarm/
│   │   │   ├── README.md
│   │   │   ├── deploy.sh
│   │   │   ├── docker-compose.app.yml
│   │   │   ├── docker-compose.default.yml
│   │   │   ├── docker-compose.gateway.yml
│   │   │   ├── docker-compose.kit.yml
│   │   │   └── gateway/
│   │   │       └── conf.d/
│   │   │           ├── default.conf
│   │   │           └── minio.conf
│   │   └── standalone/
│   │       ├── README.md
│   │       └── docker-compose.yaml
│   ├── integration-test.yml
│   ├── networks.yml
│   ├── storage-minio.yml
│   └── teable/
│       ├── Dockerfile
│       └── Dockerfile.db-migrate
├── dottea/
│   └── .gitignore
├── lint-staged.common.js
├── lint-staged.config.js
├── monorepo.code-workspace
├── package.json
├── packages/
│   ├── common-i18n/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── common-i18n.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── I18nNamespaces.ts
│   │   │   ├── index.ts
│   │   │   └── locales/
│   │   │       ├── de/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── en/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── es/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── fr/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── it/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── ja/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── ru/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── tr/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       ├── uk/
│   │   │       │   ├── auth.json
│   │   │       │   ├── chart.json
│   │   │       │   ├── common.json
│   │   │       │   ├── dashboard.json
│   │   │       │   ├── developer.json
│   │   │       │   ├── oauth.json
│   │   │       │   ├── plugin.json
│   │   │       │   ├── sdk.json
│   │   │       │   ├── setting.json
│   │   │       │   ├── share.json
│   │   │       │   ├── space.json
│   │   │       │   ├── table.json
│   │   │       │   ├── token.json
│   │   │       │   └── zod.json
│   │   │       └── zh/
│   │   │           ├── auth.json
│   │   │           ├── chart.json
│   │   │           ├── common.json
│   │   │           ├── dashboard.json
│   │   │           ├── developer.json
│   │   │           ├── oauth.json
│   │   │           ├── plugin.json
│   │   │           ├── sdk.json
│   │   │           ├── setting.json
│   │   │           ├── share.json
│   │   │           ├── space.json
│   │   │           ├── table.json
│   │   │           ├── token.json
│   │   │           └── zod.json
│   │   └── tsconfig.json
│   ├── core/
│   │   ├── .escheckrc
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── core.iml
│   │   │   └── modules.xml
│   │   ├── .size-limit.cjs
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── array/
│   │   │   │   ├── ArrayUtils.spec.ts
│   │   │   │   ├── ArrayUtils.ts
│   │   │   │   └── index.ts
│   │   │   ├── asserts/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── asserts.test.ts
│   │   │   │   ├── asserts.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── lang.ts
│   │   │   ├── auth/
│   │   │   │   ├── actions.ts
│   │   │   │   ├── anonymous.ts
│   │   │   │   ├── app-robot.ts
│   │   │   │   ├── automation-robot.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── me-tag.ts
│   │   │   │   ├── oauth.ts
│   │   │   │   ├── permission.ts
│   │   │   │   ├── role/
│   │   │   │   │   ├── base.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── share.ts
│   │   │   │   │   ├── space.ts
│   │   │   │   │   ├── table.ts
│   │   │   │   │   ├── template.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── utils.ts
│   │   │   │   ├── system.ts
│   │   │   │   └── types.ts
│   │   │   ├── convert/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── string-convert.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── nulls-to-undefined.ts
│   │   │   │   └── string-convert.ts
│   │   │   ├── errors/
│   │   │   │   ├── extract-error-message.ts
│   │   │   │   ├── http/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── http-response.types.ts
│   │   │   │   │   ├── http.error.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── formula/
│   │   │   │   ├── errors/
│   │   │   │   │   ├── circular-reference.error.spec.ts
│   │   │   │   │   ├── circular-reference.error.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── evaluate.ts
│   │   │   │   ├── function-aliases.ts
│   │   │   │   ├── function-convertor.interface.ts
│   │   │   │   ├── functions/
│   │   │   │   │   ├── array.spec.ts
│   │   │   │   │   ├── array.ts
│   │   │   │   │   ├── common.ts
│   │   │   │   │   ├── date-time.spec.ts
│   │   │   │   │   ├── date-time.ts
│   │   │   │   │   ├── factory.ts
│   │   │   │   │   ├── logical.spec.ts
│   │   │   │   │   ├── logical.ts
│   │   │   │   │   ├── numeric.spec.ts
│   │   │   │   │   ├── numeric.ts
│   │   │   │   │   ├── system.spec.ts
│   │   │   │   │   ├── system.ts
│   │   │   │   │   ├── text.spec.ts
│   │   │   │   │   └── text.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── typed-value-converter.spec.ts
│   │   │   │   ├── typed-value-converter.ts
│   │   │   │   ├── typed-value.ts
│   │   │   │   ├── visitor.spec.ts
│   │   │   │   └── visitor.ts
│   │   │   ├── index.ts
│   │   │   ├── models/
│   │   │   │   ├── aggregation/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── statistic.spec.ts
│   │   │   │   │   ├── statistic.ts
│   │   │   │   │   └── statistics-func.enum.ts
│   │   │   │   ├── channel.ts
│   │   │   │   ├── field/
│   │   │   │   │   ├── ai-config/
│   │   │   │   │   │   ├── attachment.ts
│   │   │   │   │   │   ├── date.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── multiple-select.ts
│   │   │   │   │   │   ├── rating.ts
│   │   │   │   │   │   ├── single-select.ts
│   │   │   │   │   │   └── text.ts
│   │   │   │   │   ├── button-utils.ts
│   │   │   │   │   ├── cell-value-validation.ts
│   │   │   │   │   ├── color-utils.spec.ts
│   │   │   │   │   ├── color-utils.ts
│   │   │   │   │   ├── colors.ts
│   │   │   │   │   ├── conditional.constants.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── derivate/
│   │   │   │   │   │   ├── abstract/
│   │   │   │   │   │   │   ├── formula.field.abstract.ts
│   │   │   │   │   │   │   ├── select-option.schema.ts
│   │   │   │   │   │   │   ├── select.field.abstract.spec.ts
│   │   │   │   │   │   │   ├── select.field.abstract.ts
│   │   │   │   │   │   │   └── user.field.abstract.ts
│   │   │   │   │   │   ├── attachment-option.schema.ts
│   │   │   │   │   │   ├── attachment.field.spec.ts
│   │   │   │   │   │   ├── attachment.field.ts
│   │   │   │   │   │   ├── auto-number-option.schema.ts
│   │   │   │   │   │   ├── auto-number.field.spec.ts
│   │   │   │   │   │   ├── auto-number.field.ts
│   │   │   │   │   │   ├── button-option.schema.ts
│   │   │   │   │   │   ├── button.field.spec.ts
│   │   │   │   │   │   ├── button.field.ts
│   │   │   │   │   │   ├── checkbox-option.schema.ts
│   │   │   │   │   │   ├── checkbox.field.spec.ts
│   │   │   │   │   │   ├── checkbox.field.ts
│   │   │   │   │   │   ├── conditional-rollup-option.schema.ts
│   │   │   │   │   │   ├── conditional-rollup.field.ts
│   │   │   │   │   │   ├── created-by-option.schema.ts
│   │   │   │   │   │   ├── created-by.field.ts
│   │   │   │   │   │   ├── created-time-option.schema.ts
│   │   │   │   │   │   ├── created-time.field.spec.ts
│   │   │   │   │   │   ├── created-time.field.ts
│   │   │   │   │   │   ├── date-option.schema.ts
│   │   │   │   │   │   ├── date.field.spec.ts
│   │   │   │   │   │   ├── date.field.ts
│   │   │   │   │   │   ├── formula-option.schema.ts
│   │   │   │   │   │   ├── formula.field.spec.ts
│   │   │   │   │   │   ├── formula.field.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── last-modified-by-option.schema.ts
│   │   │   │   │   │   ├── last-modified-by.field.ts
│   │   │   │   │   │   ├── last-modified-time-option.schema.ts
│   │   │   │   │   │   ├── last-modified-time.field.spec.ts
│   │   │   │   │   │   ├── last-modified-time.field.ts
│   │   │   │   │   │   ├── link-option.schema.ts
│   │   │   │   │   │   ├── link.field.spec.ts
│   │   │   │   │   │   ├── link.field.ts
│   │   │   │   │   │   ├── long-text-option.schema.ts
│   │   │   │   │   │   ├── long-text.field.spec.ts
│   │   │   │   │   │   ├── long-text.field.ts
│   │   │   │   │   │   ├── multiple-select.field.spec.ts
│   │   │   │   │   │   ├── multiple-select.field.ts
│   │   │   │   │   │   ├── number-option.schema.ts
│   │   │   │   │   │   ├── number.field.spec.ts
│   │   │   │   │   │   ├── number.field.ts
│   │   │   │   │   │   ├── rating-option.schema.ts
│   │   │   │   │   │   ├── rating.field.spec.ts
│   │   │   │   │   │   ├── rating.field.ts
│   │   │   │   │   │   ├── rollup-option.schema.ts
│   │   │   │   │   │   ├── rollup.field.spec.ts
│   │   │   │   │   │   ├── rollup.field.ts
│   │   │   │   │   │   ├── single-line-text-option.schema.ts
│   │   │   │   │   │   ├── single-line-text.field.spec.ts
│   │   │   │   │   │   ├── single-line-text.field.ts
│   │   │   │   │   │   ├── single-select.field.spec.ts
│   │   │   │   │   │   ├── single-select.field.ts
│   │   │   │   │   │   ├── user-option.schema.ts
│   │   │   │   │   │   ├── user.field.spec.ts
│   │   │   │   │   │   └── user.field.ts
│   │   │   │   │   ├── field-options-validation.spec.ts
│   │   │   │   │   ├── field-unions.schema.ts
│   │   │   │   │   ├── field-validation.ts
│   │   │   │   │   ├── field-visitor.interface.ts
│   │   │   │   │   ├── field.schema.spec.ts
│   │   │   │   │   ├── field.schema.ts
│   │   │   │   │   ├── field.ts
│   │   │   │   │   ├── field.type.ts
│   │   │   │   │   ├── field.util.spec.ts
│   │   │   │   │   ├── field.util.ts
│   │   │   │   │   ├── formatting/
│   │   │   │   │   │   ├── datetime.spec.ts
│   │   │   │   │   │   ├── datetime.ts
│   │   │   │   │   │   ├── index.spec.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── number.spec.ts
│   │   │   │   │   │   ├── number.ts
│   │   │   │   │   │   └── time-zone.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── lookup-options-base.schema.spec.ts
│   │   │   │   │   ├── lookup-options-base.schema.ts
│   │   │   │   │   ├── options.schema.ts
│   │   │   │   │   ├── show-as/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── number.ts
│   │   │   │   │   │   └── text.ts
│   │   │   │   │   ├── utils/
│   │   │   │   │   │   └── get-db-field-type.ts
│   │   │   │   │   ├── zod-error.spec.ts
│   │   │   │   │   └── zod-error.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── notification/
│   │   │   │   │   ├── action-trigger.schema.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── notification.enum.ts
│   │   │   │   │   └── notification.schema.ts
│   │   │   │   ├── op.ts
│   │   │   │   ├── record/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── record.ts
│   │   │   │   ├── table/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── table-domain.spec.ts
│   │   │   │   │   ├── table-domain.ts
│   │   │   │   │   ├── table-fields.spec.ts
│   │   │   │   │   ├── table-fields.ts
│   │   │   │   │   ├── table.ts
│   │   │   │   │   ├── tables.spec.ts
│   │   │   │   │   └── tables.ts
│   │   │   │   └── view/
│   │   │   │       ├── column-meta.schema.ts
│   │   │   │       ├── constant.ts
│   │   │   │       ├── derivate/
│   │   │   │       │   ├── calendar-view-option.schema.ts
│   │   │   │       │   ├── calendar.view.ts
│   │   │   │       │   ├── form-view-option.schema.ts
│   │   │   │       │   ├── form.view.ts
│   │   │   │       │   ├── gallery-view-option.schema.ts
│   │   │   │       │   ├── gallery.view.ts
│   │   │   │       │   ├── grid-view-option.schema.ts
│   │   │   │       │   ├── grid.view.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── kanban-view-option.schema.ts
│   │   │   │       │   ├── kanban.view.ts
│   │   │   │       │   ├── plugin-view-option.schema.ts
│   │   │   │       │   └── plugin.view.ts
│   │   │   │       ├── filter/
│   │   │   │       │   ├── conjunction.ts
│   │   │   │       │   ├── field-reference.spec.ts
│   │   │   │       │   ├── field-reference.ts
│   │   │   │       │   ├── filter-item.ts
│   │   │   │       │   ├── filter.spec.ts
│   │   │   │       │   ├── filter.ts
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── operator.spec.ts
│   │   │   │       │   └── operator.ts
│   │   │   │       ├── group/
│   │   │   │       │   ├── group.ts
│   │   │   │       │   └── index.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── option.schema.spec.ts
│   │   │   │       ├── option.schema.ts
│   │   │   │       ├── query.replace.ts
│   │   │   │       ├── sort/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── sort-func.enum.ts
│   │   │   │       │   ├── sort.schema.spec.ts
│   │   │   │       │   └── sort.ts
│   │   │   │       ├── view.schema.ts
│   │   │   │       └── view.ts
│   │   │   ├── op-builder/
│   │   │   │   ├── common.spec.ts
│   │   │   │   ├── common.ts
│   │   │   │   ├── field/
│   │   │   │   │   ├── add-column-meta.spec.ts
│   │   │   │   │   ├── add-column-meta.ts
│   │   │   │   │   ├── add-field.ts
│   │   │   │   │   ├── delete-column-meta.spec.ts
│   │   │   │   │   ├── delete-column-meta.ts
│   │   │   │   │   ├── field-op-builder.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── set-field-property.spec.ts
│   │   │   │   │   └── set-field-property.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── interface.ts
│   │   │   │   ├── op-builder.abstract.ts
│   │   │   │   ├── record/
│   │   │   │   │   ├── add-record.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── record-op-builder.ts
│   │   │   │   │   └── set-record.ts
│   │   │   │   ├── table/
│   │   │   │   │   ├── add-table.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── set-table-property.ts
│   │   │   │   │   └── table-op-builder.ts
│   │   │   │   └── view/
│   │   │   │       ├── add-view.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── set-view-property.ts
│   │   │   │       ├── update-view-column-meta.ts
│   │   │   │       └── view-op-builder.ts
│   │   │   ├── query/
│   │   │   │   ├── index.ts
│   │   │   │   ├── json-error.strategy.ts
│   │   │   │   ├── json.visitor.spec.ts
│   │   │   │   ├── json.visitor.ts
│   │   │   │   └── parser/
│   │   │   │       ├── Query.g4
│   │   │   │       ├── Query.interp
│   │   │   │       ├── Query.tokens
│   │   │   │       ├── Query.ts
│   │   │   │       ├── QueryLexer.g4
│   │   │   │       ├── QueryLexer.interp
│   │   │   │       ├── QueryLexer.tokens
│   │   │   │       ├── QueryLexer.ts
│   │   │   │       └── QueryVisitor.ts
│   │   │   ├── typeguards/
│   │   │   │   ├── __tests__/
│   │   │   │   │   └── typeguards.test.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── json-api/
│   │   │   │   │   ├── __tests__/
│   │   │   │   │   │   └── json-api-typeguard.test.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── json-api-response.types.ts
│   │   │   │   │   └── json-api.typeguard.ts
│   │   │   │   └── typeguards.ts
│   │   │   ├── types/
│   │   │   │   ├── either-or.ts
│   │   │   │   ├── ensure-keys.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── make-optional.ts
│   │   │   │   ├── make-required.ts
│   │   │   │   ├── remove-null.ts
│   │   │   │   ├── snapshot-query.ts
│   │   │   │   └── un-promisify.ts
│   │   │   ├── utils/
│   │   │   │   ├── clipboard.spec.ts
│   │   │   │   ├── clipboard.ts
│   │   │   │   ├── date.spec.ts
│   │   │   │   ├── date.ts
│   │   │   │   ├── dsn-parser.ts
│   │   │   │   ├── enum.ts
│   │   │   │   ├── get-random-int.spec.ts
│   │   │   │   ├── get-random-int.ts
│   │   │   │   ├── get-uniq-name.spec.ts
│   │   │   │   ├── get-uniq-name.ts
│   │   │   │   ├── id-generator.spec.ts
│   │   │   │   ├── id-generator.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── minidenticon.ts
│   │   │   │   └── replace-suffix.ts
│   │   │   └── zod.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.js
│   ├── db-main-prisma/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── db-main-prisma.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── prisma/
│   │   │   ├── postgres/
│   │   │   │   ├── migrations/
│   │   │   │   │   ├── 20240308114704_initial_database/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240313062534_add_credit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240409081450_field_order/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240410190501_primary_field_visible/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240416092001_clean_useless_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240528060827_add_pin_resource/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240625032002_add_admin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240626072754_add_setting_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240628115120_add_space_invitation/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240702084258_add_oauth/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240708080014_oauth_revoke/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240712040045_remove_bucket/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240716070632_notification_url_path/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240806110415_add_record_history/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240814074637_update_collaborator/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240906084530_add_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240913075702_add_dashboard_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240919032636_add_comment/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241008161823_share_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241031080906_add_attachment_thumbnail/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241126085325_add_ref_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241128112023_add_ai_config/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241205121129_add_table_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241223100142_collaborator_support_org/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241226111824_remove_collaborator_foreign_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250115084212_add_enable_email_verification_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250117105433_update_view/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250214080105_add_integration/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250217092955_add_table_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250218075500_add_plugin_context_menu/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250320062220_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250328035739_brand/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250402105144_add_template/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250406145144_add_share_id_unique/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250409093339_add_task_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250410102941_update_task_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250416113238_add_template_markdown_description/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250418091636_add_db_table_name_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250509062715_require_primary_key/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250513085306_add_ai_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520081803_update_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520103546_add_user_trial_used/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250526042029_repair_reference_caused_by_formula_duplicate/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250604101438_update_access_token_full_access/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250702035214_update_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250730041646_add_user_permanent_deleted_time/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250804000000_add_field_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250811102556_add_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812031017_remove_user_last_visit_useless_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812090828_remove_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250820022407_add_waitlist/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250820022408_add_table_meta_db_view_name/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250828083308_add_app_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250905035737_add_trash_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922111648_add_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922120000_add_conditional_lookup_flag/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251028105638_add_user_lang/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251029141643_add_notification_message_i18n/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251105070802_add_oauth_foreign_keys/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251119134101_add_base_node/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251208112242_template_community/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251210134101_disallow_dashboard/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251219083654_add_template_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104151713_add_computed_update_outbox_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104190000_add_outbox_seed_table_id/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260105123000_add_computed_update_run_tracking/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260114000000_add_field_json_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260118000000_add_symmetric_field_id_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260118010000_add_teable_try_cast_valid/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260120065143_add_core_table_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260121090646_add_task_run_log/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260121100000_add_base_share/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260129203000_add_outbox_pending_unique_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260303000000_alter_attachment_size_to_bigint/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260305000000_add_trace_data_and_nullable_steps_edges/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260305072937_oauth_app_token_optional_secret/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260305120931_add_oauth_app_client_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   └── migration_lock.toml
│   │   │   │   └── schema.prisma
│   │   │   ├── seed.ts
│   │   │   ├── sqlite/
│   │   │   │   ├── migrations/
│   │   │   │   │   ├── 20240308114656_initial_database/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240313061543_add_credit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240409081445_field_order/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240416091909_clean_useless_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240528055850_add_pin_resource/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240528060824_add_pin_resource/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240625031955_add_admin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240626072703_add_setting_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240628115107_add_space_invitation/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240702084255_add_oauth/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240708080010_oauth_revoke/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240712040040_remove_bucket/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240716070608_notification_url_path/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240806110404_add_record_history/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240814074632_update_collaborator/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240906084521_add_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240913075658_add_dashboard_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20240919032621_add_comment/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241031080903_add_attachment_thumbnail/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241126081006_add_ref_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241128112016_add_ai_config/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241205121154_add_table_trash/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241223100135_collaborator_support_org/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20241226111815_remove_collaborator_foreign_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250115084207_add_enable_email_verification_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250117105406_update_view/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250214080102_add_integration/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250217092948_add_table_plugin/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250218075455_add_plugin_context_menu/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250320062213_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250328040207_brand/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250402105138_add_template/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250406145126_add_share_id_unique/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250409093334_add_task_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250410102938_update_task_table/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250416113234_add_template_markdown_description/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250418091633_add_db_table_name_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250509062710_require_primary_key/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250513085303_add_ai_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520081750_update_user_last_visit/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250520103541_add_user_trial_used/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250526042154_repair_reference_caused_by_formula_duplicate/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250604101438_update_access_token_full_access/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250702035214_update_setting/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250730041646_add_user_permanent_deleted_time/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250804000000_add_field_meta/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250811102551_add_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812031012_remove_user_last_visit_useless_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250812090823_remove_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250820022401_add_waitlist/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250828083309_add_app_robot_user/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250904034946_add_table_meta_db_view_name/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250905035730_add_trash_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922111616_add_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20250922120000_add_conditional_lookup_flag/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251028105630_add_user_lang/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251029141619_add_notification_message_i18n/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251105070757_add_oauth_foreign_keys/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251119134053_add_base_node/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251208112242_template_community/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251210134101_disallow_dashboard/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20251219083654_add_template_visit_count/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104151713_add_computed_update_outbox_tables/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260104190000_add_outbox_seed_table_id/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260120065143_add_core_table_indexes/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260121100000_add_base_share/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   ├── 20260129203000_add_outbox_pending_unique_index/
│   │   │   │   │   │   └── migration.sql
│   │   │   │   │   └── migration_lock.toml
│   │   │   │   └── schema.prisma
│   │   │   └── template.prisma
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── prisma.module.ts
│   │   │   ├── prisma.service.ts
│   │   │   ├── seeds/
│   │   │   │   ├── e2e/
│   │   │   │   │   ├── space-seeds.ts
│   │   │   │   │   └── user-seeds.ts
│   │   │   │   └── seed.abstract.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.eslint.json
│   │   └── tsconfig.json
│   ├── eslint-config-bases/
│   │   ├── .eslintrc.cjs
│   │   ├── .idea/
│   │   │   ├── eslint-config-bases.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── bases/
│   │   │   │   ├── index.js
│   │   │   │   ├── jest.js
│   │   │   │   ├── mdx.js
│   │   │   │   ├── playwright.js
│   │   │   │   ├── prettier-config.js
│   │   │   │   ├── prettier-plugin.js
│   │   │   │   ├── react-query.js
│   │   │   │   ├── react.js
│   │   │   │   ├── regexp.js
│   │   │   │   ├── rtl.js
│   │   │   │   ├── sonar.js
│   │   │   │   ├── storybook.js
│   │   │   │   ├── tailwind.js
│   │   │   │   └── typescript.js
│   │   │   ├── helpers/
│   │   │   │   ├── getDefaultIgnorePatterns.js
│   │   │   │   ├── getPrettierConfig.js
│   │   │   │   └── index.js
│   │   │   ├── index.js
│   │   │   ├── patch/
│   │   │   │   └── modern-module-resolution.js
│   │   │   └── prettier.base.config.js
│   │   └── tsconfig.json
│   ├── formula/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── conversion.visitor.spec.ts
│   │   │   ├── conversion.visitor.ts
│   │   │   ├── datetime-format-pg.spec.ts
│   │   │   ├── datetime-format-pg.ts
│   │   │   ├── error.listener.ts
│   │   │   ├── field-reference.util.ts
│   │   │   ├── field-reference.visitor.spec.ts
│   │   │   ├── field-reference.visitor.ts
│   │   │   ├── function-call-collector.visitor.spec.ts
│   │   │   ├── function-call-collector.visitor.ts
│   │   │   ├── index.ts
│   │   │   ├── parse-formula.ts
│   │   │   └── parser/
│   │   │       ├── Formula.g4
│   │   │       ├── Formula.interp
│   │   │       ├── Formula.tokens
│   │   │       ├── Formula.ts
│   │   │       ├── FormulaLexer.g4
│   │   │       ├── FormulaLexer.interp
│   │   │       ├── FormulaLexer.tokens
│   │   │       ├── FormulaLexer.ts
│   │   │       ├── FormulaVisitor.ts
│   │   │       └── README.md
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.js
│   ├── i18n-keys/
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── icons/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── icons.iml
│   │   │   └── modules.xml
│   │   ├── LICENSE
│   │   ├── package.json
│   │   ├── scripts/
│   │   │   └── generate.mjs
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── A.tsx
│   │   │   │   ├── ActionAI.tsx
│   │   │   │   ├── ActionCreateRecord.tsx
│   │   │   │   ├── ActionGetRecord.tsx
│   │   │   │   ├── ActionHttpRequest.tsx
│   │   │   │   ├── ActionScript.tsx
│   │   │   │   ├── ActionSendEmail.tsx
│   │   │   │   ├── ActionUpdateRecord.tsx
│   │   │   │   ├── Admin.tsx
│   │   │   │   ├── AlertCircle.tsx
│   │   │   │   ├── AlertTriangle.tsx
│   │   │   │   ├── AmazonBedrock.tsx
│   │   │   │   ├── Anthropic.tsx
│   │   │   │   ├── AppBuilder.tsx
│   │   │   │   ├── AppV0.tsx
│   │   │   │   ├── Apple.tsx
│   │   │   │   ├── ArceeAi.tsx
│   │   │   │   ├── Array.tsx
│   │   │   │   ├── ArrowDown.tsx
│   │   │   │   ├── ArrowLeft.tsx
│   │   │   │   ├── ArrowRight.tsx
│   │   │   │   ├── ArrowUp.tsx
│   │   │   │   ├── ArrowUpDown.tsx
│   │   │   │   ├── ArrowUpRight.tsx
│   │   │   │   ├── Audio.tsx
│   │   │   │   ├── Azure.tsx
│   │   │   │   ├── BarChart2.tsx
│   │   │   │   ├── Bell.tsx
│   │   │   │   ├── Bfl.tsx
│   │   │   │   ├── Boolean.tsx
│   │   │   │   ├── Box.tsx
│   │   │   │   ├── Building2.tsx
│   │   │   │   ├── Bytedance.tsx
│   │   │   │   ├── Calendar.tsx
│   │   │   │   ├── Check.tsx
│   │   │   │   ├── CheckCircle2.tsx
│   │   │   │   ├── CheckSquare.tsx
│   │   │   │   ├── Checked.tsx
│   │   │   │   ├── ChevronDown.tsx
│   │   │   │   ├── ChevronLeft.tsx
│   │   │   │   ├── ChevronRight.tsx
│   │   │   │   ├── ChevronUp.tsx
│   │   │   │   ├── ChevronsLeft.tsx
│   │   │   │   ├── ChevronsRight.tsx
│   │   │   │   ├── ChevronsUpDown.tsx
│   │   │   │   ├── Circle.tsx
│   │   │   │   ├── ClipboardList.tsx
│   │   │   │   ├── Clock4.tsx
│   │   │   │   ├── Code.tsx
│   │   │   │   ├── Code2.tsx
│   │   │   │   ├── CodeReact.tsx
│   │   │   │   ├── Cohere.tsx
│   │   │   │   ├── Coins.tsx
│   │   │   │   ├── Component.tsx
│   │   │   │   ├── Compose.tsx
│   │   │   │   ├── Condition.tsx
│   │   │   │   ├── ConditionalLookup.tsx
│   │   │   │   ├── ConditionalRollup.tsx
│   │   │   │   ├── Copy.tsx
│   │   │   │   ├── CreditCard.tsx
│   │   │   │   ├── Credits.tsx
│   │   │   │   ├── Cuppy.tsx
│   │   │   │   ├── CuppyLoader.tsx
│   │   │   │   ├── Database.tsx
│   │   │   │   ├── DeepThinking.tsx
│   │   │   │   ├── Deepseek.tsx
│   │   │   │   ├── Discord.tsx
│   │   │   │   ├── DivideCircle.tsx
│   │   │   │   ├── DivideSquare.tsx
│   │   │   │   ├── DollarSign.tsx
│   │   │   │   ├── Download.tsx
│   │   │   │   ├── DraggableHandle.tsx
│   │   │   │   ├── Edit.tsx
│   │   │   │   ├── Expand.tsx
│   │   │   │   ├── ExpandAll.tsx
│   │   │   │   ├── Export.tsx
│   │   │   │   ├── Eye.tsx
│   │   │   │   ├── EyeOff.tsx
│   │   │   │   ├── File.tsx
│   │   │   │   ├── FileAudio.tsx
│   │   │   │   ├── FileAudioDark.tsx
│   │   │   │   ├── FileCsv.tsx
│   │   │   │   ├── FileDocument.tsx
│   │   │   │   ├── FileDocumentDark.tsx
│   │   │   │   ├── FileExcel.tsx
│   │   │   │   ├── FileFont.tsx
│   │   │   │   ├── FileImage.tsx
│   │   │   │   ├── FileJson.tsx
│   │   │   │   ├── FilePack.tsx
│   │   │   │   ├── FilePackDark.tsx
│   │   │   │   ├── FilePdf.tsx
│   │   │   │   ├── FilePdfDark.tsx
│   │   │   │   ├── FilePresentation.tsx
│   │   │   │   ├── FilePresentationDark.tsx
│   │   │   │   ├── FileQuestion.tsx
│   │   │   │   ├── FileScript.tsx
│   │   │   │   ├── FileSpreadsheet.tsx
│   │   │   │   ├── FileSpreadsheetDark.tsx
│   │   │   │   ├── FileText.tsx
│   │   │   │   ├── FileUnknown.tsx
│   │   │   │   ├── FileUnknownDark.tsx
│   │   │   │   ├── FileVideo.tsx
│   │   │   │   ├── FileVideoDark.tsx
│   │   │   │   ├── Filter.tsx
│   │   │   │   ├── Flame.tsx
│   │   │   │   ├── FreezeColumn.tsx
│   │   │   │   ├── Frown.tsx
│   │   │   │   ├── Gauge.tsx
│   │   │   │   ├── GiftPerson.tsx
│   │   │   │   ├── GiftPersonDark.tsx
│   │   │   │   ├── Github.tsx
│   │   │   │   ├── GithubLogo.tsx
│   │   │   │   ├── Globe.tsx
│   │   │   │   ├── GoogleLogo.tsx
│   │   │   │   ├── Hash.tsx
│   │   │   │   ├── Heart.tsx
│   │   │   │   ├── HelpCircle.tsx
│   │   │   │   ├── History.tsx
│   │   │   │   ├── Home.tsx
│   │   │   │   ├── Image.tsx
│   │   │   │   ├── ImageGeneration.tsx
│   │   │   │   ├── Import.tsx
│   │   │   │   ├── InIcon.tsx
│   │   │   │   ├── Inbox.tsx
│   │   │   │   ├── Inception.tsx
│   │   │   │   ├── Integration.tsx
│   │   │   │   ├── Kanban.tsx
│   │   │   │   ├── Key.tsx
│   │   │   │   ├── Kwaipilot.tsx
│   │   │   │   ├── Layers.tsx
│   │   │   │   ├── LayoutGrid.tsx
│   │   │   │   ├── LayoutList.tsx
│   │   │   │   ├── LayoutTemplate.tsx
│   │   │   │   ├── License.tsx
│   │   │   │   ├── Line1.tsx
│   │   │   │   ├── Line2.tsx
│   │   │   │   ├── Line3.tsx
│   │   │   │   ├── Lingyiwanwu.tsx
│   │   │   │   ├── Link.tsx
│   │   │   │   ├── LinkedIn.tsx
│   │   │   │   ├── ListChecks.tsx
│   │   │   │   ├── ListOrdered.tsx
│   │   │   │   ├── ListPlus.tsx
│   │   │   │   ├── Loader2.tsx
│   │   │   │   ├── Lock.tsx
│   │   │   │   ├── LongText.tsx
│   │   │   │   ├── MagicAi.tsx
│   │   │   │   ├── Mail.tsx
│   │   │   │   ├── MarkUnread.tsx
│   │   │   │   ├── Maximize2.tsx
│   │   │   │   ├── Meituan.tsx
│   │   │   │   ├── Menu.tsx
│   │   │   │   ├── MessageSquare.tsx
│   │   │   │   ├── MessageSquareDot.tsx
│   │   │   │   ├── Meta.tsx
│   │   │   │   ├── MicrosoftTeams.tsx
│   │   │   │   ├── Minimax.tsx
│   │   │   │   ├── Minimize2.tsx
│   │   │   │   ├── Mistral.tsx
│   │   │   │   ├── Moon.tsx
│   │   │   │   ├── Moonshot.tsx
│   │   │   │   ├── MoreHorizontal.tsx
│   │   │   │   ├── Morph.tsx
│   │   │   │   ├── MousePointerClick.tsx
│   │   │   │   ├── Network.tsx
│   │   │   │   ├── Nvidia.tsx
│   │   │   │   ├── Object.tsx
│   │   │   │   ├── Ollama.tsx
│   │   │   │   ├── OpenRouter.tsx
│   │   │   │   ├── Openai.tsx
│   │   │   │   ├── PackageCheck.tsx
│   │   │   │   ├── PaintBucket.tsx
│   │   │   │   ├── Paperclip.tsx
│   │   │   │   ├── Pencil.tsx
│   │   │   │   ├── Percent.tsx
│   │   │   │   ├── Perplexity.tsx
│   │   │   │   ├── Phone.tsx
│   │   │   │   ├── Play.tsx
│   │   │   │   ├── Plus.tsx
│   │   │   │   ├── PlusCircle.tsx
│   │   │   │   ├── PrimeIntellect.tsx
│   │   │   │   ├── Puzzle.tsx
│   │   │   │   ├── Qrcode.tsx
│   │   │   │   ├── Qwen.tsx
│   │   │   │   ├── Redo2.tsx
│   │   │   │   ├── RefreshCcw.tsx
│   │   │   │   ├── RotateCw.tsx
│   │   │   │   ├── RowExtralTall.tsx
│   │   │   │   ├── RowMedium.tsx
│   │   │   │   ├── RowShort.tsx
│   │   │   │   ├── RowTall.tsx
│   │   │   │   ├── Search.tsx
│   │   │   │   ├── Server.tsx
│   │   │   │   ├── Settings.tsx
│   │   │   │   ├── Share2.tsx
│   │   │   │   ├── Sheet.tsx
│   │   │   │   ├── ShieldCheck.tsx
│   │   │   │   ├── ShieldUser.tsx
│   │   │   │   ├── Sidebar.tsx
│   │   │   │   ├── Slack.tsx
│   │   │   │   ├── SortAsc.tsx
│   │   │   │   ├── Square.tsx
│   │   │   │   ├── Star.tsx
│   │   │   │   ├── Stealth.tsx
│   │   │   │   ├── StretchHorizontal.tsx
│   │   │   │   ├── Sun.tsx
│   │   │   │   ├── SunMedium.tsx
│   │   │   │   ├── Switch.tsx
│   │   │   │   ├── Table2.tsx
│   │   │   │   ├── Teable.tsx
│   │   │   │   ├── TeableAi.tsx
│   │   │   │   ├── TeableNew.tsx
│   │   │   │   ├── ThumbsUp.tsx
│   │   │   │   ├── Token.tsx
│   │   │   │   ├── Translation.tsx
│   │   │   │   ├── Trash.tsx
│   │   │   │   ├── Trash2.tsx
│   │   │   │   ├── TriggerButton.tsx
│   │   │   │   ├── TriggerCreateOrUpdate.tsx
│   │   │   │   ├── TriggerCreateRecord.tsx
│   │   │   │   ├── TriggerEmailReceived.tsx
│   │   │   │   ├── TriggerForm.tsx
│   │   │   │   ├── TriggerRecordMatchesConditions.tsx
│   │   │   │   ├── TriggerSchedule.tsx
│   │   │   │   ├── TriggerUpdateRecord.tsx
│   │   │   │   ├── TriggerWebhook.tsx
│   │   │   │   ├── Twitter.tsx
│   │   │   │   ├── Undo2.tsx
│   │   │   │   ├── User.tsx
│   │   │   │   ├── UserEdit.tsx
│   │   │   │   ├── UserPlus.tsx
│   │   │   │   ├── Users.tsx
│   │   │   │   ├── Vercel.tsx
│   │   │   │   ├── Video.tsx
│   │   │   │   ├── Voyage.tsx
│   │   │   │   ├── Webhook.tsx
│   │   │   │   ├── WorkflowLogic.tsx
│   │   │   │   ├── Wrench.tsx
│   │   │   │   ├── X.tsx
│   │   │   │   ├── Xai.tsx
│   │   │   │   ├── Xiaomi.tsx
│   │   │   │   ├── Zap.tsx
│   │   │   │   ├── Zapier.tsx
│   │   │   │   ├── Zhipu.tsx
│   │   │   │   ├── ZoomIn.tsx
│   │   │   │   └── ZoomOut.tsx
│   │   │   └── index.ts
│   │   ├── tsconfig.eslint.json
│   │   └── tsconfig.json
│   ├── openapi/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── openapi.iml
│   │   ├── LICENSE
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── access-token/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── refresh.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── admin/
│   │   │   │   ├── enterprise-license/
│   │   │   │   │   ├── get-status.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── plugin/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── publish.ts
│   │   │   │   │   └── unpublish.ts
│   │   │   │   └── setting/
│   │   │   │       ├── ai-key-stats.ts
│   │   │   │       ├── batch-test-llm.ts
│   │   │   │       ├── get-public.ts
│   │   │   │       ├── get.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── key.enum.ts
│   │   │   │       ├── pricing.spec.ts
│   │   │   │       ├── set-transport-config.ts
│   │   │   │       ├── test-api-key.ts
│   │   │   │       ├── test-llm.ts
│   │   │   │       ├── test-public-access.ts
│   │   │   │       ├── update.ts
│   │   │   │       └── upload-logo.ts
│   │   │   ├── aggregation/
│   │   │   │   ├── get-aggregation.ts
│   │   │   │   ├── get-calendar-daily-collection.ts
│   │   │   │   ├── get-group-points.ts
│   │   │   │   ├── get-record-index.ts
│   │   │   │   ├── get-row-count.ts
│   │   │   │   ├── get-search-by-index.ts
│   │   │   │   ├── get-search-count.ts
│   │   │   │   ├── get-task-status-collection.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── type.ts
│   │   │   ├── ai/
│   │   │   │   ├── generate-stream.ts
│   │   │   │   ├── get-ai-disable-actions.ts
│   │   │   │   ├── get-config.ts
│   │   │   │   ├── image-model-config.ts
│   │   │   │   └── index.ts
│   │   │   ├── attachment/
│   │   │   │   ├── index.ts
│   │   │   │   ├── notify.ts
│   │   │   │   ├── read-file.ts
│   │   │   │   ├── signature.ts
│   │   │   │   ├── upload-file.ts
│   │   │   │   └── utils.ts
│   │   │   ├── auth/
│   │   │   │   ├── add-password.ts
│   │   │   │   ├── change-email.ts
│   │   │   │   ├── change-password.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── reset-password.ts
│   │   │   │   ├── send-change-email-code.ts
│   │   │   │   ├── send-reset-password-email.ts
│   │   │   │   ├── send-signup-verification-code.ts
│   │   │   │   ├── signin.ts
│   │   │   │   ├── signout.ts
│   │   │   │   ├── signup.ts
│   │   │   │   ├── temp-token.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── user-me.ts
│   │   │   │   ├── user.ts
│   │   │   │   └── waitlist/
│   │   │   │       ├── get.ts
│   │   │   │       ├── index.ts
│   │   │   │       ├── invite-code.ts
│   │   │   │       ├── invite.ts
│   │   │   │       └── join.ts
│   │   │   ├── automation/
│   │   │   │   ├── index.ts
│   │   │   │   └── workflow/
│   │   │   │       └── create.ts
│   │   │   ├── axios.ts
│   │   │   ├── base/
│   │   │   │   ├── all-list.ts
│   │   │   │   ├── collaborator-add.ts
│   │   │   │   ├── collaborator-delete.ts
│   │   │   │   ├── collaborator-get-list-user.ts
│   │   │   │   ├── collaborator-get-list.ts
│   │   │   │   ├── collaborator-update.ts
│   │   │   │   ├── create-from-template.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── erd.ts
│   │   │   │   ├── export.ts
│   │   │   │   ├── get-permission.ts
│   │   │   │   ├── get-shared-base.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── import.spec.ts
│   │   │   │   ├── import.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── invitation-create-link.ts
│   │   │   │   ├── invitation-delete-link.ts
│   │   │   │   ├── invitation-email.ts
│   │   │   │   ├── invitation-get-link-list.ts
│   │   │   │   ├── invitation-update-link.ts
│   │   │   │   ├── move.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── publish.ts
│   │   │   │   ├── query-data/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── route.ts
│   │   │   │   │   └── types.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   └── update.ts
│   │   │   ├── base-node/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── folder/
│   │   │   │   │   ├── create.ts
│   │   │   │   │   ├── delete.ts
│   │   │   │   │   └── update.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-tree.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── move.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── base-share/
│   │   │   │   ├── auth.ts
│   │   │   │   ├── copy.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── refresh.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── billing/
│   │   │   │   ├── index.ts
│   │   │   │   └── subscription/
│   │   │   │       ├── get-subscription-summary-list.ts
│   │   │   │       ├── get-subscription-summary.ts
│   │   │   │       └── index.ts
│   │   │   ├── comment/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-attachment-url.ts
│   │   │   │   ├── get-count.ts
│   │   │   │   ├── get-counts-by-query.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── reaction/
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── create-reaction.ts
│   │   │   │   │   ├── delete-reaction.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── subscribe/
│   │   │   │   │   ├── create-subscribe.ts
│   │   │   │   │   ├── delete-subscribe.ts
│   │   │   │   │   ├── get-subscribe.ts
│   │   │   │   │   └── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── dashboard/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate-installed.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-remove.ts
│   │   │   │   ├── plugin-rename.ts
│   │   │   │   ├── plugin-update-storage.ts
│   │   │   │   ├── rename.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update-layout.ts
│   │   │   ├── db-connection/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get.ts
│   │   │   │   └── index.ts
│   │   │   ├── export/
│   │   │   │   ├── export-csv.ts
│   │   │   │   └── index.ts
│   │   │   ├── field/
│   │   │   │   ├── auto-fill-field.ts
│   │   │   │   ├── convert.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete-list.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── filter-link-records.ts
│   │   │   │   ├── get-delete-references.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── stop-fill-field.ts
│   │   │   │   └── update.ts
│   │   │   ├── formula/
│   │   │   │   ├── ai.ts
│   │   │   │   ├── func-define.ts
│   │   │   │   └── index.ts
│   │   │   ├── generate.schema.ts
│   │   │   ├── import/
│   │   │   │   ├── analyze.ts
│   │   │   │   ├── constant.ts
│   │   │   │   ├── import-status.ts
│   │   │   │   ├── import-table.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── inplace-import-table.ts
│   │   │   │   └── types.ts
│   │   │   ├── index.ts
│   │   │   ├── integrity/
│   │   │   │   ├── index.ts
│   │   │   │   ├── link-check.ts
│   │   │   │   └── link-fix.ts
│   │   │   ├── invitation/
│   │   │   │   ├── accept.ts
│   │   │   │   └── index.ts
│   │   │   ├── mail/
│   │   │   │   ├── index.ts
│   │   │   │   ├── test.ts
│   │   │   │   └── types.ts
│   │   │   ├── notification/
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── read-all.ts
│   │   │   │   ├── unread-count.ts
│   │   │   │   └── update-status.ts
│   │   │   ├── oauth/
│   │   │   │   ├── authorized-list.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── decision-info.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── revoke-token.ts
│   │   │   │   ├── revoke.ts
│   │   │   │   ├── secret-delete.ts
│   │   │   │   ├── secret-generate.ts
│   │   │   │   └── update.ts
│   │   │   ├── openapi-snippet/
│   │   │   │   ├── index.js
│   │   │   │   └── openapi-to-har.js
│   │   │   ├── organization/
│   │   │   │   ├── departments.ts
│   │   │   │   ├── get-me.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── user-get.ts
│   │   │   ├── pin/
│   │   │   │   ├── add.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update-order.ts
│   │   │   ├── plan/
│   │   │   │   ├── index.ts
│   │   │   │   ├── plan-convert.ts
│   │   │   │   ├── plan-create.ts
│   │   │   │   ├── plan-delete.ts
│   │   │   │   └── plan.ts
│   │   │   ├── plugin/
│   │   │   │   ├── chart/
│   │   │   │   │   ├── dashboard-query.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── plugin-panel-query.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-auth-code.ts
│   │   │   │   ├── get-center-list.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-token.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── refresh-token.ts
│   │   │   │   ├── regenerate-secret.ts
│   │   │   │   ├── submit.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── unpublish.ts
│   │   │   │   └── update.ts
│   │   │   ├── plugin-context-menu/
│   │   │   │   ├── index.ts
│   │   │   │   ├── plugin-get-list.ts
│   │   │   │   ├── plugin-get-storage.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-move.ts
│   │   │   │   ├── plugin-remove.ts
│   │   │   │   ├── plugin-rename.ts
│   │   │   │   └── plugin-update-storage.ts
│   │   │   ├── plugin-panel/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate-panel-installed.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-remove.ts
│   │   │   │   ├── plugin-rename.ts
│   │   │   │   ├── plugin-update-storage.ts
│   │   │   │   ├── rename.ts
│   │   │   │   └── update-layout.ts
│   │   │   ├── query/
│   │   │   │   ├── index.ts
│   │   │   │   └── save-query-params.ts
│   │   │   ├── record/
│   │   │   │   ├── README.ts
│   │   │   │   ├── auto-fill-cell.ts
│   │   │   │   ├── button-click.ts
│   │   │   │   ├── button-reset.ts
│   │   │   │   ├── constant.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete-list.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── form-submit.ts
│   │   │   │   ├── get-collaborators.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-record-history.ts
│   │   │   │   ├── get-record-list-history.ts
│   │   │   │   ├── get-record-status.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── insert-attachment.ts
│   │   │   │   ├── record.schema.spec.ts
│   │   │   │   ├── update-records.ts
│   │   │   │   ├── update.ts
│   │   │   │   └── upload-attachment.ts
│   │   │   ├── selection/
│   │   │   │   ├── clear.ts
│   │   │   │   ├── copy.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── paste.ts
│   │   │   │   ├── range.ts
│   │   │   │   └── temporary-paste.ts
│   │   │   ├── share/
│   │   │   │   ├── index.ts
│   │   │   │   ├── view-aggregations.ts
│   │   │   │   ├── view-auth.ts
│   │   │   │   ├── view-button-click.ts
│   │   │   │   ├── view-calendar-daily-collection.ts
│   │   │   │   ├── view-collaborators.ts
│   │   │   │   ├── view-copy.ts
│   │   │   │   ├── view-form-submit.ts
│   │   │   │   ├── view-get.ts
│   │   │   │   ├── view-group-points.ts
│   │   │   │   ├── view-link-records.ts
│   │   │   │   ├── view-records.ts
│   │   │   │   ├── view-row-count.ts
│   │   │   │   ├── view-search-count.ts
│   │   │   │   └── view-search-index.ts
│   │   │   ├── space/
│   │   │   │   ├── collaborator-add.ts
│   │   │   │   ├── collaborator-delete.ts
│   │   │   │   ├── collaborator-get-list.ts
│   │   │   │   ├── collaborator-update.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-base-list.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── integration-create.ts
│   │   │   │   ├── integration-delete.ts
│   │   │   │   ├── integration-get-list.ts
│   │   │   │   ├── integration-update.ts
│   │   │   │   ├── invitation-create-link.ts
│   │   │   │   ├── invitation-delete-link.ts
│   │   │   │   ├── invitation-email.ts
│   │   │   │   ├── invitation-get-link-list.ts
│   │   │   │   ├── invitation-update-link.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── search.ts
│   │   │   │   ├── test-llm-integration.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── table/
│   │   │   │   ├── create.ts
│   │   │   │   ├── default-view-id.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── get-abnormal-index.ts
│   │   │   │   ├── get-activated-index.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get-permission.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── permanent-delete.ts
│   │   │   │   ├── repair-table-index.ts
│   │   │   │   ├── toggle-table-index.ts
│   │   │   │   ├── update-db-table-name.ts
│   │   │   │   ├── update-description.ts
│   │   │   │   ├── update-icon.ts
│   │   │   │   ├── update-name.ts
│   │   │   │   └── update-order.ts
│   │   │   ├── template/
│   │   │   │   ├── category/
│   │   │   │   │   ├── create.ts
│   │   │   │   │   ├── delete.ts
│   │   │   │   │   ├── get.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── update-order.ts
│   │   │   │   │   └── update.ts
│   │   │   │   ├── create-snapshot.ts
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-by-base-id.ts
│   │   │   │   ├── get-permalink.ts
│   │   │   │   ├── get-published.ts
│   │   │   │   ├── get-template-detail.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── increment-visit.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── pin-top.ts
│   │   │   │   ├── unpublish.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   └── update.ts
│   │   │   ├── trash/
│   │   │   │   ├── delete.ts
│   │   │   │   ├── get-items.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── reset-items.ts
│   │   │   │   ├── restore.ts
│   │   │   │   └── types.ts
│   │   │   ├── types.ts
│   │   │   ├── undo-redo/
│   │   │   │   ├── index.ts
│   │   │   │   ├── redo.ts
│   │   │   │   └── undo.ts
│   │   │   ├── unsubscribe/
│   │   │   │   ├── export-list.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── import-list.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update.ts
│   │   │   ├── usage/
│   │   │   │   ├── get-base-usage.ts
│   │   │   │   ├── get-instance-usage.ts
│   │   │   │   ├── get-space-usage.ts
│   │   │   │   └── index.ts
│   │   │   ├── user/
│   │   │   │   ├── index.ts
│   │   │   │   ├── last-visit/
│   │   │   │   │   ├── get-base-node.ts
│   │   │   │   │   ├── get.ts
│   │   │   │   │   ├── getMap.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── list-base.ts
│   │   │   │   │   └── update.ts
│   │   │   │   ├── update-avatar.ts
│   │   │   │   ├── update-lang.ts
│   │   │   │   ├── update-name.ts
│   │   │   │   └── update-notify-meta.ts
│   │   │   ├── user-integration/
│   │   │   │   ├── delete.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── list.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── update-name.ts
│   │   │   ├── utils.ts
│   │   │   ├── view/
│   │   │   │   ├── create.ts
│   │   │   │   ├── delete.ts
│   │   │   │   ├── duplicate.ts
│   │   │   │   ├── filter-link-records.ts
│   │   │   │   ├── get-list.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── manual-sort.ts
│   │   │   │   ├── plugin-get.ts
│   │   │   │   ├── plugin-install.ts
│   │   │   │   ├── plugin-update-storage.ts
│   │   │   │   ├── refresh-share-id.ts
│   │   │   │   ├── share-disable.ts
│   │   │   │   ├── share-enable.ts
│   │   │   │   ├── update-description.ts
│   │   │   │   ├── update-fields-column-meta.ts
│   │   │   │   ├── update-filter.ts
│   │   │   │   ├── update-group.ts
│   │   │   │   ├── update-locked.ts
│   │   │   │   ├── update-name.ts
│   │   │   │   ├── update-options.ts
│   │   │   │   ├── update-order.ts
│   │   │   │   ├── update-record-order.ts
│   │   │   │   ├── update-share-meta.ts
│   │   │   │   └── update-sort.ts
│   │   │   └── zod.ts
│   │   ├── tsconfig.build.json
│   │   ├── tsconfig.eslint.json
│   │   ├── tsconfig.json
│   │   ├── vitest.config.ts
│   │   └── vitest.setup.js
│   ├── sdk/
│   │   ├── .eslintrc.cjs
│   │   ├── .gitignore
│   │   ├── .idea/
│   │   │   ├── modules.xml
│   │   │   └── sdk.iml
│   │   ├── LICENSE
│   │   ├── components.json
│   │   ├── config/
│   │   │   └── tests/
│   │   │       └── setupVitest.ts
│   │   ├── lint-staged.config.js
│   │   ├── package.json
│   │   ├── plate-components.json
│   │   ├── src/
│   │   │   ├── components/
│   │   │   │   ├── FileZone.tsx
│   │   │   │   ├── ReadOnlyTip.tsx
│   │   │   │   ├── base-query/
│   │   │   │   │   ├── FormItem.tsx
│   │   │   │   │   ├── QueryBuilder.tsx
│   │   │   │   │   ├── QueryEditor.tsx
│   │   │   │   │   ├── QueryEditorContainer.tsx
│   │   │   │   │   ├── QueryFom.tsx
│   │   │   │   │   ├── QueryOperators.tsx
│   │   │   │   │   ├── common/
│   │   │   │   │   │   ├── ContextColumnCommand.tsx
│   │   │   │   │   │   ├── ContextColumnSelector.tsx
│   │   │   │   │   │   ├── NewPopover.tsx
│   │   │   │   │   │   └── useAllColumns.ts
│   │   │   │   │   ├── constant.ts
│   │   │   │   │   ├── context/
│   │   │   │   │   │   ├── QueryEditorContext.tsx
│   │   │   │   │   │   ├── QueryEditorProvider.tsx
│   │   │   │   │   │   ├── QueryFormContext.tsx
│   │   │   │   │   │   └── QueryFormProvider.tsx
│   │   │   │   │   ├── editors/
│   │   │   │   │   │   ├── QueryAggregation.tsx
│   │   │   │   │   │   ├── QueryFilter/
│   │   │   │   │   │   │   ├── FieldComponent.tsx
│   │   │   │   │   │   │   ├── OperatorComponent.tsx
│   │   │   │   │   │   │   ├── QueryFilter.tsx
│   │   │   │   │   │   │   ├── ValueComponent.tsx
│   │   │   │   │   │   │   └── types.ts
│   │   │   │   │   │   ├── QueryGroup.tsx
│   │   │   │   │   │   ├── QueryJoin.tsx
│   │   │   │   │   │   ├── QueryOrder.tsx
│   │   │   │   │   │   ├── QuerySelect.tsx
│   │   │   │   │   │   └── types.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── query-from/
│   │   │   │   │   │   ├── QueryFrom.tsx
│   │   │   │   │   │   ├── QueryFromValue.tsx
│   │   │   │   │   │   └── useQueryFromTableValidation.ts
│   │   │   │   │   ├── useQueryContext.ts
│   │   │   │   │   └── useQueryOperatorsStatic.ts
│   │   │   │   ├── billing/
│   │   │   │   │   └── store/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       └── usage-limit-modal.ts
│   │   │   │   ├── cell-value/
│   │   │   │   │   ├── CellValue.tsx
│   │   │   │   │   ├── cell-attachment/
│   │   │   │   │   │   ├── CellAttachment.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-button/
│   │   │   │   │   │   ├── CellButton.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-checkbox/
│   │   │   │   │   │   ├── CellCheckbox.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-date/
│   │   │   │   │   │   ├── CellDate.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-link/
│   │   │   │   │   │   ├── CellLink.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-markdown/
│   │   │   │   │   │   ├── CellMarkdown.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-number/
│   │   │   │   │   │   ├── CellNumber.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-rating/
│   │   │   │   │   │   ├── CellRating.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-select/
│   │   │   │   │   │   ├── CellSelect.tsx
│   │   │   │   │   │   ├── SelectTag.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-text/
│   │   │   │   │   │   ├── CellText.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── cell-user/
│   │   │   │   │   │   ├── CellUser.tsx
│   │   │   │   │   │   ├── UserAvatar.tsx
│   │   │   │   │   │   ├── UserTag.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── components/
│   │   │   │   │   │   ├── OverflowTooltip.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── useTagVisibility.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── cell-value-editor/
│   │   │   │   │   ├── CellEditor.tsx
│   │   │   │   │   ├── CellEditorMain.tsx
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── type.ts
│   │   │   │   ├── collaborator/
│   │   │   │   │   ├── CollaboratorWithHoverCard.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── color/
│   │   │   │   │   ├── Color.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── comment/
│   │   │   │   │   ├── CommentHeader.tsx
│   │   │   │   │   ├── CommentPanel.tsx
│   │   │   │   │   ├── comment-editor/
│   │   │   │   │   │   ├── CommentEditor.tsx
│   │   │   │   │   │   ├── CommentQuote.tsx
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── transform.tsx
│   │   │   │   │   ├── comment-list/
│   │   │   │   │   │   ├── CommentContent.tsx
│   │   │   │   │   │   ├── CommentItem.tsx
│   │   │   │   │   │   ├── CommentList.tsx
│   │   │   │   │   │   ├── CommentSkeleton.tsx
│   │   │   │   │   │   ├── context.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── node/
│   │   │   │   │   │   │   ├── block-element/
│   │   │   │   │   │   │   │   ├── Image.tsx
│   │   │   │   │   │   │   │   ├── Paragraph.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   ├── inline-element/
│   │   │   │   │   │   │   │   ├── Link.tsx
│   │   │   │   │   │   │   │   ├── MentionUser.tsx
│   │   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   │   └── type.ts
│   │   │   │   │   │   ├── reaction/
│   │   │   │   │   │   │   ├── Reaction.tsx
│   │   │   │   │   │   │   ├── ReactionPicker.tsx
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── useCommentPatchListener.ts
│   │   │   │   │   │   └── useIsMe.ts
│   │   │   │   │   ├── context.ts
│   │   │   │   │   ├── hooks/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── useBaseId.ts
│   │   │   │   │   │   ├── useRecordCommentCount.ts
│   │   │   │   │   │   └── useRecordId.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── types.ts
│   │   │   │   │   └── useCommentStore.ts
│   │   │   │   ├── create-record/
│   │   │   │   │   ├── CreateRecordModal.tsx
│   │   │   │   │   └── index.ts
│   │   │   │   ├── editor/
│   │   │   │   │   ├── attachment/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── EditorMain.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── upload-attachment/
│   │   │   │   │   │   │   ├── AttachmentItem.tsx
│   │   │   │   │   │   │   ├── FileInput.tsx
│   │   │   │   │   │   │   ├── UploadAttachment.tsx
│   │   │   │   │   │   │   ├── UploadAttachmentView.tsx
│   │   │   │   │   │   │   ├── UploadingFile.tsx
│   │   │   │   │   │   │   ├── hooks/
│   │   │   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   │   │   ├── useCellAttachmentUpload.ts
│   │   │   │   │   │   │   │   ├── useLocalAttachmentUpload.ts
│   │   │   │   │   │   │   │   ├── usePendingAttachmentUpload.spec.tsx
│   │   │   │   │   │   │   │   └── usePendingAttachmentUpload.ts
│   │   │   │   │   │   │   ├── types.ts
│   │   │   │   │   │   │   └── uploadManage.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── button/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── checkbox/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── date/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── EditorMain.tsx
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── utils.ts
│   │   │   │   │   ├── formula/
│   │   │   │   │   │   ├── Editor.tsx
│   │   │   │   │   │   ├── components/
│   │   │   │   │   │   │   ├── AiPromptContainer.tsx
│   │   │   │   │   │   │   ├── CodeEditor.tsx
│   │   │   │   │   │   │   ├── FunctionGuide.tsx
│   │   │   │   │   │   │   ├── FunctionHelper.tsx
│   │   │   │   │   │   │   └── index.ts
│   │   │   │   │   │   ├── constants.ts
│   │   │   │   │   │   ├── extensions/
│   │   │   │   │   │   │   ├── autocomplete.ts
│   │   │   │   │   │   │   
Download .txt
Showing preview only (927K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (9517 symbols across 1621 files)

FILE: apps/nestjs-backend/src/app.module.ts
  constant CONDITIONAL_MODULE_TIMEOUT (line 60) | const CONDITIONAL_MODULE_TIMEOUT = isTestOrCI ? 60000 : 5000;
  class AppModule (line 143) | class AppModule {
    method register (line 144) | static register(customModuleMetadata: ModuleMetadata) {

FILE: apps/nestjs-backend/src/bootstrap.ts
  function setUpAppMiddleware (line 19) | async function setUpAppMiddleware(app: INestApplication, configService: ...
  function bootstrap (line 42) | async function bootstrap() {
  function getAvailablePort (line 86) | async function getAvailablePort(dPort: number | string): Promise<number> {

FILE: apps/nestjs-backend/src/cache/cache.module.ts
  type CacheModuleOptions (line 5) | interface CacheModuleOptions {
  class CacheModule (line 16) | class CacheModule extends CacheModuleClass {
    method register (line 17) | static register(options: typeof OPTIONS_TYPE): DynamicModule {

FILE: apps/nestjs-backend/src/cache/cache.service.ts
  class CacheService (line 9) | class CacheService<T extends ICacheStore = ICacheStore> {
    method constructor (line 11) | constructor(private readonly cacheManager: Keyv<any>) {}
    method getKeyv (line 14) | getKeyv(): Keyv<any> {
    method getRedisClient (line 22) | private getRedisClient(): Redis | undefined {
    method setnx (line 40) | async setnx<TKey extends keyof T>(
    method incr (line 69) | async incr<TKey extends keyof T>(key: TKey, ttlSeconds?: number): Prom...
    method warnNotSetTTL (line 90) | private warnNotSetTTL(key: string, ttl?: number) {
    method get (line 96) | async get<TKey extends keyof T>(key: TKey): Promise<T[TKey] | undefine...
    method set (line 100) | async set<TKey extends keyof T>(
    method setDetail (line 116) | async setDetail<TKey extends keyof T>(
    method del (line 126) | async del<TKey extends keyof T>(key: TKey): Promise<void> {
    method getMany (line 130) | async getMany<TKey extends keyof T>(keys: TKey[]): Promise<Array<T[TKe...
    method expire (line 138) | async expire<TKey extends keyof T>(key: TKey, ttl: number | string): P...

FILE: apps/nestjs-backend/src/cache/types.ts
  type ICacheStore (line 9) | interface ICacheStore {
  type IAttachmentSignatureCache (line 52) | interface IAttachmentSignatureCache {
  type IAttachmentUploadCache (line 58) | interface IAttachmentUploadCache {
  type IAttachmentLocalTokenCache (line 64) | interface IAttachmentLocalTokenCache {
  type IAttachmentPreviewCache (line 70) | interface IAttachmentPreviewCache {
  type IOauth2State (line 75) | interface IOauth2State {
  type IResetPasswordEmailCache (line 79) | interface IResetPasswordEmailCache {
  type IOAuthCodeState (line 83) | interface IOAuthCodeState {
  type IOAuthTxnStore (line 96) | interface IOAuthTxnStore {
  type OperationName (line 107) | enum OperationName {
  type IUndoRedoOperationBase (line 122) | interface IUndoRedoOperationBase {
  type IUpdateRecordsOperation (line 130) | interface IUpdateRecordsOperation extends IUndoRedoOperationBase {
  type IUpdateRecordsOrderOperation (line 148) | interface IUpdateRecordsOrderOperation extends IUndoRedoOperationBase {
  type ICreateRecordsOperation (line 165) | interface ICreateRecordsOperation extends IUndoRedoOperationBase {
  type IDeleteRecordsOperation (line 175) | interface IDeleteRecordsOperation extends Omit<ICreateRecordsOperation, ...
  type IConvertFieldOperation (line 179) | interface IConvertFieldOperation extends IUndoRedoOperationBase {
  type IConvertFieldV2Operation (line 197) | interface IConvertFieldV2Operation extends IUndoRedoOperationBase {
  type ICreateFieldsOperation (line 210) | interface ICreateFieldsOperation extends IUndoRedoOperationBase {
  type IDeleteFieldsOperation (line 224) | interface IDeleteFieldsOperation extends Omit<ICreateFieldsOperation, 'n...
  type IPasteSelectionOperation (line 228) | interface IPasteSelectionOperation extends IUndoRedoOperationBase {
  type ICreateViewOperation (line 244) | interface ICreateViewOperation extends IUndoRedoOperationBase {
  type IDeleteViewOperation (line 254) | interface IDeleteViewOperation extends IUndoRedoOperationBase {
  type IUpdateViewOperation (line 262) | interface IUpdateViewOperation extends IUndoRedoOperationBase {
  type IUndoRedoOperation (line 278) | type IUndoRedoOperation =
  type IPluginAuthStore (line 291) | interface IPluginAuthStore {

FILE: apps/nestjs-backend/src/configs/auth.config.ts
  type IAuthConfig (line 81) | type IAuthConfig = ConfigType<typeof authConfig>;

FILE: apps/nestjs-backend/src/configs/base.config.ts
  type IBaseConfig (line 23) | type IBaseConfig = ConfigType<typeof baseConfig>;

FILE: apps/nestjs-backend/src/configs/bootstrap.config.ts
  type INextJsConfig (line 24) | type INextJsConfig = ConfigType<typeof nextJsConfig>;
  type ISecurityWebConfig (line 25) | type ISecurityWebConfig = ConfigType<typeof securityWebConfig>;
  type IApiDocConfig (line 26) | type IApiDocConfig = ConfigType<typeof apiDocConfig>;

FILE: apps/nestjs-backend/src/configs/cache.config.ts
  type ICacheConfig (line 18) | type ICacheConfig = ConfigType<typeof cacheConfig>;

FILE: apps/nestjs-backend/src/configs/config.module.ts
  class ConfigModule (line 32) | class ConfigModule {
    method register (line 33) | static register(): DynamicModule {

FILE: apps/nestjs-backend/src/configs/config.spec.ts
  type IMockConfigService (line 6) | type IMockConfigService = Partial<ConfigService>;

FILE: apps/nestjs-backend/src/configs/logger.config.ts
  type ILoggerConfig (line 13) | type ILoggerConfig = ConfigType<typeof loggerConfig>;

FILE: apps/nestjs-backend/src/configs/mail.config.ts
  type IMailConfig (line 40) | type IMailConfig = ConfigType<typeof mailConfig>;

FILE: apps/nestjs-backend/src/configs/oauth.config.ts
  type IOAuthConfig (line 18) | type IOAuthConfig = ConfigType<typeof oauthConfig>;

FILE: apps/nestjs-backend/src/configs/storage.ts
  type IStorageConfig (line 50) | type IStorageConfig = ConfigType<typeof storageConfig>;

FILE: apps/nestjs-backend/src/configs/threshold.config.ts
  type IThresholdConfig (line 58) | type IThresholdConfig = ConfigType<typeof thresholdConfig>;

FILE: apps/nestjs-backend/src/configs/trash.config.ts
  type ITrashConfig (line 26) | type ITrashConfig = ReturnType<typeof trashConfig>;

FILE: apps/nestjs-backend/src/const.ts
  constant X_REQUEST_ID (line 1) | const X_REQUEST_ID = 'X-Request-Id';
  constant AUTH_SESSION_COOKIE_NAME (line 2) | const AUTH_SESSION_COOKIE_NAME = 'auth_session';

FILE: apps/nestjs-backend/src/custom.exception.ts
  class CustomHttpException (line 7) | class CustomHttpException extends HttpException {
    method constructor (line 11) | constructor(
  class TemplateAppTokenNotAllowedException (line 53) | class TemplateAppTokenNotAllowedException extends HttpException {
    method constructor (line 54) | constructor() {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-function.abstract.ts
  method constructor (line 11) | constructor(
  method dbTableName (line 26) | get dbTableName() {
  method tableAlias (line 30) | get tableAlias() {
  method compiler (line 34) | compiler(builderClient: Knex.QueryBuilder, aggFunc: StatisticsFunc, alia...
  method count (line 95) | count(): string {
  method empty (line 99) | empty(): string {
  method filled (line 103) | filled(): string {
  method unique (line 107) | unique(): string {
  method max (line 111) | max(): string {
  method min (line 115) | min(): string {
  method sum (line 119) | sum(): string {
  method average (line 123) | average(): string {
  method checked (line 127) | checked(): string {
  method unChecked (line 131) | unChecked(): string {
  method earliestDate (line 145) | earliestDate(): string {
  method latestDate (line 149) | latestDate(): string {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-function.interface.ts
  type IAggregationFunctionHandler (line 1) | type IAggregationFunctionHandler = () => string;
  type IAggregationFunctionInterface (line 3) | interface IAggregationFunctionInterface {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-query.abstract.ts
  method constructor (line 12) | constructor(
  method dbTableName (line 21) | get dbTableName() {
  method tableAlias (line 25) | get tableAlias() {
  method appendBuilder (line 29) | appendBuilder(): Knex.QueryBuilder {
  method validAggregationField (line 90) | private validAggregationField(
  method getAggregationAdapter (line 112) | private getAggregationAdapter(field: FieldCore): AbstractAggregationFunc...

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-query.interface.ts
  type IAggregationQueryInterface (line 3) | interface IAggregationQueryInterface {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/postgres/aggregation-function.postgres.ts
  class AggregationFunctionPostgres (line 5) | class AggregationFunctionPostgres extends AbstractAggregationFunction {
    method unique (line 6) | unique(): string {
    method percentUnique (line 18) | percentUnique(): string {
    method dateRangeOfDays (line 34) | dateRangeOfDays(): string {
    method dateRangeOfMonths (line 38) | dateRangeOfMonths(): string {
    method totalAttachmentSize (line 42) | totalAttachmentSize(): string {
    method percentEmpty (line 52) | percentEmpty(): string {
    method percentFilled (line 58) | percentFilled(): string {
    method checked (line 64) | checked(): string {
    method unChecked (line 70) | unChecked(): string {
    method percentChecked (line 78) | percentChecked(): string {
    method percentUnChecked (line 86) | percentUnChecked(): string {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/postgres/aggregation-query.postgres.ts
  class AggregationQueryPostgres (line 7) | class AggregationQueryPostgres extends AbstractAggregationQuery {
    method coreAggregation (line 8) | private coreAggregation(field: FieldCore): AggregationFunctionPostgres {
    method booleanAggregation (line 16) | booleanAggregation(field: FieldCore): AggregationFunctionPostgres {
    method numberAggregation (line 20) | numberAggregation(field: FieldCore): AggregationFunctionPostgres {
    method dateTimeAggregation (line 24) | dateTimeAggregation(field: FieldCore): AggregationFunctionPostgres {
    method stringAggregation (line 28) | stringAggregation(field: FieldCore): AggregationFunctionPostgres {
    method jsonAggregation (line 32) | jsonAggregation(field: FieldCore): AggregationFunctionPostgres {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/postgres/multiple-value/multiple-value-aggregation.adapter.ts
  class MultipleValueAggregationAdapter (line 3) | class MultipleValueAggregationAdapter extends AggregationFunctionPostgres {
    method toNumericSafe (line 4) | private toNumericSafe(columnExpression: string): string {
    method unique (line 10) | unique(): string {
    method max (line 19) | max(): string {
    method min (line 28) | min(): string {
    method sum (line 37) | sum(): string {
    method average (line 46) | average(): string {
    method percentUnique (line 55) | percentUnique(): string {
    method dateRangeOfDays (line 64) | dateRangeOfDays(): string {
    method dateRangeOfMonths (line 73) | dateRangeOfMonths(): string {
    method checked (line 82) | checked(): string {
    method unChecked (line 88) | unChecked(): string {
    method percentChecked (line 96) | percentChecked(): string {
    method percentUnChecked (line 104) | percentUnChecked(): string {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/postgres/single-value/single-value-aggregation.adapter.ts
  class SingleValueAggregationAdapter (line 3) | class SingleValueAggregationAdapter extends AggregationFunctionPostgres {
    method dateRangeOfDays (line 4) | dateRangeOfDays(): string {
    method dateRangeOfMonths (line 10) | dateRangeOfMonths(): string {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/aggregation-function.sqlite.ts
  class AggregationFunctionSqlite (line 5) | class AggregationFunctionSqlite extends AbstractAggregationFunction {
    method unique (line 6) | unique(): string {
    method percentUnique (line 18) | percentUnique(): string {
    method dateRangeOfDays (line 35) | dateRangeOfDays(): string {
    method dateRangeOfMonths (line 39) | dateRangeOfMonths(): string {
    method totalAttachmentSize (line 43) | totalAttachmentSize(): string {
    method percentEmpty (line 53) | percentEmpty(): string {
    method percentFilled (line 59) | percentFilled(): string {
    method checked (line 65) | checked(): string {
    method unChecked (line 69) | unChecked(): string {
    method percentChecked (line 77) | percentChecked(): string {
    method percentUnChecked (line 85) | percentUnChecked(): string {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/aggregation-query.sqlite.ts
  class AggregationQuerySqlite (line 7) | class AggregationQuerySqlite extends AbstractAggregationQuery {
    method coreAggregation (line 8) | private coreAggregation(field: FieldCore): AggregationFunctionSqlite {
    method booleanAggregation (line 16) | booleanAggregation(field: FieldCore): AggregationFunctionSqlite {
    method numberAggregation (line 20) | numberAggregation(field: FieldCore): AggregationFunctionSqlite {
    method dateTimeAggregation (line 24) | dateTimeAggregation(field: FieldCore): AggregationFunctionSqlite {
    method stringAggregation (line 28) | stringAggregation(field: FieldCore): AggregationFunctionSqlite {
    method jsonAggregation (line 32) | jsonAggregation(field: FieldCore): AggregationFunctionSqlite {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/multiple-value/multiple-value-aggregation.adapter.ts
  class MultipleValueAggregationAdapter (line 3) | class MultipleValueAggregationAdapter extends AggregationFunctionSqlite {
    method unique (line 4) | unique(): string {
    method max (line 13) | max(): string {
    method min (line 22) | min(): string {
    method sum (line 31) | sum(): string {
    method average (line 40) | average(): string {
    method percentUnique (line 49) | percentUnique(): string {
    method dateRangeOfDays (line 58) | dateRangeOfDays(): string {
    method dateRangeOfMonths (line 67) | dateRangeOfMonths(): string {
    method checked (line 76) | checked(): string {
    method unChecked (line 84) | unChecked(): string {
    method percentChecked (line 92) | percentChecked(): string {
    method percentUnChecked (line 100) | percentUnChecked(): string {

FILE: apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/single-value/single-value-aggregation.adapter.ts
  class SingleValueAggregationAdapter (line 3) | class SingleValueAggregationAdapter extends AggregationFunctionSqlite {
    method dateRangeOfDays (line 4) | dateRangeOfDays(): string {
    method dateRangeOfMonths (line 12) | dateRangeOfMonths(): string {

FILE: apps/nestjs-backend/src/db-provider/base-query/abstract.ts
  method constructor (line 4) | constructor(protected readonly knex: Knex) {}

FILE: apps/nestjs-backend/src/db-provider/base-query/base-query.postgres.ts
  class BaseQueryPostgres (line 4) | class BaseQueryPostgres extends BaseQueryAbstract {
    method constructor (line 5) | constructor(protected readonly knex: Knex) {
    method jsonSelect (line 9) | jsonSelect(

FILE: apps/nestjs-backend/src/db-provider/base-query/base-query.sqlite.ts
  class BaseQuerySqlite (line 4) | class BaseQuerySqlite extends BaseQueryAbstract {
    method constructor (line 5) | constructor(protected readonly knex: Knex) {
    method jsonSelect (line 9) | jsonSelect(

FILE: apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field-visitor.interface.ts
  type ICreateDatabaseColumnContext (line 9) | interface ICreateDatabaseColumnContext {

FILE: apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field-visitor.postgres.ts
  class CreatePostgresDatabaseColumnFieldVisitor (line 44) | class CreatePostgresDatabaseColumnFieldVisitor implements IFieldVisitor<...
    method constructor (line 47) | constructor(private readonly context: ICreateDatabaseColumnContext) {}
    method getSql (line 49) | getSql(): string[] {
    method getSchemaType (line 53) | private getSchemaType(dbFieldType: DbFieldType): SchemaType {
    method createStandardColumn (line 75) | private createStandardColumn(field: FieldCore): void {
    method createFormulaColumns (line 88) | private createFormulaColumns(field: FormulaFieldCore): void {
    method getPostgresColumnType (line 147) | private getPostgresColumnType(dbFieldType: DbFieldType): string {
    method visitNumberField (line 169) | visitNumberField(field: NumberFieldCore): void {
    method visitSingleLineTextField (line 173) | visitSingleLineTextField(field: SingleLineTextFieldCore): void {
    method visitLongTextField (line 177) | visitLongTextField(field: LongTextFieldCore): void {
    method visitAttachmentField (line 181) | visitAttachmentField(field: AttachmentFieldCore): void {
    method visitCheckboxField (line 185) | visitCheckboxField(field: CheckboxFieldCore): void {
    method visitDateField (line 189) | visitDateField(field: DateFieldCore): void {
    method visitRatingField (line 193) | visitRatingField(field: RatingFieldCore): void {
    method visitAutoNumberField (line 197) | visitAutoNumberField(_field: AutoNumberFieldCore): void {
    method visitLinkField (line 207) | visitLinkField(field: LinkFieldCore): void {
    method isSymmetricField (line 236) | private isSymmetricField(_field: LinkFieldCore): boolean {
    method createForeignKeyForLinkField (line 244) | private createForeignKeyForLinkField(field: LinkFieldCore): void {
    method visitRollupField (line 362) | visitRollupField(field: RollupFieldCore): void {
    method visitConditionalRollupField (line 367) | visitConditionalRollupField(field: ConditionalRollupFieldCore): void {
    method visitSingleSelectField (line 372) | visitSingleSelectField(field: SingleSelectFieldCore): void {
    method visitMultipleSelectField (line 376) | visitMultipleSelectField(field: MultipleSelectFieldCore): void {
    method visitButtonField (line 380) | visitButtonField(field: ButtonFieldCore): void {
    method visitFormulaField (line 385) | visitFormulaField(field: FormulaFieldCore): void {
    method visitCreatedTimeField (line 389) | visitCreatedTimeField(field: CreatedTimeFieldCore): void {
    method visitLastModifiedTimeField (line 403) | visitLastModifiedTimeField(field: LastModifiedTimeFieldCore): void {
    method visitUserField (line 428) | visitUserField(field: UserFieldCore): void {
    method visitCreatedByField (line 432) | visitCreatedByField(field: CreatedByFieldCore): void {
    method visitLastModifiedByField (line 444) | visitLastModifiedByField(field: LastModifiedByFieldCore): void {

FILE: apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field-visitor.sqlite.ts
  class CreateSqliteDatabaseColumnFieldVisitor (line 44) | class CreateSqliteDatabaseColumnFieldVisitor implements IFieldVisitor<vo...
    method constructor (line 47) | constructor(private readonly context: ICreateDatabaseColumnContext) {}
    method getSql (line 49) | getSql(): string[] {
    method getSchemaType (line 53) | private getSchemaType(dbFieldType: DbFieldType): SchemaType {
    method createStandardColumn (line 75) | private createStandardColumn(field: FieldCore): void {
    method createFormulaColumns (line 88) | private createFormulaColumns(field: FormulaFieldCore): void {
    method getSqliteColumnType (line 143) | private getSqliteColumnType(dbFieldType: DbFieldType): string {
    method visitNumberField (line 165) | visitNumberField(field: NumberFieldCore): void {
    method visitSingleLineTextField (line 169) | visitSingleLineTextField(field: SingleLineTextFieldCore): void {
    method visitLongTextField (line 173) | visitLongTextField(field: LongTextFieldCore): void {
    method visitAttachmentField (line 177) | visitAttachmentField(field: AttachmentFieldCore): void {
    method visitCheckboxField (line 181) | visitCheckboxField(field: CheckboxFieldCore): void {
    method visitDateField (line 185) | visitDateField(field: DateFieldCore): void {
    method visitRatingField (line 189) | visitRatingField(field: RatingFieldCore): void {
    method visitAutoNumberField (line 193) | visitAutoNumberField(_field: AutoNumberFieldCore): void {
    method visitLinkField (line 206) | visitLinkField(field: LinkFieldCore): void {
    method isSymmetricField (line 233) | private isSymmetricField(_field: LinkFieldCore): boolean {
    method createForeignKeyForLinkField (line 241) | private createForeignKeyForLinkField(field: LinkFieldCore): void {
    method visitRollupField (line 359) | visitRollupField(field: RollupFieldCore): void {
    method visitConditionalRollupField (line 364) | visitConditionalRollupField(field: ConditionalRollupFieldCore): void {
    method visitSingleSelectField (line 369) | visitSingleSelectField(field: SingleSelectFieldCore): void {
    method visitMultipleSelectField (line 373) | visitMultipleSelectField(field: MultipleSelectFieldCore): void {
    method visitFormulaField (line 378) | visitFormulaField(field: FormulaFieldCore): void {
    method visitButtonField (line 382) | visitButtonField(field: ButtonFieldCore): void {
    method visitCreatedTimeField (line 386) | visitCreatedTimeField(field: CreatedTimeFieldCore): void {
    method visitLastModifiedTimeField (line 401) | visitLastModifiedTimeField(field: LastModifiedTimeFieldCore): void {
    method visitUserField (line 426) | visitUserField(field: UserFieldCore): void {
    method visitCreatedByField (line 430) | visitCreatedByField(field: CreatedByFieldCore): void {
    method visitLastModifiedByField (line 442) | visitLastModifiedByField(field: LastModifiedByFieldCore): void {

FILE: apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field.util.ts
  function validateGeneratedColumnSupport (line 4) | function validateGeneratedColumnSupport(

FILE: apps/nestjs-backend/src/db-provider/db.provider.interface.ts
  type IFilterQueryExtra (line 40) | type IFilterQueryExtra = {
  type ISortQueryExtra (line 46) | type ISortQueryExtra = {
  type IAggregationQueryExtra (line 50) | type IAggregationQueryExtra = { filter?: IFilter; groupBy?: string[] } &...
  type ICalendarDailyCollectionQueryProps (line 52) | type ICalendarDailyCollectionQueryProps = {
  type IDbProvider (line 60) | interface IDbProvider {

FILE: apps/nestjs-backend/src/db-provider/db.provider.ts
  constant DB_PROVIDER_SYMBOL (line 10) | const DB_PROVIDER_SYMBOL = Symbol('DB_PROVIDER');

FILE: apps/nestjs-backend/src/db-provider/drop-database-column-query/drop-database-column-field-visitor.interface.ts
  type DropColumnOperationType (line 7) | enum DropColumnOperationType {
  type IDropDatabaseColumnContext (line 19) | interface IDropDatabaseColumnContext {

FILE: apps/nestjs-backend/src/db-provider/drop-database-column-query/drop-database-column-field-visitor.postgres.ts
  class DropPostgresDatabaseColumnFieldVisitor (line 34) | class DropPostgresDatabaseColumnFieldVisitor implements IFieldVisitor<st...
    method constructor (line 35) | constructor(private readonly context: IDropDatabaseColumnContext) {}
    method dropStandardColumn (line 37) | private dropStandardColumn(field: FieldCore): string[] {
    method dropFormulaColumns (line 58) | private dropFormulaColumns(field: FormulaFieldCore): string[] {
    method dropForeignKeyForLinkField (line 62) | private dropForeignKeyForLinkField(field: LinkFieldCore): string[] {
    method visitNumberField (line 140) | visitNumberField(field: NumberFieldCore): string[] {
    method visitSingleLineTextField (line 144) | visitSingleLineTextField(field: SingleLineTextFieldCore): string[] {
    method visitLongTextField (line 148) | visitLongTextField(field: LongTextFieldCore): string[] {
    method visitAttachmentField (line 152) | visitAttachmentField(field: AttachmentFieldCore): string[] {
    method visitCheckboxField (line 156) | visitCheckboxField(field: CheckboxFieldCore): string[] {
    method visitDateField (line 160) | visitDateField(field: DateFieldCore): string[] {
    method visitRatingField (line 164) | visitRatingField(field: RatingFieldCore): string[] {
    method visitAutoNumberField (line 168) | visitAutoNumberField(field: AutoNumberFieldCore): string[] {
    method visitLinkField (line 172) | visitLinkField(field: LinkFieldCore): string[] {
    method visitRollupField (line 196) | visitRollupField(field: RollupFieldCore): string[] {
    method visitConditionalRollupField (line 201) | visitConditionalRollupField(field: ConditionalRollupFieldCore): string...
    method visitSingleSelectField (line 206) | visitSingleSelectField(field: SingleSelectFieldCore): string[] {
    method visitMultipleSelectField (line 210) | visitMultipleSelectField(field: MultipleSelectFieldCore): string[] {
    method visitButtonField (line 214) | visitButtonField(field: ButtonFieldCore): string[] {
    method visitFormulaField (line 219) | visitFormulaField(field: FormulaFieldCore): string[] {
    method visitCreatedTimeField (line 223) | visitCreatedTimeField(field: CreatedTimeFieldCore): string[] {
    method visitLastModifiedTimeField (line 227) | visitLastModifiedTimeField(field: LastModifiedTimeFieldCore): string[] {
    method visitUserField (line 232) | visitUserField(field: UserFieldCore): string[] {
    method visitCreatedByField (line 236) | visitCreatedByField(field: CreatedByFieldCore): string[] {
    method visitLastModifiedByField (line 240) | visitLastModifiedByField(field: LastModifiedByFieldCore): string[] {

FILE: apps/nestjs-backend/src/db-provider/drop-database-column-query/drop-database-column-field-visitor.sqlite.ts
  class DropSqliteDatabaseColumnFieldVisitor (line 33) | class DropSqliteDatabaseColumnFieldVisitor implements IFieldVisitor<stri...
    method constructor (line 34) | constructor(private readonly context: IDropDatabaseColumnContext) {}
    method dropStandardColumn (line 36) | private dropStandardColumn(field: FieldCore): string[] {
    method dropFormulaColumns (line 52) | private dropFormulaColumns(field: FormulaFieldCore): string[] {
    method dropForeignKeyForLinkField (line 59) | private dropForeignKeyForLinkField(field: LinkFieldCore): string[] {
    method visitNumberField (line 126) | visitNumberField(field: NumberFieldCore): string[] {
    method visitSingleLineTextField (line 130) | visitSingleLineTextField(field: SingleLineTextFieldCore): string[] {
    method visitLongTextField (line 134) | visitLongTextField(field: LongTextFieldCore): string[] {
    method visitAttachmentField (line 138) | visitAttachmentField(field: AttachmentFieldCore): string[] {
    method visitCheckboxField (line 142) | visitCheckboxField(field: CheckboxFieldCore): string[] {
    method visitDateField (line 146) | visitDateField(field: DateFieldCore): string[] {
    method visitRatingField (line 150) | visitRatingField(field: RatingFieldCore): string[] {
    method visitAutoNumberField (line 154) | visitAutoNumberField(field: AutoNumberFieldCore): string[] {
    method visitLinkField (line 158) | visitLinkField(field: LinkFieldCore): string[] {
    method visitRollupField (line 179) | visitRollupField(field: RollupFieldCore): string[] {
    method visitConditionalRollupField (line 184) | visitConditionalRollupField(field: ConditionalRollupFieldCore): string...
    method visitSingleSelectField (line 189) | visitSingleSelectField(field: SingleSelectFieldCore): string[] {
    method visitMultipleSelectField (line 193) | visitMultipleSelectField(field: MultipleSelectFieldCore): string[] {
    method visitButtonField (line 197) | visitButtonField(field: ButtonFieldCore): string[] {
    method visitFormulaField (line 202) | visitFormulaField(field: FormulaFieldCore): string[] {
    method visitCreatedTimeField (line 206) | visitCreatedTimeField(field: CreatedTimeFieldCore): string[] {
    method visitLastModifiedTimeField (line 210) | visitLastModifiedTimeField(field: LastModifiedTimeFieldCore): string[] {
    method visitUserField (line 215) | visitUserField(field: UserFieldCore): string[] {
    method visitCreatedByField (line 219) | visitCreatedByField(field: CreatedByFieldCore): string[] {
    method visitLastModifiedByField (line 223) | visitLastModifiedByField(field: LastModifiedByFieldCore): string[] {

FILE: apps/nestjs-backend/src/db-provider/duplicate-table/abstract.ts
  method constructor (line 4) | constructor(protected readonly queryBuilder: Knex.QueryBuilder) {}

FILE: apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-attachment-table-query.abstract.ts
  method constructor (line 4) | constructor(protected readonly queryBuilder: Knex.QueryBuilder) {}

FILE: apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-attachment-table-query.postgres.ts
  class DuplicateAttachmentTableQueryPostgres (line 4) | class DuplicateAttachmentTableQueryPostgres extends DuplicateAttachmentT...
    method constructor (line 6) | constructor(queryBuilder: Knex.QueryBuilder) {
    method duplicateAttachmentTable (line 11) | duplicateAttachmentTable(

FILE: apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-attachment-table-query.sqlite.ts
  class DuplicateAttachmentTableQuerySqlite (line 4) | class DuplicateAttachmentTableQuerySqlite extends DuplicateAttachmentTab...
    method constructor (line 6) | constructor(queryBuilder: Knex.QueryBuilder) {
    method duplicateAttachmentTable (line 11) | duplicateAttachmentTable(

FILE: apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-query.postgres.ts
  class DuplicateTableQueryPostgres (line 4) | class DuplicateTableQueryPostgres extends DuplicateTableQueryAbstract {
    method constructor (line 6) | constructor(queryBuilder: Knex.QueryBuilder) {
    method duplicateTableData (line 11) | duplicateTableData(

FILE: apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-query.sqlite.ts
  class DuplicateTableQuerySqlite (line 4) | class DuplicateTableQuerySqlite extends DuplicateTableQueryAbstract {
    method constructor (line 6) | constructor(queryBuilder: Knex.QueryBuilder) {
    method duplicateTableData (line 11) | duplicateTableData(

FILE: apps/nestjs-backend/src/db-provider/filter-query/__tests__/field-reference.spec.ts
  type FieldPair (line 25) | type FieldPair = {
  function assignBaseField (line 36) | function assignBaseField<T extends FieldCore>(
  function createNumberField (line 59) | function createNumberField(id: string, dbFieldName: string): NumberField...
  function createNumberArrayField (line 69) | function createNumberArrayField(id: string, dbFieldName: string): Number...
  function createTextField (line 75) | function createTextField(id: string, dbFieldName: string): SingleLineTex...
  function createDateField (line 85) | function createDateField(id: string, dbFieldName: string): DateFieldCore {
  function createCheckboxField (line 101) | function createCheckboxField(id: string, dbFieldName: string): CheckboxF...
  function createUserField (line 111) | function createUserField(

FILE: apps/nestjs-backend/src/db-provider/filter-query/cell-value-filter.abstract.ts
  class FieldReferenceCompatibilityException (line 54) | class FieldReferenceCompatibilityException extends BadRequestException {
    method constructor (line 57) | constructor(sourceField: string, referenceField: string) {
  method constructor (line 70) | constructor(
  method ensureLiteralValue (line 84) | protected ensureLiteralValue(value: IFilterValue, operator: IFilterOpera...
  method resolveFieldReference (line 92) | protected resolveFieldReference(value: IFieldReferenceValue): string {
  method getFieldReferenceMetadata (line 108) | protected getFieldReferenceMetadata(fieldId: string): FieldCore | undefi...
  method getComparableReferenceField (line 112) | protected getComparableReferenceField(value: IFieldReferenceValue): Fiel...
  method compiler (line 129) | compiler(
  method isOperatorHandler (line 168) | isOperatorHandler(
  method isExactlyOperatorHandler (line 186) | isExactlyOperatorHandler(
  method containsOperatorHandler (line 202) | containsOperatorHandler(
  method isGreaterOperatorHandler (line 221) | isGreaterOperatorHandler(
  method isGreaterEqualOperatorHandler (line 239) | isGreaterEqualOperatorHandler(
  method isLessOperatorHandler (line 257) | isLessOperatorHandler(
  method isLessEqualOperatorHandler (line 275) | isLessEqualOperatorHandler(
  method isAnyOfOperatorHandler (line 293) | isAnyOfOperatorHandler(
  method hasAllOfOperatorHandler (line 316) | hasAllOfOperatorHandler(
  method isNotExactlyOperatorHandler (line 325) | isNotExactlyOperatorHandler(
  method isWithInOperatorHandler (line 334) | isWithInOperatorHandler(
  method isEmptyOperatorHandler (line 343) | isEmptyOperatorHandler(
  method isNotEmptyOperatorHandler (line 366) | isNotEmptyOperatorHandler(
  method createSqlPlaceholders (line 381) | protected createSqlPlaceholders(values: unknown[]): string {
  method getFilterDateTimeRange (line 385) | protected getFilterDateTimeRange(

FILE: apps/nestjs-backend/src/db-provider/filter-query/cell-value-filter.interface.ts
  type ICellValueFilterHandler (line 5) | type ICellValueFilterHandler = (
  type ICellValueFilterInterface (line 12) | interface ICellValueFilterInterface {

FILE: apps/nestjs-backend/src/db-provider/filter-query/filter-query.abstract.ts
  method constructor (line 37) | constructor(
  method appendQueryBuilder (line 46) | appendQueryBuilder(): Knex.QueryBuilder {
  method parseFilters (line 52) | private parseFilters(
  method parseFilter (line 77) | private parseFilter(
  method getFilterAdapter (line 156) | private getFilterAdapter(field: FieldCore): AbstractCellValueFilter {
  method preProcessRemoveNullAndReplaceMe (line 174) | private preProcessRemoveNullAndReplaceMe(filter?: IFilter) {
  method processFilterItem (line 191) | private processFilterItem(filterItem: IFilterItem, replaceUserId?: strin...
  method replaceMeTagInValue (line 201) | private replaceMeTagInValue(
  method shouldKeepFilterItem (line 220) | private shouldKeepFilterItem(value: unknown, field: FieldCore, operator:...

FILE: apps/nestjs-backend/src/db-provider/filter-query/filter-query.interface.ts
  type IFilterQueryInterface (line 3) | interface IFilterQueryInterface {

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/cell-value-filter.postgres.ts
  class CellValueFilterPostgres (line 13) | class CellValueFilterPostgres extends AbstractCellValueFilter {
    method isNotOperatorHandler (line 14) | isNotOperatorHandler(
    method doesNotContainOperatorHandler (line 31) | doesNotContainOperatorHandler(
    method isNoneOfOperatorHandler (line 42) | isNoneOfOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-boolean-cell-value-filter.adapter.ts
  class MultipleBooleanCellValueFilterAdapter (line 7) | class MultipleBooleanCellValueFilterAdapter extends CellValueFilterPostg...
    method isOperatorHandler (line 8) | isOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-datetime-cell-value-filter.adapter.ts
  class MultipleDatetimeCellValueFilterAdapter (line 6) | class MultipleDatetimeCellValueFilterAdapter extends CellValueFilterPost...
    method isOperatorHandler (line 7) | isOperatorHandler(
    method isNotOperatorHandler (line 25) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 44) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 62) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 80) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 98) | isLessEqualOperatorHandler(
    method isWithInOperatorHandler (line 116) | isWithInOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-json-cell-value-filter.adapter.ts
  class MultipleJsonCellValueFilterAdapter (line 15) | class MultipleJsonCellValueFilterAdapter extends CellValueFilterPostgres {
    method isOperatorHandler (line 16) | isOperatorHandler(
    method isNotOperatorHandler (line 57) | isNotOperatorHandler(
    method isExactlyOperatorHandler (line 100) | isExactlyOperatorHandler(
    method isAnyOfOperatorHandler (line 132) | isAnyOfOperatorHandler(
    method isNoneOfOperatorHandler (line 159) | isNoneOfOperatorHandler(
    method hasAllOfOperatorHandler (line 191) | hasAllOfOperatorHandler(
    method isNotExactlyOperatorHandler (line 217) | isNotExactlyOperatorHandler(
    method containsOperatorHandler (line 250) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 270) | doesNotContainOperatorHandler(
    method buildReferenceJsonArray (line 290) | private buildReferenceJsonArray(value: IFieldReferenceValue): string {
    method buildJsonArrayExpression (line 296) | private buildJsonArrayExpression(columnExpression: string, field?: Fie...
    method buildTextArrayExpression (line 304) | private buildTextArrayExpression(jsonArrayExpression: string): string {
    method getJsonPath (line 308) | private getJsonPath(field: FieldCore): string {

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-number-cell-value-filter.adapter.ts
  class MultipleNumberCellValueFilterAdapter (line 13) | class MultipleNumberCellValueFilterAdapter extends CellValueFilterPostgr...
    method isOperatorHandler (line 14) | isOperatorHandler(
    method isNotOperatorHandler (line 34) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 57) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 83) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 109) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 135) | isLessEqualOperatorHandler(
    method isAnyOfOperatorHandler (line 161) | isAnyOfOperatorHandler(
    method isNoneOfOperatorHandler (line 183) | isNoneOfOperatorHandler(
    method hasAllOfOperatorHandler (line 207) | hasAllOfOperatorHandler(
    method isExactlyOperatorHandler (line 229) | isExactlyOperatorHandler(
    method isNotExactlyOperatorHandler (line 253) | isNotExactlyOperatorHandler(
    method buildJsonArrayExpression (line 277) | private buildJsonArrayExpression(columnExpression: string, field: Fiel...
    method buildReferenceJsonArray (line 284) | private buildReferenceJsonArray(value: IFieldReferenceValue): string {
    method buildTextArrayExpression (line 290) | private buildTextArrayExpression(jsonArrayExpression: string): string {
    method buildComparisonSql (line 294) | private buildComparisonSql(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-string-cell-value-filter.adapter.ts
  class MultipleStringCellValueFilterAdapter (line 7) | class MultipleStringCellValueFilterAdapter extends CellValueFilterPostgr...
    method isOperatorHandler (line 8) | isOperatorHandler(
    method isNotOperatorHandler (line 19) | isNotOperatorHandler(
    method containsOperatorHandler (line 31) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 45) | doesNotContainOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/boolean-cell-value-filter.adapter.ts
  class BooleanCellValueFilterAdapter (line 6) | class BooleanCellValueFilterAdapter extends CellValueFilterPostgres {
    method isOperatorHandler (line 7) | isOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/datetime-cell-value-filter.adapter.ts
  class DatetimeCellValueFilterAdapter (line 15) | class DatetimeCellValueFilterAdapter extends CellValueFilterPostgres {
    method isOperatorHandler (line 16) | isOperatorHandler(
    method isNotOperatorHandler (line 40) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 67) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 88) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 109) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 130) | isLessEqualOperatorHandler(
    method isWithInOperatorHandler (line 151) | isWithInOperatorHandler(
    method extractFormatting (line 174) | private extractFormatting(): IDatetimeFormatting | undefined {
    method determineDateUnit (line 179) | private determineDateUnit(formatting?: IDatetimeFormatting): 'day' | '...
    method wrapWithTimeZone (line 192) | private wrapWithTimeZone(expr: string, formatting?: IDatetimeFormattin...
    method applyFieldReferenceEquality (line 197) | private applyFieldReferenceEquality(
    method applyFieldReferenceComparison (line 217) | private applyFieldReferenceComparison(
    method buildTruncatedExpression (line 239) | private buildTruncatedExpression(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/json-cell-value-filter.adapter.ts
  class JsonCellValueFilterAdapter (line 17) | class JsonCellValueFilterAdapter extends CellValueFilterPostgres {
    method isOperatorHandler (line 18) | isOperatorHandler(
    method isNotOperatorHandler (line 61) | isNotOperatorHandler(
    method isAnyOfOperatorHandler (line 105) | isAnyOfOperatorHandler(
    method isNoneOfOperatorHandler (line 134) | isNoneOfOperatorHandler(
    method containsOperatorHandler (line 167) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 187) | doesNotContainOperatorHandler(
    method buildReferenceJsonArray (line 207) | private buildReferenceJsonArray(value: IFieldReferenceValue): string {
    method buildJsonArrayExpression (line 213) | private buildJsonArrayExpression(columnExpression: string, field?: Fie...
    method buildTextArrayExpression (line 221) | private buildTextArrayExpression(jsonArrayExpression: string): string {
    method getJsonPath (line 225) | private getJsonPath(field: FieldCore): string {

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/number-cell-value-filter.adapter.ts
  class NumberCellValueFilterAdapter (line 6) | class NumberCellValueFilterAdapter extends CellValueFilterPostgres {
    method isOperatorHandler (line 7) | isOperatorHandler(
    method isNotOperatorHandler (line 16) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 25) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 34) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 43) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 52) | isLessEqualOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/string-cell-value-filter.adapter.ts
  class StringCellValueFilterAdapter (line 13) | class StringCellValueFilterAdapter extends CellValueFilterPostgres {
    method isOperatorHandler (line 14) | isOperatorHandler(
    method isNotOperatorHandler (line 30) | isNotOperatorHandler(
    method containsOperatorHandler (line 47) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 59) | doesNotContainOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/postgres/filter-query.postgres.ts
  class FilterQueryPostgres (line 20) | class FilterQueryPostgres extends AbstractFilterQuery {
    method constructor (line 21) | constructor(
    method booleanFilter (line 31) | booleanFilter(field: FieldCore, context?: IRecordQueryFilterContext): ...
    method numberFilter (line 39) | numberFilter(field: FieldCore, context?: IRecordQueryFilterContext): C...
    method dateTimeFilter (line 47) | dateTimeFilter(field: FieldCore, context?: IRecordQueryFilterContext):...
    method stringFilter (line 55) | stringFilter(field: FieldCore, context?: IRecordQueryFilterContext): C...
    method jsonFilter (line 63) | jsonFilter(field: FieldCore, context?: IRecordQueryFilterContext): Cel...

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/cell-value-filter.sqlite.ts
  class CellValueFilterSqlite (line 16) | class CellValueFilterSqlite extends AbstractCellValueFilter {
    method isNotOperatorHandler (line 17) | isNotOperatorHandler(
    method doesNotContainOperatorHandler (line 35) | doesNotContainOperatorHandler(
    method isNoneOfOperatorHandler (line 49) | isNoneOfOperatorHandler(
    method getJsonQueryColumn (line 63) | protected getJsonQueryColumn(field: FieldCore, operator: IFilterOperat...

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-boolean-cell-value-filter.adapter.ts
  class MultipleBooleanCellValueFilterAdapter (line 7) | class MultipleBooleanCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 8) | isOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-datetime-cell-value-filter.adapter.ts
  class MultipleDatetimeCellValueFilterAdapter (line 6) | class MultipleDatetimeCellValueFilterAdapter extends CellValueFilterSqli...
    method isOperatorHandler (line 7) | isOperatorHandler(
    method isNotOperatorHandler (line 28) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 49) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 70) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 91) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 112) | isLessEqualOperatorHandler(
    method isWithInOperatorHandler (line 133) | isWithInOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-json-cell-value-filter.adapter.ts
  class MultipleJsonCellValueFilterAdapter (line 6) | class MultipleJsonCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 7) | isOperatorHandler(
    method isNotOperatorHandler (line 18) | isNotOperatorHandler(
    method isExactlyOperatorHandler (line 29) | isExactlyOperatorHandler(
    method isAnyOfOperatorHandler (line 52) | isAnyOfOperatorHandler(
    method isNoneOfOperatorHandler (line 67) | isNoneOfOperatorHandler(
    method hasAllOfOperatorHandler (line 82) | hasAllOfOperatorHandler(
    method isNotExactlyOperatorHandler (line 97) | isNotExactlyOperatorHandler(
    method containsOperatorHandler (line 116) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 130) | doesNotContainOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-number-cell-value-filter.adapter.ts
  class MultipleNumberCellValueFilterAdapter (line 5) | class MultipleNumberCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 6) | isOperatorHandler(
    method isNotOperatorHandler (line 20) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 34) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 48) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 62) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 76) | isLessEqualOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-string-cell-value-filter.adapter.ts
  class MultipleStringCellValueFilterAdapter (line 5) | class MultipleStringCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 6) | isOperatorHandler(
    method isNotOperatorHandler (line 21) | isNotOperatorHandler(
    method containsOperatorHandler (line 36) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 51) | doesNotContainOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/boolean-cell-value-filter.adapter.ts
  class BooleanCellValueFilterAdapter (line 6) | class BooleanCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 7) | isOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/datetime-cell-value-filter.adapter.ts
  class DatetimeCellValueFilterAdapter (line 13) | class DatetimeCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 14) | isOperatorHandler(
    method isNotOperatorHandler (line 34) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 57) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 77) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 97) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 117) | isLessEqualOperatorHandler(
    method isWithInOperatorHandler (line 137) | isWithInOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/json-cell-value-filter.adapter.ts
  class JsonCellValueFilterAdapter (line 13) | class JsonCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 14) | isOperatorHandler(
    method isNotOperatorHandler (line 51) | isNotOperatorHandler(
    method isAnyOfOperatorHandler (line 88) | isAnyOfOperatorHandler(
    method isNoneOfOperatorHandler (line 99) | isNoneOfOperatorHandler(
    method containsOperatorHandler (line 110) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 120) | doesNotContainOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/number-cell-value-filter.adapter.ts
  class NumberCellValueFilterAdapter (line 6) | class NumberCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 7) | isOperatorHandler(
    method isNotOperatorHandler (line 16) | isNotOperatorHandler(
    method isGreaterOperatorHandler (line 25) | isGreaterOperatorHandler(
    method isGreaterEqualOperatorHandler (line 34) | isGreaterEqualOperatorHandler(
    method isLessOperatorHandler (line 43) | isLessOperatorHandler(
    method isLessEqualOperatorHandler (line 52) | isLessEqualOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/string-cell-value-filter.adapter.ts
  class StringCellValueFilterAdapter (line 12) | class StringCellValueFilterAdapter extends CellValueFilterSqlite {
    method isOperatorHandler (line 13) | isOperatorHandler(
    method isNotOperatorHandler (line 29) | isNotOperatorHandler(
    method containsOperatorHandler (line 46) | containsOperatorHandler(
    method doesNotContainOperatorHandler (line 56) | doesNotContainOperatorHandler(

FILE: apps/nestjs-backend/src/db-provider/filter-query/sqlite/filter-query.sqlite.ts
  class FilterQuerySqlite (line 21) | class FilterQuerySqlite extends AbstractFilterQuery {
    method constructor (line 22) | constructor(
    method booleanFilter (line 32) | booleanFilter(field: FieldCore, context?: IRecordQueryFilterContext): ...
    method numberFilter (line 40) | numberFilter(field: FieldCore, context?: IRecordQueryFilterContext): C...
    method dateTimeFilter (line 48) | dateTimeFilter(field: FieldCore, context?: IRecordQueryFilterContext):...
    method stringFilter (line 56) | stringFilter(field: FieldCore, context?: IRecordQueryFilterContext): C...
    method jsonFilter (line 64) | jsonFilter(field: FieldCore, context?: IRecordQueryFilterContext): Abs...

FILE: apps/nestjs-backend/src/db-provider/generated-column-query/generated-column-query.abstract.ts
  method setContext (line 18) | setContext(context: IFormulaConversionContext): void {
  method setCallMetadata (line 22) | setCallMetadata(metadata?: IFormulaParamMetadata[]): void {
  method isGeneratedColumnContext (line 27) | protected get isGeneratedColumnContext(): boolean {
  method add (line 127) | add(left: string, right: string): string {
  method subtract (line 131) | subtract(left: string, right: string): string {
  method multiply (line 135) | multiply(left: string, right: string): string {
  method divide (line 139) | divide(left: string, right: string): string {
  method modulo (line 143) | modulo(left: string, right: string): string {
  method equal (line 148) | equal(left: string, right: string): string {
  method notEqual (line 152) | notEqual(left: string, right: string): string {
  method greaterThan (line 156) | greaterThan(left: string, right: string): string {
  method lessThan (line 160) | lessThan(left: string, right: string): string {
  method greaterThanOrEqual (line 164) | greaterThanOrEqual(left: string, right: string): string {
  method lessThanOrEqual (line 168) | lessThanOrEqual(left: string, right: string): string {
  method logicalAnd (line 173) | logicalAnd(left: string, right: string): string {
  method logicalOr (line 177) | logicalOr(left: string, right: string): string {
  method bitwiseAnd (line 181) | bitwiseAnd(left: string, right: string): string {
  method unaryMinus (line 186) | unaryMinus(value: string): string {
  method stringLiteral (line 194) | stringLiteral(value: string): string {
  method numberLiteral (line 198) | numberLiteral(value: number): string {
  method booleanLiteral (line 202) | booleanLiteral(value: boolean): string {
  method nullLiteral (line 206) | nullLiteral(): string {
  method castToNumber (line 211) | castToNumber(value: string): string {
  method castToString (line 215) | castToString(value: string): string {
  method castToBoolean (line 219) | castToBoolean(value: string): string {
  method castToDate (line 223) | castToDate(value: string): string {
  method isNull (line 228) | isNull(value: string): string {
  method coalesce (line 232) | coalesce(params: string[]): string {
  method parentheses (line 237) | parentheses(expression: string): string {
  method escapeIdentifier (line 242) | protected escapeIdentifier(identifier: string): string {
  method joinParams (line 247) | protected joinParams(params: string[], separator = ', '): string {

FILE: apps/nestjs-backend/src/db-provider/generated-column-query/index.ts
  function createGeneratedColumnQuerySupportValidator (line 6) | function createGeneratedColumnQuerySupportValidator(driver: DriverClient) {

FILE: apps/nestjs-backend/src/db-provider/generated-column-query/postgres/generated-column-query-support-validator.postgres.ts
  class GeneratedColumnQuerySupportValidatorPostgres (line 11) | class GeneratedColumnQuerySupportValidatorPostgres
    method setContext (line 16) | setContext(context: IFormulaConversionContext): void {
    method setCallMetadata (line 20) | setCallMetadata(): void {
    method sum (line 25) | sum(_params: string[]): boolean {
    method average (line 30) | average(_params: string[]): boolean {
    method max (line 35) | max(_params: string[]): boolean {
    method min (line 39) | min(_params: string[]): boolean {
    method round (line 43) | round(_value: string, _precision?: string): boolean {
    method roundUp (line 47) | roundUp(_value: string, _precision?: string): boolean {
    method roundDown (line 51) | roundDown(_value: string, _precision?: string): boolean {
    method ceiling (line 55) | ceiling(_value: string): boolean {
    method floor (line 59) | floor(_value: string): boolean {
    method even (line 63) | even(_value: string): boolean {
    method odd (line 67) | odd(_value: string): boolean {
    method int (line 71) | int(_value: string): boolean {
    method abs (line 75) | abs(_value: string): boolean {
    method sqrt (line 79) | sqrt(_value: string): boolean {
    method power (line 83) | power(_base: string, _exponent: string): boolean {
    method exp (line 87) | exp(_value: string): boolean {
    method log (line 91) | log(_value: string, _base?: string): boolean {
    method mod (line 95) | mod(_dividend: string, _divisor: string): boolean {
    method value (line 99) | value(_text: string): boolean {
    method concatenate (line 104) | concatenate(_params: string[]): boolean {
    method stringConcat (line 108) | stringConcat(_left: string, _right: string): boolean {
    method find (line 112) | find(_searchText: string, _withinText: string, _startNum?: string): bo...
    method search (line 117) | search(_searchText: string, _withinText: string, _startNum?: string): ...
    method mid (line 122) | mid(_text: string, _startNum: string, _numChars: string): boolean {
    method left (line 126) | left(_text: string, _numChars: string): boolean {
    method right (line 130) | right(_text: string, _numChars: string): boolean {
    method replace (line 134) | replace(_oldText: string, _startNum: string, _numChars: string, _newTe...
    method regexpReplace (line 138) | regexpReplace(_text: string, _pattern: string, _replacement: string): ...
    method substitute (line 143) | substitute(_text: string, _oldText: string, _newText: string, _instanc...
    method lower (line 148) | lower(_text: string): boolean {
    method upper (line 154) | upper(_text: string): boolean {
    method rept (line 160) | rept(_text: string, _numTimes: string): boolean {
    method trim (line 164) | trim(_text: string): boolean {
    method len (line 168) | len(_text: string): boolean {
    method t (line 172) | t(_value: string): boolean {
    method encodeUrlComponent (line 177) | encodeUrlComponent(_text: string): boolean {
    method now (line 183) | now(): boolean {
    method today (line 188) | today(): boolean {
    method dateAdd (line 193) | dateAdd(_date: string, _count: string, _unit: string): boolean {
    method datestr (line 199) | datestr(_date: string): boolean {
    method datetimeDiff (line 204) | datetimeDiff(_startDate: string, _endDate: string, _unit: string): boo...
    method datetimeFormat (line 209) | datetimeFormat(_date: string, _format: string): boolean {
    method datetimeParse (line 214) | datetimeParse(_dateString: string, _format?: string): boolean {
    method day (line 219) | day(_date: string): boolean {
    method fromNow (line 224) | fromNow(_date: string): boolean {
    method hour (line 229) | hour(_date: string): boolean {
    method isAfter (line 234) | isAfter(_date1: string, _date2: string): boolean {
    method isBefore (line 239) | isBefore(_date1: string, _date2: string): boolean {
    method isSame (line 244) | isSame(_date1: string, _date2: string, _unit?: string): boolean {
    method lastModifiedTime (line 249) | lastModifiedTime(): boolean {
    method minute (line 253) | minute(_date: string): boolean {
    method month (line 258) | month(_date: string): boolean {
    method second (line 263) | second(_date: string): boolean {
    method timestr (line 268) | timestr(_date: string): boolean {
    method toNow (line 273) | toNow(_date: string): boolean {
    method weekNum (line 278) | weekNum(_date: string): boolean {
    method weekday (line 283) | weekday(_date: string): boolean {
    method workday (line 288) | workday(_startDate: string, _days: string): boolean {
    method workdayDiff (line 293) | workdayDiff(_startDate: string, _endDate: string): boolean {
    method year (line 298) | year(_date: string): boolean {
    method createdTime (line 303) | createdTime(): boolean {
    method if (line 311) | if(_condition: string, _valueIfTrue: string, _valueIfFalse: string): b...
    method and (line 315) | and(_params: string[]): boolean {
    method or (line 319) | or(_params: string[]): boolean {
    method not (line 323) | not(_value: string): boolean {
    method xor (line 327) | xor(_params: string[]): boolean {
    method blank (line 331) | blank(): boolean {
    method error (line 335) | error(_message: string): boolean {
    method isError (line 340) | isError(_value: string): boolean {
    method switch (line 345) | switch(
    method count (line 354) | count(_params: string[]): boolean {
    method countA (line 358) | countA(_params: string[]): boolean {
    method countAll (line 362) | countAll(_value: string): boolean {
    method arrayJoin (line 366) | arrayJoin(_array: string, _separator?: string): boolean {
    method arrayUnique (line 371) | arrayUnique(_arrays: string[]): boolean {
    method arrayFlatten (line 376) | arrayFlatten(_arrays: string[]): boolean {
    method arrayCompact (line 381) | arrayCompact(_arrays: string[]): boolean {
    method recordId (line 387) | recordId(): boolean {
    method autoNumber (line 391) | autoNumber(): boolean {
    method textAll (line 395) | textAll(_value: string): boolean {
    method add (line 401) | add(_left: string, _right: string): boolean {
    method subtract (line 405) | subtract(_left: string, _right: string): boolean {
    method multiply (line 409) | multiply(_left: string, _right: string): boolean {
    method divide (line 413) | divide(_left: string, _right: string): boolean {
    method modulo (line 417) | modulo(_left: string, _right: string): boolean {
    method equal (line 422) | equal(_left: string, _right: string): boolean {
    method notEqual (line 426) | notEqual(_left: string, _right: string): boolean {
    method greaterThan (line 430) | greaterThan(_left: string, _right: string): boolean {
    method lessThan (line 434) | lessThan(_left: string, _right: string): boolean {
    method greaterThanOrEqual (line 438) | greaterThanOrEqual(_left: string, _right: string): boolean {
    method lessThanOrEqual (line 442) | lessThanOrEqual(_left: string, _right: string): boolean {
    method logicalAnd (line 447) | logicalAnd(_left: string, _right: string): boolean {
    method logicalOr (line 451) | logicalOr(_left: string, _right: string): boolean {
    method bitwiseAnd (line 455) | bitwiseAnd(_left: string, _right: string): boolean {
    method unaryMinus (line 460) | unaryMinus(_value: string): boolean {
    method fieldReference (line 465) | fieldReference(_fieldId: string, _columnName: string): boolean {
    method stringLiteral (line 470) | stringLiteral(_value: string): boolean {
    method numberLiteral (line 474) | numberLiteral(_value: number): boolean {
    method booleanLiteral (line 478) | booleanLiteral(_value: boolean): boolean {
    method nullLiteral (line 482) | nullLiteral(): boolean {
    method castToNumber (line 487) | castToNumber(_value: string): boolean {
    method castToString (line 491) | castToString(_value: string): boolean {
    method castToBoolean (line 495) | castToBoolean(_value: string): boolean {
    method castToDate (line 499) | castToDate(_value: string): boolean {
    method isNull (line 504) | isNull(_value: string): boolean {
    method coalesce (line 508) | coalesce(_params: string[]): boolean {
    method parentheses (line 513) | parentheses(_expression: string): boolean {

FILE: apps/nestjs-backend/src/db-provider/generated-column-query/postgres/generated-column-query.postgres.ts
  class GeneratedColumnQueryPostgres (line 27) | class GeneratedColumnQueryPostgres extends GeneratedColumnQueryAbstract {
    method isEmptyStringLiteral (line 28) | private isEmptyStringLiteral(value: string): boolean {
    method isNullLiteral (line 32) | private isNullLiteral(value: string): boolean {
    method shouldCoalesceNumericComparison (line 36) | private shouldCoalesceNumericComparison(value: string, metadataIndex?:...
    method normalizeNumericComparisonOperand (line 44) | private normalizeNumericComparisonOperand(value: string, metadataIndex...
    method hasWrappingParentheses (line 51) | private hasWrappingParentheses(expr: string): boolean {
    method stripOuterParentheses (line 73) | private stripOuterParentheses(expr: string): string {
    method getParamInfo (line 81) | private getParamInfo(index?: number) {
    method isNumericLiteral (line 85) | private isNumericLiteral(expr: string): boolean {
    method toNumericSafe (line 110) | private toNumericSafe(expr: string, metadataIndex?: number): string {
    method looseNumericCoercion (line 154) | private looseNumericCoercion(expr: string): string {
    method numericFromJson (line 176) | private numericFromJson(expr: string): string {
    method numericFromText (line 188) | private numericFromText(expr: string): string {
    method collapseNumeric (line 199) | private collapseNumeric(expr: string, metadataIndex?: number): string {
    method normalizeBlankComparable (line 204) | private normalizeBlankComparable(value: string, metadataIndex?: number...
    method ensureTextCollation (line 209) | private ensureTextCollation(expr: string): string {
    method buildBlankAwareComparison (line 213) | private buildBlankAwareComparison(
    method isTextLikeExpression (line 253) | private isTextLikeExpression(value: string, metadataIndex?: number): b...
    method isNumericLikeExpression (line 279) | private isNumericLikeExpression(value: string, metadataIndex?: number)...
    method getExpressionFieldType (line 308) | private getExpressionFieldType(value: string): DbFieldType | undefined {
    method buildJsonScalarCoercion (line 323) | private buildJsonScalarCoercion(jsonExpr: string): string {
    method coerceJsonExpressionToText (line 348) | private coerceJsonExpressionToText(wrapped: string): string {
    method coerceNonJsonExpressionToText (line 363) | private coerceNonJsonExpressionToText(wrapped: string): string {
    method coerceToTextComparable (line 373) | private coerceToTextComparable(value: string, metadataIndex?: number):...
    method isHardTextExpression (line 442) | private isHardTextExpression(value: string): boolean {
    method isDateLikeOperand (line 453) | private isDateLikeOperand(metadataIndex?: number): boolean {
    method buildDayInterval (line 474) | private buildDayInterval(expr: string, metadataIndex?: number): string {
    method countANonNullExpression (line 479) | private countANonNullExpression(value: string, metadataIndex?: number)...
    method add (line 488) | override add(left: string, right: string): string {
    method subtract (line 505) | override subtract(left: string, right: string): string {
    method multiply (line 525) | override multiply(left: string, right: string): string {
    method unaryMinus (line 531) | override unaryMinus(value: string): string {
    method divide (line 536) | override divide(left: string, right: string): string {
    method modulo (line 542) | override modulo(left: string, right: string): string {
    method isBooleanLikeExpression (line 548) | private isBooleanLikeExpression(value: string, metadataIndex?: number)...
    method normalizeBooleanCondition (line 562) | private normalizeBooleanCondition(condition: string, metadataIndex = 0...
    method sum (line 596) | sum(params: string[]): string {
    method average (line 602) | average(params: string[]): string {
    method max (line 608) | max(params: string[]): string {
    method min (line 612) | min(params: string[]): string {
    method round (line 616) | round(value: string, precision?: string): string {
    method roundUp (line 625) | roundUp(value: string, precision?: string): string {
    method roundDown (line 635) | roundDown(value: string, precision?: string): string {
    method ceiling (line 645) | ceiling(value: string): string {
    method floor (line 649) | floor(value: string): string {
    method even (line 653) | even(value: string): string {
    method odd (line 659) | odd(value: string): string {
    method int (line 665) | int(value: string): string {
    method abs (line 669) | abs(value: string): string {
    method sqrt (line 673) | sqrt(value: string): string {
    method power (line 677) | power(base: string, exponent: string): string {
    method exp (line 683) | exp(value: string): string {
    method log (line 687) | log(value: string, base?: string): string {
    method mod (line 697) | mod(dividend: string, divisor: string): string {
    method value (line 703) | value(text: string): string {
    method concatenate (line 708) | concatenate(params: string[]): string {
    method stringConcat (line 718) | stringConcat(left: string, right: string): string {
    method equal (line 722) | equal(left: string, right: string): string {
    method notEqual (line 726) | notEqual(left: string, right: string): string {
    method greaterThan (line 730) | greaterThan(left: string, right: string): string {
    method lessThan (line 736) | lessThan(left: string, right: string): string {
    method greaterThanOrEqual (line 742) | greaterThanOrEqual(left: string, right: string): string {
    method lessThanOrEqual (line 748) | lessThanOrEqual(left: string, right: string): string {
    method bitwiseAnd (line 755) | bitwiseAnd(left: string, right: string): string {
    method find (line 770) | find(searchText: string, withinText: string, startNum?: string): string {
    method search (line 780) | search(searchText: string, withinText: string, startNum?: string): str...
    method mid (line 791) | mid(text: string, startNum: string, numChars: string): string {
    method left (line 795) | left(text: string, numChars: string): string {
    method right (line 799) | right(text: string, numChars: string): string {
    method replace (line 803) | replace(oldText: string, startNum: string, numChars: string, newText: ...
    method regexpReplace (line 809) | regexpReplace(text: string, pattern: string, replacement: string): str...
    method substitute (line 816) | substitute(text: string, oldText: string, newText: string, instanceNum...
    method lower (line 828) | lower(text: string): string {
    method upper (line 833) | upper(text: string): string {
    method rept (line 838) | rept(text: string, numTimes: string): string {
    method trim (line 843) | trim(text: string): string {
    method len (line 848) | len(text: string): string {
    method t (line 854) | t(value: string): string {
    method encodeUrlComponent (line 858) | encodeUrlComponent(text: string): string {
    method now (line 864) | now(): string {
    method today (line 873) | today(): string {
    method normalizeIntervalUnit (line 882) | private normalizeIntervalUnit(
    method normalizeDiffUnit (line 943) | private normalizeDiffUnit(
    method normalizeTruncateUnit (line 986) | private normalizeTruncateUnit(
    method dateAdd (line 1031) | dateAdd(date: string, count: string, unit: string): string {
    method datestr (line 1042) | datestr(date: string): string {
    method buildMonthDiff (line 1046) | private buildMonthDiff(startDate: string, endDate: string): string {
    method datetimeDiff (line 1065) | datetimeDiff(startDate: string, endDate: string, unit: string): string {
    method datetimeFormat (line 1095) | datetimeFormat(date: string, format: string): string {
    method datetimeParse (line 1099) | datetimeParse(dateString: string, format?: string): string {
    method day (line 1119) | day(date: string): string {
    method buildNowDiffByUnit (line 1123) | private buildNowDiffByUnit(nowExpr: string, dateExpr: string, unit: st...
    method fromNow (line 1151) | fromNow(date: string, unit = 'day'): string {
    method hour (line 1161) | hour(date: string): string {
    method isAfter (line 1165) | isAfter(date1: string, date2: string): string {
    method isBefore (line 1169) | isBefore(date1: string, date2: string): string {
    method isSame (line 1173) | isSame(date1: string, date2: string, unit?: string): string {
    method lastModifiedTime (line 1190) | lastModifiedTime(): string {
    method minute (line 1195) | minute(date: string): string {
    method month (line 1199) | month(date: string): string {
    method second (line 1203) | second(date: string): string {
    method timestr (line 1207) | timestr(date: string): string {
    method toNow (line 1211) | toNow(date: string, unit = 'day'): string {
    method weekNum (line 1215) | weekNum(date: string): string {
    method weekday (line 1219) | weekday(date: string, _startDayOfWeek?: string): string {
    method workday (line 1223) | workday(startDate: string, days: string, _holidayStr?: string): string {
    method workdayDiff (line 1231) | workdayDiff(startDate: string, endDate: string): string {
    method year (line 1239) | year(date: string): string {
    method createdTime (line 1243) | createdTime(): string {
    method if (line 1249) | if(condition: string, valueIfTrue: string, valueIfFalse: string): stri...
    method and (line 1296) | and(params: string[]): string {
    method or (line 1300) | or(params: string[]): string {
    method not (line 1304) | not(value: string): string {
    method xor (line 1308) | xor(params: string[]): string {
    method blank (line 1321) | blank(): string {
    method error (line 1325) | error(_message: string): string {
    method isError (line 1331) | isError(value: string): string {
    method switch (line 1337) | switch(
    method count (line 1371) | count(params: string[]): string {
    method countA (line 1376) | countA(params: string[]): string {
    method countAll (line 1382) | countAll(value: string): string {
    method normalizeJsonbArray (line 1396) | private normalizeJsonbArray(array: string): string {
    method buildJsonArrayUnion (line 1404) | private buildJsonArrayUnion(
    method arrayJoin (line 1425) | arrayJoin(array: string, separator?: string): string {
    method arrayUnique (line 1430) | arrayUnique(arrays: string[]): string {
    method arrayFlatten (line 1439) | arrayFlatten(arrays: string[]): string {
    method arrayCompact (line 1448) | arrayCompact(arrays: string[]): string {
    method recordId (line 1458) | recordId(): string {
    method autoNumber (line 1463) | autoNumber(): string {
    method textAll (line 1468) | textAll(value: string): string {
    method castToNumber (line 1474) | castToNumber(value: string): string {
    method castToString (line 1478) | castToString(value: string): string {
    method castToBoolean (line 1482) | castToBoolean(value: string): string {
    method castToDate (line 1486) | castToDate(value: string): string {
    method fieldReference (line 1491) | fieldReference(_fieldId: string, columnName: string): string {
    method escapeIdentifier (line 1497) | protected escapeIdentifier(identifier: string): string {
    method guardDefaultDatetimeParse (line 1501) | private guardDefaultDatetimeParse(valueExpr: string): string {
    method parseDatetimeParseWithoutFormat (line 1509) | private parseDatetimeParseWithoutFormat(valueExpr: string): string {
    method parseDatetimeParseWithFormat (line 1532) | private parseDatetimeParseWithFormat(
    method castToTimestamp (line 1552) | private castToTimestamp(date: string, metadataIndex?: number): string {
    method hasTrustedDatetimeInput (line 1590) | private hasTrustedDatetimeInput(index: number): boolean {

FILE: apps/nestjs-backend/src/db-provider/generated-column-query/sqlite/generated-column-query-support-validator.sqlite.ts
  class GeneratedColumnQuerySupportValidatorSqlite (line 17) | class GeneratedColumnQuerySupportValidatorSqlite
    method setContext (line 22) | setContext(context: IFormulaConversionContext): void {
    method setCallMetadata (line 26) | setCallMetadata(): void {
    method sum (line 31) | sum(_params: string[]): boolean {
    method average (line 36) | average(_params: string[]): boolean {
    method max (line 41) | max(_params: string[]): boolean {
    method min (line 45) | min(_params: string[]): boolean {
    method round (line 49) | round(_value: string, _precision?: string): boolean {
    method roundUp (line 53) | roundUp(_value: string, _precision?: string): boolean {
    method roundDown (line 57) | roundDown(_value: string, _precision?: string): boolean {
    method ceiling (line 61) | ceiling(_value: string): boolean {
    method floor (line 66) | floor(_value: string): boolean {
    method even (line 70) | even(_value: string): boolean {
    method odd (line 74) | odd(_value: string): boolean {
    method int (line 78) | int(_value: string): boolean {
    method abs (line 82) | abs(_value: string): boolean {
    method sqrt (line 86) | sqrt(_value: string): boolean {
    method power (line 91) | power(_base: string, _exponent: string): boolean {
    method exp (line 96) | exp(_value: string): boolean {
    method log (line 101) | log(_value: string, _base?: string): boolean {
    method mod (line 106) | mod(_dividend: string, _divisor: string): boolean {
    method value (line 110) | value(_text: string): boolean {
    method concatenate (line 115) | concatenate(_params: string[]): boolean {
    method stringConcat (line 119) | stringConcat(_left: string, _right: string): boolean {
    method find (line 123) | find(_searchText: string, _withinText: string, _startNum?: string): bo...
    method search (line 128) | search(_searchText: string, _withinText: string, _startNum?: string): ...
    method mid (line 133) | mid(_text: string, _startNum: string, _numChars: string): boolean {
    method left (line 137) | left(_text: string, _numChars: string): boolean {
    method right (line 141) | right(_text: string, _numChars: string): boolean {
    method replace (line 145) | replace(_oldText: string, _startNum: string, _numChars: string, _newTe...
    method regexpReplace (line 149) | regexpReplace(_text: string, _pattern: string, _replacement: string): ...
    method substitute (line 154) | substitute(_text: string, _oldText: string, _newText: string, _instanc...
    method lower (line 158) | lower(_text: string): boolean {
    method upper (line 162) | upper(_text: string): boolean {
    method rept (line 166) | rept(_text: string, _numTimes: string): boolean {
    method trim (line 171) | trim(_text: string): boolean {
    method len (line 175) | len(_text: string): boolean {
    method t (line 179) | t(_value: string): boolean {
    method encodeUrlComponent (line 183) | encodeUrlComponent(_text: string): boolean {
    method now (line 189) | now(): boolean {
    method today (line 194) | today(): boolean {
    method dateAdd (line 199) | dateAdd(_date: string, _count: string, _unit: string): boolean {
    method datestr (line 204) | datestr(_date: string): boolean {
    method datetimeDiff (line 208) | datetimeDiff(_startDate: string, _endDate: string, _unit: string): boo...
    method datetimeFormat (line 212) | datetimeFormat(_date: string, _format: string): boolean {
    method datetimeParse (line 216) | datetimeParse(_dateString: string, _format?: string): boolean {
    method day (line 221) | day(_date: string): boolean {
    method fromNow (line 226) | fromNow(_date: string): boolean {
    method hour (line 231) | hour(_date: string): boolean {
    method isAfter (line 236) | isAfter(_date1: string, _date2: string): boolean {
    method isBefore (line 240) | isBefore(_date1: string, _date2: string): boolean {
    method isSame (line 244) | isSame(_date1: string, _date2: string, _unit?: string): boolean {
    method lastModifiedTime (line 248) | lastModifiedTime(): boolean {
    method minute (line 252) | minute(_date: string): boolean {
    method month (line 257) | month(_date: string): boolean {
    method second (line 262) | second(_date: string): boolean {
    method timestr (line 267) | timestr(_date: string): boolean {
    method toNow (line 271) | toNow(_date: string): boolean {
    method weekNum (line 276) | weekNum(_date: string): boolean {
    method weekday (line 280) | weekday(_date: string): boolean {
    method workday (line 285) | workday(_startDate: string, _days: string): boolean {
    method workdayDiff (line 290) | workdayDiff(_startDate: string, _endDate: string): boolean {
    method year (line 295) | year(_date: string): boolean {
    method createdTime (line 300) | createdTime(): boolean {
    method if (line 307) | if(_condition: string, _valueIfTrue: string, _valueIfFalse: string): b...
    method and (line 311) | and(_params: string[]): boolean {
    method or (line 315) | or(_params: string[]): boolean {
    method not (line 319) | not(_value: string): boolean {
    method xor (line 323) | xor(_params: string[]): boolean {
    method blank (line 327) | blank(): boolean {
    method error (line 331) | error(_message: string): boolean {
    method isError (line 336) | isError(_value: string): boolean {
    method switch (line 341) | switch(
    method count (line 350) | count(_params: string[]): boolean {
    method countA (line 354) | countA(_params: string[]): boolean {
    method countAll (line 358) | countAll(_value: string): boolean {
    method arrayJoin (line 362) | arrayJoin(_array: string, _separator?: string): boolean {
    method arrayUnique (line 367) | arrayUnique(_arrays: string[]): boolean {
    method arrayFlatten (line 372) | arrayFlatten(_arrays: string[]): boolean {
    method arrayCompact (line 377) | arrayCompact(_arrays: string[]): boolean {
    method recordId (line 383) | recordId(): boolean {
    method autoNumber (line 388) | autoNumber(): boolean {
    method textAll (line 392) | textAll(_value: string): boolean {
    method add (line 398) | add(_left: string, _right: string): boolean {
    method subtract (line 402) | subtract(_left: string, _right: string): boolean {
    method multiply (line 406) | multiply(_left: string, _right: string): boolean {
    method divide (line 410) | divide(_left: string, _right: string): boolean {
    method modulo (line 414) | modulo(_left: string, _right: string): boolean {
    method equal (line 419) | equal(_left: string, _right: string): boolean {
    method notEqual (line 423) | notEqual(_left: string, _right: string): boolean {
    method greaterThan (line 427) | greaterThan(_left: string, _right: string): boolean {
    method lessThan (line 431) | lessThan(_left: string, _right: string): boolean {
    method greaterThanOrEqual (line 435) | greaterThanOrEqual(_left: string, _right: string): boolean {
    method lessThanOrEqual (line 439) | lessThanOrEqual(_left: string, _right: string): boolean {
    method logicalAnd (line 444) | logicalAnd(_left: string, _right: string): boolean {
    method logicalOr (line 448) | logicalOr(_left: string, _right: string): boolean {
    method bitwiseAnd (line 452) | bitwiseAnd(_left: string, _right: string): boolean {
    method unaryMinus (line 457) | unaryMinus(_value: string): boolean {
    method fieldReference (line 462) | fieldReference(_fieldId: string, _columnName: string): boolean {
    method stringLiteral (line 467) | stringLiteral(_value: string): boolean {
    method numberLiteral (line 471) | numberLiteral(_value: number): boolean {
    method booleanLiteral (line 475) | booleanLiteral(_value: boolean): boolean {
    method nullLiteral (line 479) | nullLiteral(): boolean {
    method castToNumber (line 484) | castToNumber(_value: string): boolean {
    method castToString (line 488) | castToString(_value: string): boolean {
    method castToBoolean (line 492) | castToBoolean(_value: string): boolean {
    method castToDate (line 496) | castToDate(_value: string): boolean {
    method isNull (line 501) | isNull(_value: string): boolean {
    method coalesce (line 505) | coalesce(_params: string[]): boolean {
    method parentheses (line 510) | parentheses(_expression: string): boolean {

FILE: apps/nestjs-backend/src/db-provider/generated-column-query/sqlite/generated-column-query.sqlite.ts
  class GeneratedColumnQuerySqlite (line 10) | class GeneratedColumnQuerySqlite extends GeneratedColumnQueryAbstract {
    method getParamInfo (line 11) | private getParamInfo(index?: number) {
    method isStringLiteral (line 15) | private isStringLiteral(value: string): boolean {
    method isEmptyStringLiteral (line 20) | private isEmptyStringLiteral(value: string): boolean {
    method normalizeBlankComparable (line 24) | private normalizeBlankComparable(value: string): string {
    method buildBlankAwareComparison (line 29) | private buildBlankAwareComparison(operator: '=' | '<>', left: string, ...
    method sum (line 53) | sum(params: string[]): string {
    method average (line 64) | average(params: string[]): string {
    method max (line 75) | max(params: string[]): string {
    method min (line 86) | min(params: string[]): string {
    method round (line 97) | round(value: string, precision?: string): string {
    method roundUp (line 104) | roundUp(value: string, precision?: string): string {
    method roundDown (line 122) | roundDown(value: string, precision?: string): string {
    method ceiling (line 140) | ceiling(value: string): string {
    method floor (line 144) | floor(value: string): string {
    method even (line 148) | even(value: string): string {
    method odd (line 152) | odd(value: string): string {
    method int (line 156) | int(value: string): string {
    method abs (line 160) | abs(value: string): string {
    method sqrt (line 164) | sqrt(value: string): string {
    method power (line 175) | power(base: string, exponent: string): string {
    method exp (line 195) | exp(value: string): string {
    method log (line 199) | log(value: string, base?: string): string {
    method mod (line 207) | mod(dividend: string, divisor: string): string {
    method value (line 211) | value(text: string): string {
    method concatenate (line 216) | concatenate(params: string[]): string {
    method stringConcat (line 224) | stringConcat(left: string, right: string): string {
    method equal (line 228) | equal(left: string, right: string): string {
    method notEqual (line 232) | notEqual(left: string, right: string): string {
    method find (line 236) | find(searchText: string, withinText: string, startNum?: string): string {
    method search (line 243) | search(searchText: string, withinText: string, startNum?: string): str...
    method mid (line 251) | mid(text: string, startNum: string, numChars: string): string {
    method left (line 255) | left(text: string, numChars: string): string {
    method right (line 259) | right(text: string, numChars: string): string {
    method replace (line 263) | replace(oldText: string, startNum: string, numChars: string, newText: ...
    method regexpReplace (line 267) | regexpReplace(text: string, pattern: string, replacement: string): str...
    method substitute (line 272) | substitute(text: string, oldText: string, newText: string, instanceNum...
    method lower (line 277) | lower(text: string): string {
    method upper (line 281) | upper(text: string): string {
    method rept (line 285) | rept(text: string, numTimes: string): string {
    method trim (line 290) | trim(text: string): string {
    method len (line 294) | len(text: string): string {
    method t (line 298) | t(value: string): string {
    method encodeUrlComponent (line 306) | encodeUrlComponent(text: string): string {
    method now (line 312) | now(): string {
    method today (line 325) | today(): string {
    method normalizeDateModifier (line 334) | private normalizeDateModifier(unitLiteral: string): {
    method normalizeDiffUnit (line 380) | private normalizeDiffUnit(
    method normalizeTruncateFormat (line 423) | private normalizeTruncateFormat(unitLiteral: string): string {
    method dateAdd (line 462) | dateAdd(date: string, count: string, unit: string): string {
    method datestr (line 468) | datestr(date: string): string {
    method buildMonthDiff (line 472) | private buildMonthDiff(startDate: string, endDate: string): string {
    method datetimeDiff (line 489) | datetimeDiff(startDate: string, endDate: string, unit: string): string {
    method datetimeFormat (line 516) | datetimeFormat(date: string, format: string): string {
    method datetimeParse (line 530) | datetimeParse(dateString: string, _format?: string): string {
    method day (line 535) | day(date: string): string {
    method buildNowDiffByUnit (line 539) | private buildNowDiffByUnit(nowExpr: string, dateExpr: string, unit: st...
    method fromNow (line 567) | fromNow(date: string, unit = 'day'): string {
    method hour (line 577) | hour(date: string): string {
    method isAfter (line 581) | isAfter(date1: string, date2: string): string {
    method isBefore (line 585) | isBefore(date1: string, date2: string): string {
    method isSame (line 589) | isSame(date1: string, date2: string, unit?: string): string {
    method lastModifiedTime (line 602) | lastModifiedTime(): string {
    method minute (line 606) | minute(date: string): string {
    method month (line 610) | month(date: string): string {
    method second (line 614) | second(date: string): string {
    method timestr (line 618) | timestr(date: string): string {
    method toNow (line 622) | toNow(date: string, unit = 'day'): string {
    method weekNum (line 626) | weekNum(date: string): string {
    method weekday (line 630) | weekday(date: string, _startDayOfWeek?: string): string {
    method workday (line 635) | workday(startDate: string, days: string, _holidayStr?: string): string {
    method workdayDiff (line 639) | workdayDiff(startDate: string, endDate: string): string {
    method year (line 643) | year(date: string): string {
    method createdTime (line 647) | createdTime(): string {
    method normalizeBooleanCondition (line 651) | private normalizeBooleanCondition(condition: string): string {
    method if (line 663) | if(condition: string, valueIfTrue: string, valueIfFalse: string): stri...
    method and (line 668) | and(params: string[]): string {
    method or (line 672) | or(params: string[]): string {
    method not (line 676) | not(value: string): string {
    method xor (line 680) | xor(params: string[]): string {
    method blank (line 692) | blank(): string {
    method error (line 696) | error(_message: string): string {
    method isError (line 702) | isError(value: string): string {
    method switch (line 707) | switch(
    method count (line 727) | count(params: string[]): string {
    method countA (line 732) | countA(params: string[]): string {
    method countAll (line 737) | countAll(value: string): string {
    method buildJsonArrayUnion (line 752) | private buildJsonArrayUnion(
    method arrayJoin (line 771) | arrayJoin(array: string, separator?: string): string {
    method arrayUnique (line 785) | arrayUnique(arrays: string[]): string {
    method arrayFlatten (line 801) | arrayFlatten(arrays: string[]): string {
    method arrayCompact (line 813) | arrayCompact(arrays: string[]): string {
    method recordId (line 829) | recordId(): string {
    method autoNumber (line 833) | autoNumber(): string {
    method textAll (line 837) | textAll(value: string): string {
    method fieldReference (line 846) | fieldReference(_fieldId: string, columnName: string): string {
    method castToNumber (line 853) | castToNumber(value: string): string {
    method castToString (line 857) | castToString(value: string): string {
    method castToBoolean (line 861) | castToBoolean(value: string): string {
    method castToDate (line 865) | castToDate(value: string): string {
    method escapeIdentifier (line 870) | protected escapeIdentifier(identifier: string): string {
    method modulo (line 875) | modulo(left: string, right: string): string {
    method booleanLiteral (line 880) | booleanLiteral(value: boolean): string {

FILE: apps/nestjs-backend/src/db-provider/group-query/group-query.abstract.ts
  method constructor (line 11) | constructor(
  method appendGroupBuilder (line 20) | appendGroupBuilder(): Knex.QueryBuilder {
  method getTableColumnName (line 24) | protected getTableColumnName(field: FieldCore): string {
  method parseGroups (line 32) | private parseGroups(
  method getGroupAdapter (line 52) | private getGroupAdapter(field: FieldCore): Knex.QueryBuilder {

FILE: apps/nestjs-backend/src/db-provider/group-query/group-query.interface.ts
  type IGroupQueryInterface (line 3) | interface IGroupQueryInterface {
  type IGroupQueryExtra (line 7) | interface IGroupQueryExtra {

FILE: apps/nestjs-backend/src/db-provider/group-query/group-query.postgres.ts
  class GroupQueryPostgres (line 10) | class GroupQueryPostgres extends AbstractGroupQuery {
    method constructor (line 11) | constructor(
    method isDistinct (line 22) | private get isDistinct() {
    method string (line 27) | string(field: FieldCore): Knex.QueryBuilder {
    method number (line 38) | number(field: FieldCore): Knex.QueryBuilder {
    method resolveDateTruncUnit (line 56) | private resolveDateTruncUnit(
    method date (line 71) | date(field: FieldCore): Knex.QueryBuilder {
    method json (line 94) | json(field: FieldCore): Knex.QueryBuilder {
    method multipleDate (line 144) | multipleDate(field: FieldCore): Knex.QueryBuilder {
    method multipleNumber (line 175) | multipleNumber(field: FieldCore): Knex.QueryBuilder {

FILE: apps/nestjs-backend/src/db-provider/group-query/group-query.sqlite.ts
  class GroupQuerySqlite (line 11) | class GroupQuerySqlite extends AbstractGroupQuery {
    method constructor (line 12) | constructor(
    method isDistinct (line 23) | private get isDistinct() {
    method string (line 28) | string(field: IFieldInstance): Knex.QueryBuilder {
    method number (line 41) | number(field: IFieldInstance): Knex.QueryBuilder {
    method date (line 54) | date(field: IFieldInstance): Knex.QueryBuilder {
    method json (line 75) | json(field: IFieldInstance): Knex.QueryBuilder {
    method multipleDate (line 109) | multipleDate(field: IFieldInstance): Knex.QueryBuilder {
    method multipleNumber (line 141) | multipleNumber(field: IFieldInstance): Knex.QueryBuilder {

FILE: apps/nestjs-backend/src/db-provider/integrity-query/abstract.ts
  method constructor (line 4) | constructor(protected readonly knex: Knex) {}

FILE: apps/nestjs-backend/src/db-provider/integrity-query/integrity-query.postgres.ts
  class IntegrityQueryPostgres (line 4) | class IntegrityQueryPostgres extends IntegrityQueryAbstract {
    method constructor (line 5) | constructor(protected readonly knex: Knex) {
    method checkLinks (line 9) | checkLinks({
    method fixLinks (line 93) | fixLinks({
    method updateJsonField (line 184) | updateJsonField({

FILE: apps/nestjs-backend/src/db-provider/integrity-query/integrity-query.sqlite.ts
  class IntegrityQuerySqlite (line 4) | class IntegrityQuerySqlite extends IntegrityQueryAbstract {
    method constructor (line 5) | constructor(protected readonly knex: Knex) {
    method checkLinks (line 9) | checkLinks({
    method fixLinks (line 111) | fixLinks({
    method updateJsonField (line 204) | updateJsonField({

FILE: apps/nestjs-backend/src/db-provider/postgres.provider.ts
  class PostgresProvider (line 70) | class PostgresProvider implements IDbProvider {
    method constructor (line 72) | constructor(private readonly knex: Knex) {}
    method createSchema (line 76) | createSchema(schemaName: string) {
    method dropSchema (line 83) | dropSchema(schemaName: string): string {
    method generateDbTableName (line 87) | generateDbTableName(baseId: string, name: string) {
    method getForeignKeysInfo (line 91) | getForeignKeysInfo(dbTableName: string) {
    method renameTableName (line 117) | renameTableName(oldTableName: string, newTableName: string) {
    method dropTable (line 124) | dropTable(tableName: string): string {
    method checkColumnExist (line 128) | async checkColumnExist(
    method checkTableExist (line 144) | checkTableExist(tableName: string): string {
    method renameColumn (line 154) | renameColumn(tableName: string, oldName: string, newName: string): str...
    method dropColumn (line 163) | dropColumn(
    method dropColumnAndIndex (line 182) | dropColumnAndIndex(tableName: string, columnName: string, _indexName: ...
    method columnInfo (line 192) | columnInfo(tableName: string): string {
    method updateJsonColumn (line 206) | updateJsonColumn(
    method updateJsonArrayColumn (line 230) | updateJsonArrayColumn(
    method modifyColumnSchema (line 258) | modifyColumnSchema(
    method createColumnSchema (line 327) | createColumnSchema(
    method splitTableName (line 368) | splitTableName(tableName: string): string[] {
    method joinDbTableName (line 372) | joinDbTableName(schemaName: string, dbTableName: string) {
    method duplicateTable (line 376) | duplicateTable(
    method alterAutoNumber (line 394) | alterAutoNumber(tableName: string): string[] {
    method batchInsertSql (line 416) | batchInsertSql(tableName: string, insertData: ReadonlyArray<unknown>):...
    method executeUpdateRecordsSqlList (line 420) | executeUpdateRecordsSqlList(params: {
    method updateFromSelectSql (line 453) | updateFromSelectSql(params: {
    method lockRecordsSql (line 524) | lockRecordsSql(params: {
    method aggregationQuery (line 545) | aggregationQuery(
    method filterQuery (line 562) | filterQuery(
    method sortQuery (line 572) | sortQuery(
    method groupQuery (line 582) | groupQuery(
    method searchQuery (line 599) | searchQuery(
    method searchCountQuery (line 616) | searchCountQuery(
    method searchIndexQuery (line 633) | searchIndexQuery(
    method searchIndex (line 657) | searchIndex() {
    method duplicateTableQuery (line 661) | duplicateTableQuery(queryBuilder: Knex.QueryBuilder) {
    method duplicateAttachmentTableQuery (line 665) | duplicateAttachmentTableQuery(queryBuilder: Knex.QueryBuilder) {
    method shareFilterCollaboratorsQuery (line 669) | shareFilterCollaboratorsQuery(
    method baseQuery (line 685) | baseQuery(): BaseQueryAbstract {
    method integrityQuery (line 689) | integrityQuery(): IntegrityQueryAbstract {
    method calendarDailyCollectionQuery (line 693) | calendarDailyCollectionQuery(
    method lookupOptionsQuery (line 758) | lookupOptionsQuery(optionsKey: keyof ILookupLinkOptionsVo, value: stri...
    method optionsQuery (line 772) | optionsQuery(type: FieldType, optionsKey: string, value: string): stri...
    method searchBuilder (line 801) | searchBuilder(qb: Knex.QueryBuilder, search: [string, string][]): Knex...
    method getTableIndexes (line 809) | getTableIndexes(dbTableName: string): string {
    method generatedColumnQuery (line 842) | generatedColumnQuery(): IGeneratedColumnQueryInterface {
    method convertFormulaToGeneratedColumn (line 846) | convertFormulaToGeneratedColumn(
    method selectQuery (line 870) | selectQuery(): ISelectQueryInterface {
    method convertFormulaToSelectQuery (line 874) | convertFormulaToSelectQuery(
    method generateDatabaseViewName (line 897) | generateDatabaseViewName(tableId: string): string {
    method createDatabaseView (line 901) | createDatabaseView(
    method recreateDatabaseView (line 918) | recreateDatabaseView(table: TableDomain, qb: Knex.QueryBuilder): strin...
    method dropDatabaseView (line 940) | dropDatabaseView(tableId: string): string[] {
    method refreshDatabaseView (line 949) | refreshDatabaseView(tableId: string, options?: { concurrently?: boolea...
    method createMaterializedView (line 963) | createMaterializedView(table: TableDomain, qb: Knex.QueryBuilder): str...
    method dropMaterializedView (line 968) | dropMaterializedView(tableId: string): string {

FILE: apps/nestjs-backend/src/db-provider/search-query/abstract.ts
  method appendQueryBuilder (line 8) | static appendQueryBuilder(
  method buildSearchCountQuery (line 29) | static buildSearchCountQuery(
  method constructor (line 72) | constructor(
  method normalizeSelection (line 111) | private normalizeSelection(selection: unknown): string | undefined {
  method quoteIdentifier (line 127) | private quoteIdentifier(identifier: string): string {

FILE: apps/nestjs-backend/src/db-provider/search-query/get-offset.ts
  function getOffset (line 4) | function getOffset(timeZone: string) {

FILE: apps/nestjs-backend/src/db-provider/search-query/search-index-builder.postgres.ts
  type IPgIndex (line 8) | interface IPgIndex {
  class FieldFormatter (line 18) | class FieldFormatter {
    method getSearchableExpression (line 19) | static getSearchableExpression(field: IFieldInstance, isArray = false)...
    method getIndexExpression (line 69) | static getIndexExpression(field: IFieldInstance): string | null {
  class IndexBuilderPostgres (line 74) | class IndexBuilderPostgres extends IndexBuilderAbstract {
    method getIndexPrefix (line 78) | private getIndexPrefix() {
    method getIndexName (line 82) | private getIndexName(table: string, field: Pick<IFieldInstance, 'id' |...
    method getSearchFactor (line 104) | private getSearchFactor() {
    method createSingleIndexSql (line 108) | createSingleIndexSql(dbTableName: string, field: IFieldInstance): stri...
    method getDropIndexSql (line 119) | getDropIndexSql(dbTableName: string): string {
    method getCreateIndexSql (line 140) | getCreateIndexSql(dbTableName: string, searchFields: IFieldInstance[])...
    method getExistTableIndexSql (line 153) | getExistTableIndexSql(dbTableName: string): string {
    method getDeleteSingleIndexSql (line 166) | getDeleteSingleIndexSql(dbTableName: string, field: IFieldInstance): s...
    method getUpdateSingleIndexNameSql (line 173) | getUpdateSingleIndexNameSql(
    method getIndexInfoSql (line 188) | getIndexInfoSql(dbTableName: string): string {
    method getAbnormalIndex (line 197) | getAbnormalIndex(dbTableName: string, fields: IFieldInstance[], existi...

FILE: apps/nestjs-backend/src/db-provider/search-query/search-index-builder.sqlite.ts
  type ISqliteIndex (line 8) | type ISqliteIndex = Record<string, unknown>;
  class FieldFormatter (line 10) | class FieldFormatter {
    method getSearchableExpression (line 11) | static getSearchableExpression(field: IFieldInstance, isArray = false)...
    method getIndexExpression (line 59) | static getIndexExpression(field: IFieldInstance): string {
  constant NO_OPERATION_SQL (line 65) | const NO_OPERATION_SQL = '/* no operation */';
  class IndexBuilderSqlite (line 67) | class IndexBuilderSqlite extends IndexBuilderAbstract {
    method getIndexName (line 68) | private getIndexName(table: string, dbFieldName: string): string {
    method createSingleIndexSql (line 72) | createSingleIndexSql(dbTableName: string, field: IFieldInstance): stri...
    method getDropIndexSql (line 76) | getDropIndexSql(dbTableName: string): string {
    method getCreateIndexSql (line 83) | getCreateIndexSql(dbTableName: string, searchFields: IFieldInstance[])...
    method getExistTableIndexSql (line 87) | getExistTableIndexSql(dbTableName: string): string {
    method getDeleteSingleIndexSql (line 96) | getDeleteSingleIndexSql(dbTableName: string, field: IFieldInstance): s...
    method getUpdateSingleIndexNameSql (line 100) | getUpdateSingleIndexNameSql(
    method getIndexInfoSql (line 108) | getIndexInfoSql(dbTableName: string): string {
    method getAbnormalIndex (line 112) | getAbnormalIndex(dbTableName: string, fields: IFieldInstance[], existi...

FILE: apps/nestjs-backend/src/db-provider/search-query/search-query.postgres.ts
  class SearchQueryPostgres (line 15) | class SearchQueryPostgres extends SearchQueryAbstract {
    method constructor (line 17) | constructor(
    method appendBuilder (line 28) | appendBuilder() {
    method getSql (line 35) | getSql(): string | null {
    method getQuery (line 40) | getQuery() {
    method getSearchQueryWithIndex (line 51) | protected getSearchQueryWithIndex() {
    method getSingleCellTypeQuery (line 67) | protected getSingleCellTypeQuery() {
    method getMultipleCellTypeQuery (line 89) | protected getMultipleCellTypeQuery() {
    method text (line 111) | protected text() {
    method number (line 127) | protected number() {
    method date (line 138) | protected date() {
    method json (line 153) | protected json() {
    method multipleText (line 162) | protected multipleText() {
    method multipleNumber (line 181) | protected multipleNumber() {
    method multipleDate (line 200) | protected multipleDate() {
    method multipleJson (line 219) | protected multipleJson() {
  class SearchQueryPostgresBuilder (line 246) | class SearchQueryPostgresBuilder {
    method constructor (line 247) | constructor(
    method getSearchConditions (line 269) | private getSearchConditions() {
    method getCaseWhenSqlBy (line 292) | getCaseWhenSqlBy() {
    method getSearchIndexQuery (line 319) | getSearchIndexQuery() {

FILE: apps/nestjs-backend/src/db-provider/search-query/search-query.sqlite.ts
  class SearchQuerySqlite (line 12) | class SearchQuerySqlite extends SearchQueryAbstract {
    method constructor (line 14) | constructor(
    method appendBuilder (line 25) | appendBuilder() {
    method getSql (line 32) | getSql(): string | null {
    method getQuery (line 36) | getQuery() {
    method getSearchQueryWithIndex (line 43) | protected getSearchQueryWithIndex() {
    method getMultipleCellTypeQuery (line 47) | protected getMultipleCellTypeQuery() {
    method getSingleCellTypeQuery (line 69) | protected getSingleCellTypeQuery() {
    method text (line 91) | protected text() {
    method json (line 101) | protected json() {
    method date (line 110) | protected date() {
    method number (line 121) | protected number() {
    method multipleText (line 132) | protected multipleText() {
    method multipleJson (line 151) | protected multipleJson() {
    method multipleNumber (line 169) | protected multipleNumber() {
    method multipleDate (line 188) | protected multipleDate() {
  class SearchQuerySqliteBuilder (line 208) | class SearchQuerySqliteBuilder {
    method constructor (line 209) | constructor(
    method getSearchConditions (line 230) | private getSearchConditions() {
    method getSearchIndexQuery (line 250) | getSearchIndexQuery() {

FILE: apps/nestjs-backend/src/db-provider/search-query/types.ts
  type ISearchCellValueType (line 8) | type ISearchCellValueType = Exclude<CellValueType, CellValueType.Boolean>;
  type ISearchQueryConstructor (line 10) | type ISearchQueryConstructor = {

FILE: apps/nestjs-backend/src/db-provider/select-query/postgres/select-query.postgres.ts
  class SelectQueryPostgres (line 29) | class SelectQueryPostgres extends SelectQueryAbstract {
    method tableAlias (line 30) | private get tableAlias(): string | undefined {
    method qualifySystemColumn (line 35) | private qualifySystemColumn(column: string): string {
    method hasWrappingParentheses (line 41) | private hasWrappingParentheses(expr: string): boolean {
    method stripOuterParentheses (line 63) | private stripOuterParentheses(expr: string): string {
    method getParamInfo (line 71) | private getParamInfo(index?: number) {
    method isNumericLiteral (line 75) | private isNumericLiteral(expr: string): boolean {
    method toNumericSafe (line 100) | private toNumericSafe(
    method looseNumericCoercion (line 153) | private looseNumericCoercion(
    method numericFromJson (line 187) | private numericFromJson(expr: string): string {
    method buildNumericArrayAggregation (line 199) | private buildNumericArrayAggregation(expr: string): { sum: string; cou...
    method buildNumericArrayExtremum (line 211) | private buildNumericArrayExtremum(expr: string, op: 'max' | 'min'): st...
    method collapseNumeric (line 220) | private collapseNumeric(expr: string, metadataIndex?: number): string {
    method isDateLikeOperand (line 225) | private isDateLikeOperand(metadataIndex?: number): boolean {
    method buildDayInterval (line 246) | private buildDayInterval(expr: string, metadataIndex?: number): string {
    method isEmptyStringLiteral (line 251) | private isEmptyStringLiteral(value: string): boolean {
    method isNullLiteral (line 255) | private isNullLiteral(value: string): boolean {
    method shouldCoalesceNumericComparison (line 259) | private shouldCoalesceNumericComparison(value: string, metadataIndex?:...
    method normalizeNumericComparisonOperand (line 267) | private normalizeNumericComparisonOperand(value: string, metadataIndex...
    method normalizeBlankComparable (line 275) | private normalizeBlankComparable(value: string, metadataIndex?: number...
    method ensureTextCollation (line 282) | private ensureTextCollation(expr: string): string {
    method isTextLikeExpression (line 286) | private isTextLikeExpression(value: string, metadataIndex?: number): b...
    method isNumericLikeExpression (line 312) | private isNumericLikeExpression(value: string, metadataIndex?: number)...
    method getExpressionFieldType (line 341) | private getExpressionFieldType(value: string): DbFieldType | undefined {
    method isHardTextExpression (line 368) | private isHardTextExpression(value: string): boolean {
    method coerceArrayLikeToText (line 379) | private coerceArrayLikeToText(expr: string, metadataIndex?: number): s...
    method buildJsonScalarCoercion (line 408) | private buildJsonScalarCoercion(jsonExpr: string): string {
    method coerceJsonExpressionToText (line 433) | private coerceJsonExpressionToText(wrapped: string, metadataIndex?: nu...
    method coerceNonJsonExpressionToText (line 442) | private coerceNonJsonExpressionToText(wrapped: string): string {
    method coerceToTextComparable (line 452) | private coerceToTextComparable(value: string, metadataIndex?: number):...
    method countANonNullExpression (line 518) | private countANonNullExpression(value: string, metadataIndex?: number)...
    method normalizeIntervalUnit (line 527) | private normalizeIntervalUnit(
    method normalizeDiffUnit (line 588) | private normalizeDiffUnit(
    method normalizeTruncateUnit (line 631) | private normalizeTruncateUnit(
    method buildBlankAwareComparison (line 676) | private buildBlankAwareComparison(
    method sanitizeTimestampInput (line 734) | private sanitizeTimestampInput(date: string): string {
    method isTrustedDatetime (line 740) | private isTrustedDatetime(expr: string, metadataIndex?: number): boole...
    method isTimestampish (line 755) | private isTimestampish(expr: string): boolean {
    method shouldTreatAsDatetime (line 765) | private shouldTreatAsDatetime(expr: string, metadataIndex?: number): b...
    method tzWrap (line 784) | private tzWrap(date: string, metadataIndex?: number): string {
    method buildTimezoneOffsetSql (line 803) | private buildTimezoneOffsetSql(localTimestampSql: string): string {
    method getDatePattern (line 815) | private getDatePattern(date: DateFormattingPreset | string): string {
    method getTimePattern (line 844) | private getTimePattern(time?: TimeFormatting): string | null {
    method buildDatetimeFormatting (line 855) | private buildDatetimeFormatting(formatting?: Partial<IDatetimeFormatti...
    method normalizeAnyToJsonArray (line 870) | private normalizeAnyToJsonArray(expr: string): string {
    method extractFirstScalarFromMultiValue (line 880) | private extractFirstScalarFromMultiValue(expr: string): string {
    method formatDatetimeOperandForSlice (line 889) | private formatDatetimeOperandForSlice(expr: string, metadataIndex: num...
    method buildSliceOperand (line 958) | private buildSliceOperand(expr: string, metadataIndex: number): string {
    method sum (line 966) | sum(params: string[]): string {
    method average (line 985) | average(params: string[]): string {
    method max (line 1014) | max(params: string[]): string {
    method min (line 1025) | min(params: string[]): string {
    method round (line 1036) | round(value: string, precision?: string): string {
    method roundUp (line 1043) | roundUp(value: string, precision?: string): string {
    method roundDown (line 1053) | roundDown(value: string, precision?: string): string {
    method ceiling (line 1063) | ceiling(value: string): string {
    method floor (line 1067) | floor(value: string): string {
    method even (line 1071) | even(value: string): string {
    method odd (line 1077) | odd(value: string): string {
    method int (line 1083) | int(value: string): string {
    method abs (line 1087) | abs(value: string): string {
    method sqrt (line 1091) | sqrt(value: string): string {
    method power (line 1095) | power(base: string, exponent: string): string {
    method exp (line 1101) | exp(value: string): string {
    method log (line 1105) | log(value: string, base?: string): string {
    method mod (line 1115) | mod(dividend: string, divisor: string): string {
    method value (line 1121) | value(text: string): string {
    method concatenate (line 1126) | concatenate(params: string[]): string {
    method stringConcat (line 1130) | stringConcat(left: string, right: string): string {
    method find (line 1137) | find(searchText: string, withinText: string, startNum?: string): string {
    method search (line 1147) | search(searchText: string, withinText: string, startNum?: string): str...
    method mid (line 1158) | mid(text: string, startNum: string, numChars: string): string {
    method left (line 1163) | left(text: string, numChars: string): string {
    method right (line 1168) | right(text: string, numChars: string): string {
    method replace (line 1173) | replace(oldText: string, startNum: string, numChars: string, newText: ...
    method regexpReplace (line 1179) | regexpReplace(text: string, pattern: string, replacement: string): str...
    method substitute (line 1186) | substitute(text: string, oldText: string, newText: string, instanceNum...
    method lower (line 1198) | lower(text: string): string {
    method upper (line 1203) | upper(text: string): string {
    method rept (line 1208) | rept(text: string, numTimes: string): string {
    method trim (line 1213) | trim(text: string): string {
    method len (line 1218) | len(text: string): string {
    method t (line 1224) | t(value: string): string {
    method encodeUrlComponent (line 1228) | encodeUrlComponent(text: string): string {
    method now (line 1252) | now(): string {
    method today (line 1256) | today(): string {
    method dateAdd (line 1260) | dateAdd(date: string, count: string, unit: string): string {
    method datestr (line 1271) | datestr(date: string): string {
    method buildMonthDiff (line 1275) | private buildMonthDiff(startDate: string, endDate: string): string {
    method datetimeDiff (line 1294) | datetimeDiff(startDate: string, endDate: string, unit: string): string {
    method datetimeFormat (line 1325) | datetimeFormat(date: string, format: string): string {
    method datetimeParse (line 1334) | datetimeParse(dateString: string, format?: string): string {
    method day (line 1358) | day(date: string): string {
    method buildNowDiffByUnit (line 1362) | private buildNowDiffByUnit(nowExpr: string, dateExpr: string, unit: st...
    method fromNow (line 1390) | fromNow(date: string, unit = 'day'): string {
    method hour (line 1398) | hour(date: string): string {
    method isAfter (line 1402) | isAfter(date1: string, date2: string): string {
    method isBefore (line 1406) | isBefore(date1: string, date2: string): string {
    method isSame (line 1410) | isSame(date1: string, date2: string, unit?: string): string {
    method lastModifiedTime (line 1427) | lastModifiedTime(): string {
    method minute (line 1432) | minute(date: string): string {
    method month (line 1436) | month(date: string): string {
    method second (line 1440) | second(date: string): string {
    method timestr (line 1444) | timestr(date: string): string {
    method toNow (line 1448) | toNow(date: string, unit = 'day'): string {
    method weekNum (line 1452) | weekNum(date: string): string {
    method weekday (line 1456) | weekday(date: string, startDayOfWeek?: string): string {
    method workday (line 1466) | workday(startDate: string, days: string, holidayStr?: string): string {
    method workdayDiff (line 1518) | workdayDiff(startDate: string, endDate: string): string {
    method year (line 1528) | year(date: string): string {
    method createdTime (line 1532) | createdTime(): string {
    method truthinessScore (line 1538) | private truthinessScore(value: string, metadataIndex?: number): string {
    method if (line 1589) | if(condition: string, valueIfTrue: string, valueIfFalse: string): stri...
    method and (line 1640) | and(params: string[]): string {
    method or (line 1644) | or(params: string[]): string {
    method not (line 1648) | not(value: string): string {
    method xor (line 1652) | xor(params: string[]): string {
    method blank (line 1661) | blank(): string {
    method error (line 1665) | error(_message: string): string {
    method isError (line 1670) | isError(_value: string): string {
    method switch (line 1675) | switch(
    method count (line 1703) | count(params: string[]): string {
    method countA (line 1708) | countA(params: string[]): string {
    method countAll (line 1713) | countAll(value: string): string {
    method normalizeJsonbArray (line 1732) | private normalizeJsonbArray(array: string): string {
    method buildJsonbArrayUnion (line 1742) | private buildJsonbArrayUnion(
    method arrayJoin (line 1763) | arrayJoin(array: string, separator?: string): string {
    method arrayUnique (line 1775) | arrayUnique(arrays: string[]): string {
    method arrayFlatten (line 1784) | arrayFlatten(arrays: string[]): string {
    method arrayCompact (line 1793) | arrayCompact(arrays: string[]): string {
    method recordId (line 1803) | recordId(): string {
    method autoNumber (line 1808) | autoNumber(): string {
    method textAll (line 1813) | textAll(value: string): string {
    method add (line 1818) | add(left: string, right: string): string {
    method subtract (line 1835) | subtract(left: string, right: string): string {
    method multiply (line 1852) | multiply(left: string, right: string): string {
    method divide (line 1858) | divide(left: string, right: string): string {
    method modulo (line 1864) | modulo(left: string, right: string): string {
    method equal (line 1871) | equal(left: string, right: string): string {
    method notEqual (line 1875) | notEqual(left: string, right: string): string {
    method greaterThan (line 1879) | greaterThan(left: string, right: string): string {
    method lessThan (line 1885) | lessThan(left: string, right: string): string {
    method greaterThanOrEqual (line 1891) | greaterThanOrEqual(left: string, right: string): string {
    method lessThanOrEqual (line 1897) | lessThanOrEqual(left: string, right: string): string {
    method logicalAnd (line 1904) | logicalAnd(left: string, right: string): string {
    method logicalOr (line 1908) | logicalOr(left: string, right: string): string {
    method bitwiseAnd (line 1912) | bitwiseAnd(left: string, right: string): string {
    method unaryMinus (line 1936) | unaryMinus(value: string): string {
    method fieldReference (line 1942) | fieldReference(_fieldId: string, columnName: string): string {
    method stringLiteral (line 1947) | stringLiteral(value: string): string {
    method numberLiteral (line 1951) | numberLiteral(value: number): string {
    method booleanLiteral (line 1955) | booleanLiteral(value: boolean): string {
    method nullLiteral (line 1959) | nullLiteral(): string {
    method castToNumber (line 1964) | castToNumber(value: string): string {
    method castToString (line 1968) | castToString(value: string): string {
    method castToBoolean (line 1972) | castToBoolean(value: string): string {
    method castToDate (line 1976) | castToDate(value: string): string {
    method isNull (line 1981) | isNull(value: string): string {
    method coalesce (line 1985) | coalesce(params: string[]): string {
    method parentheses (line 1990) | parentheses(expression: string): string {
    method guardDefaultDatetimeParse (line 1994) | private guardDefaultDatetimeParse(valueExpr: string): string {
    method parseDatetimeParseWithoutFormat (line 2002) | private parseDatetimeParseWithoutFormat(valueExpr: string): string {
    method parseDatetimeParseWithFormat (line 2025) | private parseDatetimeParseWithFormat(
    method hasTrustedDatetimeInput (line 2046) | private hasTrustedDatetimeInput(index: number): boolean {

FILE: apps/nestjs-backend/src/db-provider/select-query/select-query.abstract.ts
  method setContext (line 24) | setContext(context: IFormulaConversionContext): void {
  method setCallMetadata (line 28) | setCallMetadata(metadata?: IFormulaParamMetadata[]): void {
  method isSelectQueryContext (line 33) | protected get isSelectQueryContext(): boolean {
  method joinParams (line 38) | protected joinParams(params: string[]): string {
  method wrapInParentheses (line 43) | protected wrapInParentheses(expression: string): string {
  method handleNullValue (line 48) | protected handleNullValue(expression: string, defaultValue: string = 'NU...

FILE: apps/nestjs-backend/src/db-provider/select-query/sqlite/select-query.sqlite.ts
  class SelectQuerySqlite (line 11) | class SelectQuerySqlite extends SelectQueryAbstract {
    method tableAlias (line 12) | private get tableAlias(): string | undefined {
    method getParamInfo (line 17) | private getParamInfo(index?: number) {
    method isStringLiteral (line 21) | private isStringLiteral(value: string): boolean {
    method qualifySystemColumn (line 26) | private qualifySystemColumn(column: string): string {
    method isEmptyStringLiteral (line 32) | private isEmptyStringLiteral(value: string): boolean {
    method normalizeBlankComparable (line 36) | private normalizeBlankComparable(value: string): string {
    method buildBlankAwareComparison (line 40) | private buildBlankAwareComparison(operator: '=' | '<>', left: string, ...
    method coalesceNumeric (line 63) | private coalesceNumeric(expr: string): string {
    method sum (line 68) | sum(params: string[]): string {
    method average (line 79) | average(params: string[]): string {
    method max (line 87) | max(params: string[]): string {
    method min (line 91) | min(params: string[]): string {
    method round (line 95) | round(value: string, precision?: string): string {
    method roundUp (line 102) | roundUp(value: string, precision?: string): string {
    method roundDown (line 110) | roundDown(value: string, precision?: string): string {
    method ceiling (line 118) | ceiling(value: string): string {
    method floor (line 122) | floor(value: string): string {
    method even (line 126) | even(value: string): string {
    method odd (line 130) | odd(value: string): string {
    method int (line 134) | int(value: string): string {
    method abs (line 138) | abs(value: string): string {
    method sqrt (line 142) | sqrt(value: string): string {
    method power (line 146) | power(base: string, exponent: string): string {
    method exp (line 150) | exp(value: string): string {
    method log (line 154) | log(value: string, base?: string): string {
    method mod (line 163) | mod(dividend: string, divisor: string): string {
    method value (line 167) | value(text: string): string {
    method concatenate (line 172) | concatenate(params: string[]): string {
    method stringConcat (line 176) | stringConcat(left: string, right: string): string {
    method find (line 180) | find(searchText: string, withinText: string, startNum?: string): string {
    method search (line 187) | search(searchText: string, withinText: string, startNum?: string): str...
    method mid (line 195) | mid(text: string, startNum: string, numChars: string): string {
    method left (line 199) | left(text: string, numChars: string): string {
    method right (line 203) | right(text: string, numChars: string): string {
    method replace (line 207) | replace(oldText: string, startNum: string, numChars: string, newText: ...
    method regexpReplace (line 211) | regexpReplace(text: string, pattern: string, replacement: string): str...
    method substitute (line 216) | substitute(text: string, oldText: string, newText: string, instanceNum...
    method lower (line 221) | lower(text: string): string {
    method upper (line 225) | upper(text: string): string {
    method rept (line 229) | rept(text: string, numTimes: string): string {
    method trim (line 234) | trim(text: string): string {
    method len (line 238) | len(text: string): string {
    method t (line 242) | t(value: string): string {
    method encodeUrlComponent (line 247) | encodeUrlComponent(text: string): string {
    method now (line 253) | now(): string {
    method normalizeDateModifier (line 257) | private normalizeDateModifier(unitLiteral: string): {
    method normalizeDiffUnit (line 303) | private normalizeDiffUnit(
    method normalizeTruncateFormat (line 346) | private normalizeTruncateFormat(unitLiteral: string): string {
    method today (line 385) | today(): string {
    method dateAdd (line 389) | dateAdd(date: string, count: string, unit: string): string {
    method datestr (line 395) | datestr(date: string): string {
    method buildMonthDiff (line 399) | private buildMonthDiff(startDate: string, endDate: string): string {
    method datetimeDiff (line 416) | datetimeDiff(startDate: string, endDate: string, unit: string): string {
    method datetimeFormat (line 443) | datetimeFormat(date: string, format: string): string {
    method datetimeParse (line 447) | datetimeParse(dateString: string, _format?: string): string {
    method day (line 452) | day(date: string): string {
    method buildNowDiffByUnit (line 456) | private buildNowDiffByUnit(nowExpr: string, dateExpr: string, unit: st...
    method fromNow (line 483) | fromNow(date: string, unit = 'day'): string {
    method hour (line 487) | hour(date: string): string {
    method isAfter (line 491) | isAfter(date1: string, date2: string): string {
    method isBefore (line 495) | isBefore(date1: string, date2: string): string {
    method isSame (line 499) | isSame(date1: string, date2: string, unit?: string): string {
    method lastModifiedTime (line 512) | lastModifiedTime(): string {
    method minute (line 516) | minute(date: string): string {
    method month (line 520) | month(date: string): string {
    method second (line 524) | second(date: string): string {
    method timestr (line 528) | timestr(date: string): string {
    method toNow (line 532) | toNow(date: string, unit = 'day'): string {
    method weekNum (line 536) | weekNum(date: string): string {
    method weekday (line 540) | weekday(date: string, startDayOfWeek?: string): string {
    method workday (line 552) | workday(startDate: string, days: string, holidayStr?: string): string {
    method workdayDiff (line 614) | workdayDiff(startDate: string, endDate: string): string {
    method year (line 618) | year(date: string): string {
    method createdTime (line 622) | createdTime(): string {
    method truthinessScore (line 627) | private truthinessScore(value: string): string {
    method if (line 638) | if(condition: string, valueIfTrue: string, valueIfFalse: string): stri...
    method and (line 643) | and(params: string[]): string {
    method or (line 647) | or(params: string[]): string {
    method not (line 651) | not(value: string): string {
    method xor (line 655) | xor(params: string[]): string {
    method blank (line 662) | blank(): string {
    method error (line 667) | error(_message: string): string {
    method isError (line 672) | isError(_value: string): string {
    method switch (line 676) | switch(
    method count (line 693) | count(params: string[]): string {
    method countA (line 697) | countA(params: string[]): string {
    method countAll (line 701) | countAll(value: string): string {
    method buildJsonArrayUnion (line 721) | private buildJsonArrayUnion(
    method arrayJoin (line 740) | arrayJoin(array: string, separator?: string): string {
    method arrayUnique (line 746) | arrayUnique(arrays: string[]): string {
    method arrayFlatten (line 762) | arrayFlatten(arrays: string[]): string {
    method arrayCompact (line 774) | arrayCompact(arrays: string[]): string {
    method recordId (line 790) | recordId(): string {
    method autoNumber (line 794) | autoNumber(): string {
    method textAll (line 798) | textAll(value: string): string {
    method add (line 803) | add(left: string, right: string): string {
    method subtract (line 807) | subtract(left: string, right: string): string {
    method multiply (line 811) | multiply(left: string, right: string): string {
    method divide (line 815) | divide(left: string, right: string): string {
    method modulo (line 819) | modulo(left: string, right: string): string {
    method equal (line 824) | equal(left: string, right: string): string {
    method notEqual (line 828) | notEqual(left: string, right: string): string {
    method greaterThan (line 832) | greaterThan(left: string, right: string): string {
    method lessThan (line 836) | lessThan(left: string, right: string): string {
    method greaterThanOrEqual (line 840) | greaterThanOrEqual(left: string, right: string): string {
    method lessThanOrEqual (line 844) | lessThanOrEqual(left: string, right: string): string {
    method logicalAnd (line 849) | logicalAnd(left: string, right: string): string {
    method logicalOr (line 853) | logicalOr(left: string, right: string): string {
    method bitwiseAnd (line 857) | bitwiseAnd(left: string, right: string): string {
    method unaryMinus (line 862) | unaryMinus(value: string): string {
    method fieldReference (line 867) | fieldReference(_fieldId: string, columnName: string): string {
    method stringLiteral (line 872) | stringLiteral(value: string): string {
    method numberLiteral (line 876) | numberLiteral(value: number): string {
    method booleanLiteral (line 880) | booleanLiteral(value: boolean): string {
    method nullLiteral (line 884) | nullLiteral(): string {
    method castToNumber (line 889) | castToNumber(value: string): string {
    method castToString (line 893) | castToString(value: string): string {
    method castToBoolean (line 897) | castToBoolean(value: string): string {
    method castToDate (line 901) | castToDate(value: string): string {
    method isNull (line 906) | isNull(value: string): string {
    method coalesce (line 910) | coalesce(params: string[]): string {
    method parentheses (line 915) | parentheses(expression: string): string {

FILE: apps/nestjs-backend/src/db-provider/sort-query/function/sort-function.abstract.ts
  method constructor (line 11) | constructor(
  method compiler (line 35) | compiler(builderClient: Knex.QueryBuilder, sortFunc: SortFunc) {
  method generateSQL (line 49) | generateSQL(sortFunc: SortFunc): string | undefined {
  method asc (line 63) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
  method desc (line 71) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
  method getAscSQL (line 79) | getAscSQL() {
  method getDescSQL (line 86) | getDescSQL() {
  method createSqlPlaceholders (line 93) | protected createSqlPlaceholders(values: unknown[]): string {
  method normalizeSelection (line 97) | private normalizeSelection(selection: unknown): string | undefined {
  method quoteIdentifier (line 113) | private quoteIdentifier(identifier: string): string {
  method isNullConstant (line 124) | private isNullConstant(selection?: string): boolean {

FILE: apps/nestjs-backend/src/db-provider/sort-query/function/sort-function.interface.ts
  type ISortFunctionHandler (line 3) | type ISortFunctionHandler = (builderClient: Knex.QueryBuilder) => Knex.Q...
  type ISortFunctionInterface (line 5) | interface ISortFunctionInterface {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/multiple-value/multiple-datetime-sort.adapter.ts
  class MultipleDateTimeSortAdapter (line 6) | class MultipleDateTimeSortAdapter extends SortFunctionPostgres {
    method asc (line 7) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 44) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 81) | getAscSQL() {
    method getDescSQL (line 119) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/multiple-value/multiple-json-sort.adapter.ts
  class MultipleJsonSortAdapter (line 7) | class MultipleJsonSortAdapter extends SortFunctionPostgres {
    method firstChoiceIndexExpr (line 12) | private firstChoiceIndexExpr(optionSets: string[]) {
    method orderByMultiSelect (line 25) | private orderByMultiSelect(
    method asc (line 41) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 61) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 81) | getAscSQL() {
    method getDescSQL (line 107) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/multiple-value/multiple-number-sort.adapter.ts
  class MultipleNumberSortAdapter (line 5) | class MultipleNumberSortAdapter extends SortFunctionPostgres {
    method asc (line 6) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 28) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 50) | getAscSQL() {
    method getDescSQL (line 72) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/single-value/date-sort.adapter.ts
  class DateSortAdapter (line 6) | class DateSortAdapter extends SortFunctionPostgres {
    method asc (line 7) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 27) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 47) | getAscSQL() {
    method getDescSQL (line 67) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/single-value/json-sort.adapter.ts
  class JsonSortAdapter (line 5) | class JsonSortAdapter extends SortFunctionPostgres {
    method asc (line 6) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 20) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 34) | getAscSQL() {
    method getDescSQL (line 47) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/single-value/string-sort.adapter.ts
  class StringSortAdapter (line 6) | class StringSortAdapter extends SortFunctionPostgres {
    method asc (line 7) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 29) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 51) | getAscSQL() {
    method getDescSQL (line 72) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/sort-query.function.ts
  class SortFunctionPostgres (line 5) | class SortFunctionPostgres extends AbstractSortFunction {
    method asc (line 6) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 18) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 30) | getAscSQL() {
    method getDescSQL (line 43) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/postgres/sort-query.postgres.ts
  class SortQueryPostgres (line 12) | class SortQueryPostgres extends AbstractSortQuery {
    method booleanSort (line 13) | booleanSort(field: FieldCore, context?: IRecordQuerySortContext): Sort...
    method numberSort (line 17) | numberSort(field: FieldCore, context?: IRecordQuerySortContext): SortF...
    method dateTimeSort (line 25) | dateTimeSort(field: FieldCore, context?: IRecordQuerySortContext): Sor...
    method stringSort (line 33) | stringSort(field: FieldCore, context?: IRecordQuerySortContext): SortF...
    method jsonSort (line 41) | jsonSort(field: FieldCore, context?: IRecordQuerySortContext): SortFun...

FILE: apps/nestjs-backend/src/db-provider/sort-query/sort-query.abstract.ts
  method constructor (line 13) | constructor(
  method appendSortBuilder (line 22) | appendSortBuilder(): Knex.QueryBuilder {
  method getRawSortSQLText (line 26) | getRawSortSQLText(): string {
  method genSortSQL (line 30) | private genSortSQL(sortObjs?: ISortItem[]) {
  method parseSorts (line 53) | private parseSorts(queryBuilder: Knex.QueryBuilder, sortObjs?: ISortItem...
  method getSortAdapter (line 70) | private getSortAdapter(field: FieldCore): AbstractSortFunction {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sort-query.interface.ts
  type ISortQueryInterface (line 3) | interface ISortQueryInterface {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/multiple-value/multiple-datetime-sort.adapter.ts
  class MultipleDateTimeSortAdapter (line 7) | class MultipleDateTimeSortAdapter extends SortFunctionSqlite {
    method asc (line 8) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 40) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 72) | getAscSQL() {
    method getDescSQL (line 107) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/multiple-value/multiple-json-sort.adapter.ts
  class MultipleJsonSortAdapter (line 4) | class MultipleJsonSortAdapter extends SortFunctionSqlite {
    method asc (line 5) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 18) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 31) | getAscSQL() {
    method getDescSQL (line 45) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/multiple-value/multiple-number-sort.adapter.ts
  class MultipleNumberSortAdapter (line 5) | class MultipleNumberSortAdapter extends SortFunctionSqlite {
    method asc (line 6) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 25) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 44) | getAscSQL() {
    method getDescSQL (line 63) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/single-value/date-sort.adapter.ts
  class DateSortAdapter (line 7) | class DateSortAdapter extends SortFunctionSqlite {
    method asc (line 8) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 29) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 50) | getAscSQL() {
    method getDescSQL (line 71) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/single-value/json-sort.adapter.ts
  class JsonSortAdapter (line 5) | class JsonSortAdapter extends SortFunctionSqlite {
    method asc (line 6) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 20) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 34) | getAscSQL() {
    method getDescSQL (line 47) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/single-value/string-sort.adapter.ts
  class StringSortAdapter (line 6) | class StringSortAdapter extends SortFunctionSqlite {
    method asc (line 7) | asc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method desc (line 26) | desc(builderClient: Knex.QueryBuilder): Knex.QueryBuilder {
    method getAscSQL (line 45) | getAscSQL() {
    method getDescSQL (line 63) | getDescSQL() {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/sort-query.function.ts
  class SortFunctionSqlite (line 3) | class SortFunctionSqlite extends AbstractSortFunction {
    method generateOrderByCase (line 4) | generateOrderByCase(keys: string[], columnName: string): string {

FILE: apps/nestjs-backend/src/db-provider/sort-query/sqlite/sort-query.sqlite.ts
  class SortQuerySqlite (line 12) | class SortQuerySqlite extends AbstractSortQuery {
    method booleanSort (line 13) | booleanSort(field: FieldCore, context?: IRecordQuerySortContext): Sort...
    method numberSort (line 17) | numberSort(field: FieldCore, context?: IRecordQuerySortContext): SortF...
    method dateTimeSort (line 25) | dateTimeSort(field: FieldCore, context?: IRecordQuerySortContext): Sor...
    method stringSort (line 33) | stringSort(field: FieldCore, context?: IRecordQuerySortContext): SortF...
    method jsonSort (line 40) | jsonSort(field: FieldCore, context?: IRecordQuerySortContext): SortFun...

FILE: apps/nestjs-backend/src/db-provider/sqlite.provider.ts
  class SqliteProvider (line 67) | class SqliteProvider implements IDbProvider {
    method constructor (line 70) | constructor(private readonly knex: Knex) {}
    method createSchema (line 74) | createSchema(_schemaName: string) {
    method dropSchema (line 78) | dropSchema(_schemaName: string) {
    method generateDbTableName (line 82) | generateDbTableName(baseId: string, name: string) {
    method getForeignKeysInfo (line 87) | getForeignKeysInfo(_tableName: string): string {
    method renameTableName (line 95) | renameTableName(oldTableName: string, newTableName: string) {
    method dropTable (line 99) | dropTable(tableName: string): string {
    method checkColumnExist (line 103) | async checkColumnExist(
    method checkTableExist (line 113) | checkTableExist(tableName: string): string {
    method renameColumn (line 125) | renameColumn(tableName: string, oldName: string, newName: string): str...
    method modifyColumnSchema (line 133) | modifyColumnSchema(
    method createColumnSchema (line 177) | createColumnSchema(
    method splitTableName (line 217) | splitTableName(tableName: string): string[] {
    method joinDbTableName (line 221) | joinDbTableName(schemaName: string, dbTableName: string) {
    method dropColumn (line 225) | dropColumn(
    method dropColumnAndIndex (line 243) | dropColumnAndIndex(tableName: string, columnName: string, indexName: s...
    method columnInfo (line 250) | columnInfo(tableName: string): string {
    method updateJsonColumn (line 254) | updateJsonColumn(
    method updateJsonArrayColumn (line 274) | updateJsonArrayColumn(
    method duplicateTable (line 306) | duplicateTable(
    method alterAutoNumber (line 322) | alterAutoNumber(_tableName: string): string[] {
    method batchInsertSql (line 326) | batchInsertSql(tableName: string, insertData: ReadonlyArray<unknown>):...
    method executeUpdateRecordsSqlList (line 342) | executeUpdateRecordsSqlList(params: {
    method updateFromSelectSql (line 371) | updateFromSelectSql(params: {
    method aggregationQuery (line 417) | aggregationQuery(
    method filterQuery (line 434) | filterQuery(
    method sortQuery (line 444) | sortQuery(
    method groupQuery (line 454) | groupQuery(
    method searchQuery (line 471) | searchQuery(
    method searchCountQuery (line 488) | searchCountQuery(
    method searchIndexQuery (line 505) | searchIndexQuery(
    method searchIndex (line 529) | searchIndex() {
    method duplicateTableQuery (line 533) | duplicateTableQuery(queryBuilder: Knex.QueryBuilder) {
    method duplicateAttachmentTableQuery (line 537) | duplicateAttachmentTableQuery(queryBuilder: Knex.QueryBuilder) {
    method shareFilterCollaboratorsQuery (line 541) | shareFilterCollaboratorsQuery(
    method baseQuery (line 555) | baseQuery(): BaseQueryAbstract {
    method integrityQuery (line 559) | integrityQuery(): IntegrityQueryAbstract {
    method calendarDailyCollectionQuery (line 563) | calendarDailyCollectionQuery(
    method lookupOptionsQuery (line 626) | lookupOptionsQuery(optionsKey: keyof ILookupLinkOptionsVo, value: stri...
    method optionsQuery (line 640) | optionsQuery(type: FieldType, optionsKey: string, value: string): stri...
    method searchBuilder (line 669) | searchBuilder(qb: Knex.QueryBuilder, search: [string, string][]): Knex...
    method getTableIndexes (line 677) | getTableIndexes(dbTableName: string): string {
    method generatedColumnQuery (line 696) | generatedColumnQuery(): IGeneratedColumnQueryInterface {
    method convertFormulaToGeneratedColumn (line 699) | convertFormulaToGeneratedColumn(
    method selectQuery (line 723) | selectQuery(): ISelectQueryInterface {
    method convertFormulaToSelectQuery (line 727) | convertFormulaToSelectQuery(
    method generateDatabaseViewName (line 749) | generateDatabaseViewName(tableId: string): string {
    method createDatabaseView (line 753) | createDatabaseView(table: TableDomain, qb: Knex.QueryBuilder): string[] {
    method recreateDatabaseView (line 758) | recreateDatabaseView(table: TableDomain, qb: Knex.QueryBuilder): strin...
    method dropDatabaseView (line 766) | dropDatabaseView(tableId: string): string[] {
    method refreshDatabaseView (line 772) | refreshDatabaseView(_tableId: string): string | undefined {
    method createMaterializedView (line 776) | createMaterializedView(table: TableDomain, qb: Knex.QueryBuilder): str...
    method dropMaterializedView (line 781) | dropMaterializedView(tableId: string): string {

FILE: apps/nestjs-backend/src/db-provider/utils/default-datetime-parse-pattern.ts
  constant DEFAULT_DATETIME_PARSE_PATTERN (line 6) | const DEFAULT_DATETIME_PARSE_PATTERN = (() => {

FILE: apps/nestjs-backend/src/db-provider/utils/formula-param-metadata.util.ts
  type IResolvedFormulaParamInfo (line 5) | interface IResolvedFormulaParamInfo {
  constant EMPTY_INFO (line 16) | const EMPTY_INFO: IResolvedFormulaParamInfo = {
  function resolveFormulaParamInfo (line 27) | function resolveFormulaParamInfo(
  function isTrustedNumeric (line 68) | function isTrustedNumeric(info: IResolvedFormulaParamInfo): boolean {
  function isTextLikeParam (line 72) | function isTextLikeParam(info: IResolvedFormulaParamInfo): boolean {
  function isDatetimeLikeParam (line 88) | function isDatetimeLikeParam(info: IResolvedFormulaParamInfo): boolean {
  function isBooleanLikeParam (line 92) | function isBooleanLikeParam(info: IResolvedFormulaParamInfo): boolean {
  function isJsonLikeParam (line 104) | function isJsonLikeParam(info: IResolvedFormulaParamInfo): boolean {
  function inferTypeFromField (line 108) | function inferTypeFromField(field?: IFormulaParamMetadata['field']): For...
  function mapDbFieldType (line 136) | function mapDbFieldType(dbFieldType?: DbFieldType): FormulaParamType | u...

FILE: apps/nestjs-backend/src/event-emitter/decorators/emit-controller-event.decorator.ts
  constant EMIT_EVENT_NAME (line 7) | const EMIT_EVENT_NAME = 'EMIT_EVENT_NAME';
  function EmitControllerEvent (line 9) | function EmitControllerEvent(name: Events): MethodDecorator {

FILE: apps/nestjs-backend/src/event-emitter/event-emitter.module.ts
  type EventEmitterModuleOptions (line 18) | interface EventEmitterModuleOptions {
  class EventEmitterModule (line 26) | class EventEmitterModule extends EventEmitterModuleClass {
    method register (line 27) | static register(options?: typeof OPTIONS_TYPE): DynamicModule {

FILE: apps/nestjs-backend/src/event-emitter/event-emitter.service.ts
  type DocType (line 37) | type DocType = IdPrefix.Table | IdPrefix.Field | IdPrefix.View | IdPrefi...
  class EventEmitterService (line 40) | class EventEmitterService {
    method constructor (line 71) | constructor(
    method emit (line 76) | emit<T extends unknown | unknown[]>(event: string, data: T): boolean {
    method emitAsync (line 80) | emitAsync<T extends unknown | unknown[]>(event: string, data: T): Prom...
    method ops2Event (line 85) | async ops2Event(rawOpMaps?: IRawOpMap[]): Promise<void> {
    method aggregateEventsByGroup (line 103) | private aggregateEventsByGroup(project: GroupedObservable<string, OpEv...
    method combineEvents (line 114) | private combineEvents(groupedEvents: OpEvent[]): OpEvent {
    method getMergePropertyName (line 129) | private getMergePropertyName(event: OpEvent): string {
    method initAcc (line 149) | private initAcc(event: OpEvent, mergePropertyName: string): OpEvent {
    method aggregateEventChanges (line 156) | private aggregateEventChanges(combinedEvent: OpEvent, mergePropertyNam...
    method handleEventResult (line 162) | private handleEventResult(result: OpEvent): void {
    method collectEventsFromRawOpMap (line 167) | private collectEventsFromRawOpMap(rawOpMaps?: IRawOpMap[]) {
    method generateEventsFromRawOps (line 178) | private generateEventsFromRawOps(rawOpMap: IRawOpMap, eventManager: Ma...
    method createExtendPlainContext (line 211) | private createExtendPlainContext(docId: string, id: string) {
    method getOpType (line 227) | private getOpType(rawOp: CreateOp | DeleteOp | EditOp): RawOpType | nu...
    method mergeEventsForUpdate (line 234) | private mergeEventsForUpdate(
    method getUpdateFieldsFromEvent (line 259) | private getUpdateFieldsFromEvent(
    method combineUpdateEvents (line 279) | private combineUpdateEvents(
    method createEvent (line 299) | private createEvent(docType: DocType, action: RawOpType, plain: any) {
    method getOpBuilder (line 318) | private getOpBuilder(docType: DocType) {
    method convertOpsToClassPlain (line 327) | private convertOpsToClassPlain(
    method initData (line 352) | private initData(
    method applyOperation (line 372) | private applyOperation(
    method buildAndApplyOp (line 392) | private buildAndApplyOp(

FILE: apps/nestjs-backend/src/event-emitter/event-job/event-job.module.ts
  class EventJobModule (line 21) | class EventJobModule {
    method registerQueue (line 22) | static async registerQueue(name: string): Promise<DynamicModule> {

FILE: apps/nestjs-backend/src/event-emitter/event-job/fallback/fallback-queue.module.ts
  class FallbackQueueModule (line 8) | class FallbackQueueModule {
    method registerQueue (line 9) | static registerQueue(name: string): DynamicModule {

FILE: apps/nestjs-backend/src/event-emitter/event-job/fallback/fallback-queue.service.ts
  constant PROCESSOR_METADATA (line 8) | const PROCESSOR_METADATA = 'bullmq:processor_metadata';
  class FallbackQueueService (line 11) | class FallbackQueueService implements OnModuleInit {
    method constructor (line 13) | constructor(
    method onModuleInit (line 18) | async onModuleInit() {
    method collectionProcess (line 23) | collectionProcess() {
    method handleListener (line 55) | private async handleListener(

FILE: apps/nestjs-backend/src/event-emitter/events/app/app.event.ts
  type IAppVo (line 6) | interface IAppVo {
  type IAppCreatePayload (line 11) | type IAppCreatePayload = { baseId: string; app: IAppVo };
  type IAppDeletePayload (line 12) | type IAppDeletePayload = { baseId: string; appId: string; permanent?: bo...
  type IAppUpdatePayload (line 13) | type IAppUpdatePayload = { baseId: string; app: IAppVo };
  class AppCreateEvent (line 15) | class AppCreateEvent extends CoreEvent<IAppCreatePayload> {
    method constructor (line 18) | constructor(payload: IAppCreatePayload, context: IEventContext) {
  class AppDeleteEvent (line 23) | class AppDeleteEvent extends CoreEvent<IAppDeletePayload> {
    method constructor (line 25) | constructor(payload: IAppDeletePayload, context: IEventContext) {
  class AppUpdateEvent (line 30) | class AppUpdateEvent extends CoreEvent<IAppUpdatePayload> {
    method constructor (line 33) | constructor(payload: IAppUpdatePayload, context: IEventContext) {
  class AppEventFactory (line 38) | class AppEventFactory {
    method create (line 39) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/base/base-node.event.ts
  type IBaseNodeCreatePayload (line 10) | type IBaseNodeCreatePayload = { baseId: string; node: IBaseNodeVo };
  type IBaseNodeDeletePayload (line 11) | type IBaseNodeDeletePayload = { baseId: string; node: IDeleteBaseNodeVo };
  type IBaseNodeUpdatePayload (line 12) | type IBaseNodeUpdatePayload = IBaseNodeCreatePayload;
  class BaseNodeEventFactory (line 15) | class BaseNodeEventFactory {
    method create (line 16) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/base/base.event.ts
  type IBaseCreatePayload (line 7) | type IBaseCreatePayload = { base: ICreateBaseVo };
  type IBaseDeletePayload (line 8) | type IBaseDeletePayload = { baseId: string; permanent?: boolean };
  type IBaseUpdatePayload (line 9) | type IBaseUpdatePayload = IBaseCreatePayload;
  type IBasePermissionUpdatePayload (line 10) | type IBasePermissionUpdatePayload = { baseId: string };
  class BaseCreateEvent (line 12) | class BaseCreateEvent extends CoreEvent<IBaseCreatePayload> {
    method constructor (line 15) | constructor(base: ICreateBaseVo, context: IEventContext) {
  class BaseDeleteEvent (line 20) | class BaseDeleteEvent extends CoreEvent<IBaseDeletePayload> {
    method constructor (line 22) | constructor(payload: IBaseDeletePayload, context: IEventContext) {
  class BaseUpdateEvent (line 27) | class BaseUpdateEvent extends CoreEvent<IBaseUpdatePayload> {
    method constructor (line 30) | constructor(base: ICreateBaseVo, context: IEventContext) {
  class BasePermissionUpdateEvent (line 35) | class BasePermissionUpdateEvent extends CoreEvent<IBasePermissionUpdateP...
    method constructor (line 38) | constructor(baseId: string, context: IEventContext) {
  class BaseEventFactory (line 43) | class BaseEventFactory {
    method create (line 44) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/base/folder/base.folder.event.ts
  type IBaseFolder (line 6) | type IBaseFolder = {
  type IBaseFolderCreatePayload (line 11) | type IBaseFolderCreatePayload = { baseId: string; folder: IBaseFolder };
  type IBaseFolderDeletePayload (line 12) | type IBaseFolderDeletePayload = { baseId: string; folderId: string };
  type IBaseFolderUpdatePayload (line 13) | type IBaseFolderUpdatePayload = IBaseFolderCreatePayload;
  class BaseFolderCreateEvent (line 15) | class BaseFolderCreateEvent extends CoreEvent<IBaseFolderCreatePayload> {
    method constructor (line 18) | constructor(payload: IBaseFolderCreatePayload, context: IEventContext) {
  class BaseFolderDeleteEvent (line 23) | class BaseFolderDeleteEvent extends CoreEvent<IBaseFolderDeletePayload> {
    method constructor (line 25) | constructor(payload: IBaseFolderDeletePayload, context: IEventContext) {
  class BaseFolderUpdateEvent (line 30) | class BaseFolderUpdateEvent extends CoreEvent<IBaseFolderUpdatePayload> {
    method constructor (line 33) | constructor(payload: IBaseFolderUpdatePayload, context: IEventContext) {
  class BaseFolderEventFactory (line 38) | class BaseFolderEventFactory {
    method create (line 39) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/core-event.ts
  type IEventContext (line 7) | interface IEventContext {
  type IEventRawContext (line 24) | interface IEventRawContext {
  method constructor (line 36) | constructor(

FILE: apps/nestjs-backend/src/event-emitter/events/dashboard/dashboard.event.ts
  type IDashboardCreatePayload (line 7) | type IDashboardCreatePayload = { baseId: string; dashboard: ICreateDashb...
  type IDashboardUpdatePayload (line 8) | type IDashboardUpdatePayload = { baseId: string; dashboard: ICreateDashb...
  type IDashboardDeletePayload (line 9) | type IDashboardDeletePayload = { baseId: string; dashboardId: string; pe...
  class DashboardCreateEvent (line 11) | class DashboardCreateEvent extends CoreEvent<IDashboardCreatePayload> {
    method constructor (line 14) | constructor(payload: IDashboardCreatePayload, context: IEventContext) {
  class DashboardDeleteEvent (line 19) | class DashboardDeleteEvent extends CoreEvent<IDashboardDeletePayload> {
    method constructor (line 21) | constructor(payload: IDashboardDeletePayload, context: IEventContext) {
  class DashboardUpdateEvent (line 26) | class DashboardUpdateEvent extends CoreEvent<IDashboardUpdatePayload> {
    method constructor (line 29) | constructor(payload: IDashboardUpdatePayload, context: IEventContext) {
  class DashboardEventFactory (line 34) | class DashboardEventFactory {
    method create (line 35) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/event.enum.ts
  type Events (line 2) | enum Events {

FILE: apps/nestjs-backend/src/event-emitter/events/last-visit/last-visit.event.ts
  class LastVisitUpdateEvent (line 4) | class LastVisitUpdateEvent {
    method constructor (line 7) | constructor(public readonly payload: IUpdateUserLastVisitRo) {}

FILE: apps/nestjs-backend/src/event-emitter/events/op-event.ts
  type IChangeValue (line 4) | interface IChangeValue {

FILE: apps/nestjs-backend/src/event-emitter/events/space/collaborator.event.ts
  class CollaboratorCreateEvent (line 3) | class CollaboratorCreateEvent {
    method constructor (line 6) | constructor(public readonly spaceId: string) {}
  class CollaboratorDeleteEvent (line 9) | class CollaboratorDeleteEvent {
    method constructor (line 12) | constructor(public readonly spaceId: string) {}
  class CollaboratorUpdateEvent (line 15) | class CollaboratorUpdateEvent {
    method constructor (line 18) | constructor(public readonly spaceId: string) {}

FILE: apps/nestjs-backend/src/event-emitter/events/space/space.event.ts
  type ISpaceCreatePayload (line 7) | type ISpaceCreatePayload = { space: ICreateSpaceVo };
  type ISpaceDeletePayload (line 8) | type ISpaceDeletePayload = { spaceId: string; permanent?: boolean };
  type ISpaceUpdatePayload (line 9) | type ISpaceUpdatePayload = ISpaceCreatePayload;
  class SpaceCreateEvent (line 11) | class SpaceCreateEvent extends CoreEvent<ISpaceCreatePayload> {
    method constructor (line 14) | constructor(space: ICreateSpaceVo, context: IEventContext) {
  class SpaceDeleteEvent (line 19) | class SpaceDeleteEvent extends CoreEvent<ISpaceDeletePayload> {
    method constructor (line 22) | constructor(payload: ISpaceDeletePayload, context: IEventContext) {
  class SpaceUpdateEvent (line 27) | class SpaceUpdateEvent extends CoreEvent<ISpaceUpdatePayload> {
    method constructor (line 30) | constructor(space: ICreateSpaceVo, context: IEventContext) {
  class SpaceEventFactory (line 35) | class SpaceEventFactory {
    method create (line 36) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/table/button.event.ts
  type IButtonClickEventPayload (line 6) | type IButtonClickEventPayload = {
  class ButtonClickEvent (line 12) | class ButtonClickEvent extends CoreEvent<IButtonClickEventPayload> {
    method constructor (line 15) | constructor(payload: IButtonClickEventPayload, context: IEventContext) {
  class ButtonEventFactory (line 20) | class ButtonEventFactory {
    method create (line 21) | static create(name: string, payload: IButtonClickEventPayload, context...

FILE: apps/nestjs-backend/src/event-emitter/events/table/field.event.ts
  type IChangeField (line 9) | type IChangeField = Record<IFieldPropertyKey, IChangeValue> & { id: stri...
  type IFieldCreatePayload (line 11) | type IFieldCreatePayload = { tableId: string; field: IFieldVo | IFieldVo...
  type IFieldDeletePayload (line 12) | type IFieldDeletePayload = { tableId: string; fieldId: string | string[] };
  type IFieldUpdatePayload (line 13) | type IFieldUpdatePayload = {
  class FieldCreateEvent (line 18) | class FieldCreateEvent extends OpEvent<IFieldCreatePayload> {
    method constructor (line 22) | constructor(tableId: string, field: IFieldVo | IFieldVo[], context: IE...
  class FieldDeleteEvent (line 27) | class FieldDeleteEvent extends OpEvent<IFieldDeletePayload> {
    method constructor (line 32) | constructor(tableId: string, fieldId: string | string[], context: IEve...
  class FieldUpdateEvent (line 37) | class FieldUpdateEvent extends OpEvent<IFieldUpdatePayload> {
    method constructor (line 42) | constructor(tableId: string, field: IChangeField | IChangeField[], con...
  class FieldEventFactory (line 47) | class FieldEventFactory {
    method create (line 48) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/table/record.event.ts
  type IChangeRecord (line 9) | type IChangeRecord = Record<keyof Pick<IRecord, 'fields'>, Record<string...
  type IRecordCreatePayload (line 13) | type IRecordCreatePayload = { tableId: string; record: IRecord | IRecord...
  type IRecordDeletePayload (line 14) | type IRecordDeletePayload = { tableId: string; recordId: string | string...
  type IRecordUpdatePayload (line 15) | type IRecordUpdatePayload = {
  function getFieldIdsFromRecord (line 21) | function getFieldIdsFromRecord(record: IRecord | IRecord[]) {
  class RecordCreateEvent (line 32) | class RecordCreateEvent extends OpEvent<IRecordCreatePayload> {
    method constructor (line 36) | constructor(tableId: string, record: IRecord | IRecord[], context: IEv...
  class RecordDeleteEvent (line 41) | class RecordDeleteEvent extends OpEvent<IRecordDeletePayload> {
    method constructor (line 45) | constructor(tableId: string, recordId: string | string[], context: IEv...
  class RecordUpdateEvent (line 50) | class RecordUpdateEvent extends OpEvent<IRecordUpdatePayload> {
    method constructor (line 54) | constructor(
  class RecordEventFactory (line 64) | class RecordEventFactory {
    method create (line 65) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/table/table.event.ts
  type IChangeTable (line 9) | type IChangeTable = Record<keyof Omit<ITableOp, 'id' | 'lastModifiedTime...
  type ITableCreatePayload (line 13) | type ITableCreatePayload = { baseId: string; table: ITableOp };
  type ITableDeletePayload (line 14) | type ITableDeletePayload = { baseId: string; tableId: string; permanent?...
  type ITableUpdatePayload (line 15) | type ITableUpdatePayload = {
  class TableCreateEvent (line 20) | class TableCreateEvent extends OpEvent<ITableCreatePayload> {
    method constructor (line 24) | constructor(payload: ITableCreatePayload, context: IEventContext) {
  class TableDeleteEvent (line 29) | class TableDeleteEvent extends OpEvent<ITableDeletePayload> {
    method constructor (line 33) | constructor(payload: ITableDeletePayload, context: IEventContext) {
  class TableUpdateEvent (line 38) | class TableUpdateEvent extends OpEvent<ITableUpdatePayload> {
    method constructor (line 42) | constructor(payload: ITableUpdatePayload, context: IEventContext) {
  class TableEventFactory (line 47) | class TableEventFactory {
    method create (line 48) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/table/view.event.ts
  type IChangeView (line 9) | type IChangeView = Record<
  type IViewCreatePayload (line 26) | type IViewCreatePayload = { tableId: string; view: IViewVo | IViewVo[] };
  type IViewDeletePayload (line 27) | type IViewDeletePayload = { tableId: string; viewId: string };
  type IViewUpdatePayload (line 28) | type IViewUpdatePayload = {
  class ViewCreateEvent (line 33) | class ViewCreateEvent extends OpEvent<IViewCreatePayload> {
    method constructor (line 37) | constructor(tableId: string, view: IViewVo | IViewVo[], context: IEven...
  class ViewDeleteEvent (line 42) | class ViewDeleteEvent extends OpEvent<IViewDeletePayload> {
    method constructor (line 46) | constructor(tableId: string, viewId: string, context: IEventContext) {
  class ViewUpdateEvent (line 51) | class ViewUpdateEvent extends OpEvent<IViewUpdatePayload> {
    method constructor (line 55) | constructor(tableId: string, view: IChangeView, context: IEventContext) {
  class ViewEventFactory (line 60) | class ViewEventFactory {
    method create (line 61) | static create(

FILE: apps/nestjs-backend/src/event-emitter/events/user/user.event.ts
  class UserSignUpEvent (line 3) | class UserSignUpEvent {
    method constructor (line 6) | constructor(public readonly userId: string) {}
  class UserEmailChangeEvent (line 9) | class UserEmailChangeEvent {
    method constructor (line 12) | constructor(

FILE: apps/nestjs-backend/src/event-emitter/events/workflow/workflow.event.ts
  type IWorkflowVo (line 6) | interface IWorkflowVo {
  type IWorkflowCreatePayload (line 11) | type IWorkflowCreatePayload = { baseId: string; workflow: IWorkflowVo };
  type IWorkflowDeletePayload (line 12) | type IWorkflowDeletePayload = { baseId: string; workflowId: string; perm...
  type IWorkflowUpdatePayload (line 13) | type IWorkflowUpdatePayload = IWorkflowCreatePayload;
  class WorkflowCreateEvent (line 15) | class WorkflowCreateEvent extends CoreEvent<IWorkflowCreatePayload> {
    method constructor (line 18) | constructor(payload: IWorkflowCreatePayload, context: IEventContext) {
  class WorkflowDeleteEvent (line 23) | class WorkflowDeleteEvent extends CoreEvent<IWorkflowDeletePayload> {
    method constructor (line 25) | constructor(payload: IWorkflowDeletePayload, context: IEventContext) {
  class WorkflowUpdateEvent (line 30) | class WorkflowUpdateEvent extends CoreEvent<IWorkflowUpdatePayload> {
    method constructor (line 33) | constructor(payload: IWorkflowUpdatePayload, context: IEventContext) {
  class WorkflowEventFactory (line 38) | class WorkflowEventFactory {
    method create (line 39) | static create(

FILE: apps/nestjs-backend/src/event-emitter/interceptor/event.Interceptor.ts
  class EventMiddleware (line 23) | class EventMiddleware implements NestInterceptor {
    method constructor (line 24) | constructor(
    method intercept (line 29) | intercept(context: ExecutionContext, next: CallHandler): Observable<an...
    method interceptContext (line 45) | private interceptContext(req: Request, resolveData: any) {
    method createEvent (line 56) | private createEvent(

FILE: apps/nestjs-backend/src/event-emitter/listeners/action-trigger.listener.ts
  type IViewEvent (line 22) | type IViewEvent = ViewUpdateEvent;
  type IRecordEvent (line 23) | type IRecordEvent = RecordCreateEvent | RecordDeleteEvent | RecordUpdate...
  type IListenerEvent (line 24) | type IListenerEvent =
  type IActionTriggerData (line 31) | interface IActionTriggerData {
  class ActionTriggerListener (line 37) | class ActionTriggerListener {
    method constructor (line 40) | constructor(
    method listener (line 50) | private async listener(listenerEvent: IListenerEvent): Promise<void> {
    method handleTableViewUpdate (line 84) | private async handleTableViewUpdate(event: ViewUpdateEvent): Promise<v...
    method handleTableFieldUpdate (line 121) | private async handleTableFieldUpdate(event: FieldUpdateEvent): Promise...
    method handleTableFieldCreate (line 130) | private async handleTableFieldCreate(event: FieldCreateEvent): Promise...
    method handleTableFieldDelete (line 135) | private async handleTableFieldDelete(event: FieldDeleteEvent): Promise...
    method handleTableRecordEvent (line 140) | private async handleTableRecordEvent(event: IRecordEvent): Promise<voi...
    method isTableViewUpdateEvent (line 158) | private isTableViewUpdateEvent(event: IListenerEvent): boolean {
    method isTableFieldUpdateEvent (line 162) | private isTableFieldUpdateEvent(event: IListenerEvent): boolean {
    method isTableFieldCreateEvent (line 166) | private isTableFieldCreateEvent(event: IListenerEvent): boolean {
    method isTableFieldDeleteEvent (line 170) | private isTableFieldDeleteEvent(event: IListenerEvent): boolean {
    method isValidViewUpdateOperation (line 174) | private isValidViewUpdateOperation(event: ViewUpdateEvent): boolean | ...
    method isValidFieldUpdateOperation (line 180) | private isValidFieldUpdateOperation(event: FieldUpdateEvent): boolean ...
    method isTableRecordEvent (line 186) | private isTableRecordEvent(event: IListenerEvent): boolean {
    method emitActionTrigger (line 195) | private emitActionTrigger(tableIdOrViewId: string, data: IActionTrigge...

FILE: apps/nestjs-backend/src/event-emitter/listeners/attachment.listener.ts
  class AttachmentListener (line 13) | class AttachmentListener {
    method constructor (line 14) | constructor(private readonly attachmentsTableService: AttachmentsTable...
    method recordCreateListener (line 17) | async recordCreateListener(listenerEvent: RecordCreateEvent) {
    method recordDeleteListener (line 30) | async recordDeleteListener(listenerEvent: RecordDeleteEvent) {
    method recordUpdateListener (line 41) | async recordUpdateListener(listenerEvent: RecordUpdateEvent) {
    method fieldDeleteListener (line 54) | async fieldDeleteListener(listenerEvent: FieldDeleteEvent) {

FILE: apps/nestjs-backend/src/event-emitter/listeners/base-permission-update.listener.ts
  class BasePermissionUpdateListener (line 11) | class BasePermissionUpdateListener {
    method constructor (line 14) | constructor(
    method basePermissionUpdateListener (line 21) | async basePermissionUpdateListener(listenerEvent: BasePermissionUpdate...

FILE: apps/nestjs-backend/src/event-emitter/listeners/collaborator-notification.listener.ts
  type IListenerEvent (line 14) | type IListenerEvent = RecordCreateEvent | RecordUpdateEvent;
  type IUserField (line 16) | type IUserField = {
  class CollaboratorNotificationListener (line 28) | class CollaboratorNotificationListener {
    method constructor (line 31) | constructor(
    method listener (line 40) | private async listener(listenerEvent: IListenerEvent): Promise<void> {
    method hasRelevantFields (line 58) | private hasRelevantFields(
    method getRecordFields (line 66) | private getRecordFields(record: IRecord | IChangeRecord | (IRecord | I...
    method updateTableRecord (line 71) | private async updateTableRecord(
    method extractNotificationData (line 116) | private extractNotificationData(
    method fetchUserFields (line 150) | private async fetchUserFields(tableId: string) {

FILE: apps/nestjs-backend/src/event-emitter/listeners/pin.listener.ts
  class PinListener (line 8) | class PinListener {
    method constructor (line 11) | constructor(private readonly prismaService: PrismaService) {}
    method spaceAndBaseDelete (line 15) | async spaceAndBaseDelete(listenerEvent: SpaceDeleteEvent | BaseDeleteE...

FILE: apps/nestjs-backend/src/event-emitter/listeners/record-history.listener.ts
  constant SELECT_FIELD_TYPE_SET (line 18) | const SELECT_FIELD_TYPE_SET = new Set([FieldType.SingleSelect, FieldType...
  class RecordHistoryListener (line 21) | class RecordHistoryListener {
    method constructor (line 22) | constructor(
    method recordUpdateListener (line 31) | async recordUpdateListener(event: RecordUpdateEvent) {
    method minimizeFieldOptions (line 142) | private minimizeFieldOptions(

FILE: apps/nestjs-backend/src/event-emitter/listeners/trash.listener.ts
  class TrashListener (line 15) | class TrashListener {
    method constructor (line 16) | constructor(private readonly prismaService: PrismaService) {}
    method onEvent (line 23) | async onEvent(

FILE: apps/nestjs-backend/src/features/access-token/access-token.controller.ts
  class AccessTokenController (line 22) | class AccessTokenController {
    method constructor (line 23) | constructor(private readonly accessTokenService: AccessTokenService) {}
    method createAccessToken (line 26) | async createAccessToken(
    method updateAccessToken (line 33) | async updateAccessToken(
    method deleteAccessToken (line 41) | async deleteAccessToken(@Param('accessTokenId') accessTokenId: string) {
    method refreshAccessToken (line 47) | async refreshAccessToken(
    method getAccessTokens (line 55) | async getAccessTokens(): Promise<ListAccessTokenVo> {
    method getAccessToken (line 60) | async getAccessToken(@Param('accessTokenId') accessTokenId: string): P...

FILE: apps/nestjs-backend/src/features/access-token/access-token.encryptor.ts
  type ITokenEncryptor (line 4) | interface ITokenEncryptor {

FILE: apps/nestjs-backend/src/features/access-token/access-token.module.ts
  class AccessTokenModule (line 10) | class AccessTokenModule {}

FILE: apps/nestjs-backend/src/features/access-token/access-token.service.ts
  class AccessTokenService (line 18) | class AccessTokenService {
    method constructor (line 19) | constructor(
    method transformAccessTokenEntity (line 26) | private transformAccessTokenEntity<
    method validate (line 61) | async validate(splitAccessTokenObj: { accessTokenId: string; sign: str...
    method listAccessToken (line 88) | async listAccessToken() {
    method createAccessToken (line 109) | async createAccessToken(
    method deleteAccessToken (line 150) | async deleteAccessToken(id: string) {
    method refreshAccessToken (line 157) | async refreshAccessToken(id: string, refreshAccessTokenRo?: RefreshAcc...
    method updateAccessToken (line 186) | async updateAccessToken(id: string, updateAccessToken: UpdateAccessTok...
    method getAccessToken (line 213) | async getAccessToken(accessTokenId: string) {

FILE: apps/nestjs-backend/src/features/aggregation/aggregation.module.ts
  class AggregationModule (line 25) | class AggregationModule {}

FILE: apps/nestjs-backend/src/features/aggregation/aggregation.service.interface.ts
  type IAggregationService (line 23) | interface IAggregationService {
  type IWithView (line 146) | interface IWithView {
  type ICustomFieldStats (line 156) | interface ICustomFieldStats {

FILE: apps/nestjs-backend/src/features/aggregation/aggregation.service.symbol.ts
  constant AGGREGATION_SERVICE_SYMBOL (line 6) | const AGGREGATION_SERVICE_SYMBOL = Symbol('AGGREGATION_SERVICE');

FILE: apps/nestjs-backend/src/features/aggregation/aggregation.service.ts
  type IStatisticsData (line 56) | type IStatisticsData = {
  class AggregationService (line 67) | class AggregationService implements IAggregationService {
    method constructor (line 69) | constructor(
    method performAggregation (line 86) | async performAggregation(params: {
    method convertValueToNumberOrString (line 185) | private convertValueToNumberOrString(currentValue: unknown): number | ...
    method calculateDateRangeOfMonths (line 195) | private calculateDateRangeOfMonths(currentValue: string): number {
    method handleAggregation (line 199) | private async handleAggregation(params: {
    method performGroupedAggregation (line 292) | async performGroupedAggregation(params: {
    method resolveAggregationProjection (line 383) | private resolveAggregationProjection(params: {
    method performRowCount (line 441) | async performRowCount(tableId: string, queryRo: IQueryBaseRo): Promise...
    method getDbTableName (line 483) | private async getDbTableName(prisma: Prisma.TransactionClient, tableId...
    method handleRowCount (line 490) | private async handleRowCount(params: {
    method fetchStatisticsParams (line 581) | private async fetchStatisticsParams(params: {
    method findView (line 605) | private async findView(tableId: string, withView?: IWithView) {
    method filterFieldInstances (line 632) | private filterFieldInstances(
    method buildStatisticsData (line 645) | private buildStatisticsData(
    method getStatisticFields (line 677) | private getStatisticFields(
    method getFieldsData (line 724) | async getFieldsData(tableId: string, fieldIds?: string[], withName?: b...
    method getGroupPoints (line 748) | async getGroupPoints(
    method getSearchCount (line 770) | public async getSearchCount(tableId: string, queryRo: ISearchCountRo, ...
    method getRecordIndexBySearchOrder (line 823) | public async getRecordIndexBySearchOrder(
    method getRecordIndex (line 1012) | async getRecordIndex(tableId: string, queryRo: IRecordIndexRo): Promis...
    method getCalendarDailyCollection (line 1059) | public async getCalendarDailyCollection(

FILE: apps/nestjs-backend/src/features/aggregation/open-api/aggregation-open-api.controller.ts
  class AggregationOpenApiController (line 44) | class AggregationOpenApiController {
    method constructor (line 45) | constructor(
    method getAggregationWithCache (line 52) | private async getAggregationWithCache<T>(
    method getAggregation (line 103) | async getAggregation(
    method getRowCount (line 114) | async getRowCount(
    method getRecordIndex (line 125) | async getRecordIndex(
    method getSearchCount (line 136) | async getSearchCount(
    method getSearchIndex (line 147) | async getSearchIndex(
    method getGroupPoints (line 158) | async getGroupPoints(
    method getCalendarDailyCollection (line 169) | async getCalendarDailyCollection(
    method getTaskStatusCollection (line 181) | async getTaskStatusCollection(

FILE: apps/nestjs-backend/src/features/aggregation/open-api/aggregation-open-api.module.ts
  class AggregationOpenApiModule (line 12) | class AggregationOpenApiModule {}

FILE: apps/nestjs-backend/src/features/aggregation/open-api/aggregation-open-api.service.ts
  class AggregationOpenApiService (line 24) | class AggregationOpenApiService {
    method constructor (line 25) | constructor(
    method getAggregation (line 29) | async getAggregation(tableId: string, query?: IAggregationRo): Promise...
    method getRowCount (line 69) | async getRowCount(tableId: string, query: IQueryBaseRo = {}): Promise<...
    method getGroupPoints (line 76) | async getGroupPoints(
    method getCalendarDailyCollection (line 84) | async getCalendarDailyCollection(
    method getRecordIndex (line 91) | async getRecordIndex(tableId: string, query: IRecordIndexRo): Promise<...
    method validFieldStats (line 95) | private async validFieldStats(
    method getSearchCount (line 125) | public async getSearchCount(tableId: string, queryRo: ISearchCountRo, ...
    method getRecordIndexBySearchOrder (line 129) | public async getRecordIndexBySearchOrder(

FILE: apps/nestjs-backend/src/features/ai/ai.controller.ts
  class AiController (line 10) | class AiController {
    method constructor (line 11) | constructor(private readonly aiService: AiService) {}
    method generateStream (line 15) | async generateStream(
    method getAIConfig (line 25) | async getAIConfig(@Param('baseId') baseId: string) {
    method getAIDisableAIActions (line 31) | async getAIDisableAIActions(@Param('baseId') baseId: string) {

FILE: apps/nestjs-backend/src/features/ai/ai.module.ts
  class AiModule (line 12) | class AiModule {}

FILE: apps/nestjs-backend/src/features/ai/ai.service.ts
  constant AI_GATEWAY_PROVIDER_NAME (line 35) | const AI_GATEWAY_PROVIDER_NAME = 'teable';
  type ILanguageModelV2 (line 37) | type ILanguageModelV2 = Exclude<LanguageModel, string>;
  type IGatewayModelsCache (line 42) | interface IGatewayModelsCache {
  class AiService (line 48) | class AiService {
    method constructor (line 54) | constructor(
    method parseModelKey (line 61) | public parseModelKey(modelKey: string) {
    method isGatewayModel (line 70) | public isGatewayModel(modelKey: string): boolean {
    method buildGatewayModelKey (line 82) | public buildGatewayModelKey(modelId: string): string {
    method parseOwnerFromModelId (line 90) | private parseOwnerFromModelId(modelId: string): string | undefined {
    method getModelConfig (line 96) | async getModelConfig(modelKey: string, llmProviders: LLMProvider[] = [...
    method getModelInstance (line 161) | async getModelInstance(
    method getAIConfig (line 237) | async getAIConfig(baseId: string) {
    method getAIDisableAIActions (line 334) | async getAIDisableAIActions(baseId: string) {
    method getToolApiKeys (line 362) | async getToolApiKeys(baseId: string) {
    method getSimplifiedAIConfig (line 376) | async getSimplifiedAIConfig(baseId: string) {
    method getGenerationModelInstance (line 396) | private async getGenerationModelInstance(baseId: string, aiGenerateRo:...
    method generateStream (line 406) | async generateStream(
    method generateText (line 422) | async generateText(baseId: string, aiGenerateRo: IAiGenerateRo) {
    method getInstanceAIConfig (line 433) | async getInstanceAIConfig() {
    method findModelInProviders (line 443) | findModelInProviders(modelKey: string, llmProviders: LLMProvider[]): b...
    method findModelInGateway (line 460) | async findModelInGateway(modelKey: string): Promise<boolean> {
    method checkInstanceAIModel (line 483) | async checkInstanceAIModel(modelKey: string): Promise<boolean> {
    method getChatModelInstance (line 495) | async getChatModelInstance(baseId: string) {
    method getGatewayModelConfig (line 564) | async getGatewayModelConfig(modelId: string) {
    method getModelTags (line 599) | async getModelTags(modelKey: string, llmProviders: LLMProvider[]): Pro...
    method abilityToTags (line 646) | private abilityToTags(ability: IChatModelAbility): GatewayModelTag[] {
    method getGatewayModelPricing (line 660) | async getGatewayModelPricing(modelId: string) {
    method getGatewayApiModel (line 698) | private async getGatewayApiModel(modelId: string): Promise<IGatewayApi...
    method fetchGatewayModelsFromApi (line 708) | async fetchGatewayModelsFromApi(): Promise<IGatewayApiModel[]> {
    method getAttachmentTransferMode (line 748) | async getAttachmentTransferMode(): Promise<'url' | 'base64'> {
    method findFirstVisionModel (line 762) | async findFirstVisionModel(llmProviders: LLMProvider[]): Promise<

FILE: apps/nestjs-backend/src/features/ai/constant.ts
  constant TASK_MODEL_MAP (line 4) | const TASK_MODEL_MAP = {

FILE: apps/nestjs-backend/src/features/ai/util.ts
  method pull (line 53) | async pull(controller) {

FILE: apps/nestjs-backend/src/features/attachments/attachments-crop.module.ts
  class AttachmentsCropModule (line 14) | class AttachmentsCropModule {}

FILE: apps/nestjs-backend/src/features/attachments/attachments-crop.processor.ts
  type IRecordImageJob (line 11) | interface IRecordImageJob {
  constant ATTACHMENTS_CROP_QUEUE (line 19) | const ATTACHMENTS_CROP_QUEUE = 'attachments-crop-queue';
  class AttachmentsCropQueueProcessor (line 31) | class AttachmentsCropQueueProcessor extends WorkerHost {
    method constructor (line 34) | constructor(
    method process (line 43) | public async process(job: Job<IRecordImageJob>) {
    method handleCropImage (line 50) | private async handleCropImage(job: Job<IRecordImageJob>) {

FILE: apps/nestjs-backend/src/features/attachments/attachments-storage.module.ts
  class AttachmentsStorageModule (line 10) | class AttachmentsStorageModule {}

FILE: apps/nestjs-backend/src/features/attachments/attachments-storage.service.ts
  class AttachmentsStorageService (line 21) | class AttachmentsStorageService {
    method constructor (line 25) | constructor(
    method getPreviewUrl (line 35) | async getPreviewUrl<T extends string | string[] = string | string[]>(
    method getPreviewUrlByPath (line 78) | async getPreviewUrlByPath(
    method getTableThumbnailUrl (line 104) | async getTableThumbnailUrl(path: string, mimetype: string) {
    method cropTableImage (line 117) | async cropTableImage(bucket: string, path: string, height: number) {

FILE: apps/nestjs-backend/src/features/attachments/attachments-table.module.ts
  class AttachmentsTableModule (line 10) | class AttachmentsTableModule {}

FILE: apps/nestjs-backend/src/features/attachments/attachments-table.service.ts
  class AttachmentsTableService (line 9) | class AttachmentsTableService {
    method constructor (line 10) | constructor(private readonly prismaService: PrismaService) {}
    method createUniqueKey (line 12) | private createUniqueKey(
    method getAttachmentFields (line 21) | private async getAttachmentFields(tableId: string) {
    method createRecords (line 28) | async createRecords(userId: string, tableId: string, records: IRecord[...
    method updateRecords (line 58) | async updateRecords(userId: string, tableId: string, records: IChangeR...
    method delete (line 132) | async delete(
    method deleteRecords (line 149) | async deleteRecords(tableId: string, recordIds: string[]) {
    method deleteFields (line 155) | async deleteFields(tableId: string, fieldIds: string[]) {
    method deleteTable (line 161) | async deleteTable(tableId: string) {

FILE: apps/nestjs-backend/src/features/attachments/attachments.controller.ts
  class AttachmentsController (line 26) | class AttachmentsController {
    method constructor (line 27) | constructor(private readonly attachmentsService: AttachmentsService) {}
    method uploadFilePut (line 30) | async uploadFilePut(@Req() req: Request, @Param('token') token: string) {
    method uploadFilePost (line 36) | async uploadFilePost(@Req() req: Request, @Param('token') token: strin...
    method read (line 42) | async read(
    method signature (line 75) | async signature(
    method notify (line 83) | async notify(

FILE: apps/nestjs-backend/src/features/attachments/attachments.module.ts
  class AttachmentsModule (line 23) | class AttachmentsModule {}

FILE: apps/nestjs-backend/src/features/attachments/attachments.service.ts
  class AttachmentsService (line 38) | class AttachmentsService {
    method constructor (line 41) | constructor(
    method upload (line 54) | async upload(req: Request, token: string) {
    method readLocalFile (line 77) | async readLocalFile(path: string, token?: string) {
    method localFileConditionalCaching (line 111) | localFileConditionalCaching(path: string, reqHeaders: IncomingHttpHead...
    method signature (line 134) | async signature(signatureRo: SignatureRo & { internal?: boolean }): Pr...
    method notify (line 168) | async notify(token: string, filename?: string): Promise<INotifyVo> {
    method notifyToAttachmentItem (line 234) | private async notifyToAttachmentItem(token: string, filename: string):...
    method uploadFile (line 243) | async uploadFile(file: Express.Multer.File): Promise<IAttachmentItem> {
    method uploadFromLocalFile (line 284) | async uploadFromLocalFile(filePath: string, filename: string): Promise...
    method uploadFromUrl (line 333) | async uploadFromUrl(
    method getFileInfo (line 385) | private async getFileInfo(
    method uploadFileContent (line 432) | private async uploadFileContent(
    method uploadStreamToStorage (line 454) | private async uploadStreamToStorage(
    method getFilenameFromUrl (line 473) | private getFilenameFromUrl(url: string): string {
    method downloadFile (line 479) | private async downloadFile(

FILE: apps/nestjs-backend/src/features/attachments/constant.ts
  constant ATTACHMENT_SM_THUMBNAIL_HEIGHT (line 1) | const ATTACHMENT_SM_THUMBNAIL_HEIGHT = 56;
  constant ATTACHMENT_LG_THUMBNAIL_HEIGHT (line 2) | const ATTACHMENT_LG_THUMBNAIL_HEIGHT = 525;

FILE: apps/nestjs-backend/src/features/attachments/guard/auth.guard.ts
  class DynamicAuthGuardFactory (line 9) | class DynamicAuthGuardFactory implements CanActivate {
    method constructor (line 10) | constructor(
    method canActivate (line 15) | canActivate(context: ExecutionContext) {

FILE: apps/nestjs-backend/src/features/attachments/plugins/aliyun.ts
  class AliyunStorage (line 14) | class AliyunStorage extends S3Storage implements StorageAdapter {
    method constructor (line 17) | constructor(@StorageConfig() readonly config: IStorageConfig) {
    method replacePrivateBucketEndpoint (line 38) | private replacePrivateBucketEndpoint(url: string, bucket: string) {
    method getPreviewUrl (line 51) | async getPreviewUrl(

FILE: apps/nestjs-backend/src/features/attachments/plugins/local.ts
  type ITokenEncryptor (line 24) | interface ITokenEncryptor {
  class LocalStorage (line 30) | class LocalStorage implements StorageAdapter {
    method constructor (line 37) | constructor(
    method getUploadUrl (line 50) | private getUploadUrl(token: string, internal?: boolean) {
    method deleteFile (line 55) | private deleteFile(filePath: string) {
    method getUrl (line 67) | private getUrl(bucket: string, path: string, params: ITokenEncryptor) {
    method parsePath (line 73) | parsePath(path: string) {
    method presigned (line 81) | async presigned(_bucket: string, dir: string, params: IPresignParams) {
    method validateToken (line 109) | async validateToken(token: string, file: ILocalFileUpload) {
    method saveTemporaryFile (line 151) | async saveTemporaryFile(req: Request) {
    method save (line 190) | async save(filePath: string, rename: string, isDelete: boolean = true) {
    method read (line 200) | read(path: string) {
    method getLastModifiedTime (line 204) | getLastModifiedTime(path: string) {
    method getFileMate (line 212) | async getFileMate(path: string) {
    method getObjectMeta (line 224) | async getObjectMeta(bucket: string, path: string, token: string): Prom...
    method getPreviewUrl (line 254) | async getPreviewUrl(
    method verifyReadToken (line 269) | verifyReadToken(token: string) {
    method uploadFileWidthPath (line 291) | async uploadFileWidthPath(
    method uploadFile (line 305) | async uploadFile(
    method uploadFileStream (line 335) | async uploadFileStream(
    method cropImage (line 344) | async cropImage(
    method downloadFile (line 372) | async downloadFile(bucket: string, path: string): Promise<ReadableStre...
    method deleteDir (line 376) | async deleteDir(bucket: string, path: string, throwError: boolean = tr...

FILE: apps/nestjs-backend/src/features/attachments/plugins/minio.ts
  class MinioStorage (line 16) | class MinioStorage implements StorageAdapter {
    method constructor (line 20) | constructor(@StorageConfig() readonly config: IStorageConfig) {
    method presigned (line 44) | async presigned(
    method getShape (line 89) | private async getShape(bucket: string, objectName: string) {
    method getObjectMeta (line 108) | async getObjectMeta(bucket: string, path: string, _token: string) {
    method getPreviewUrl (line 135) | async getPreviewUrl(
    method uploadFileWidthPath (line 148) | async uploadFileWidthPath(
    method uploadFile (line 166) | async uploadFile(
    method uploadFileStream (line 185) | async uploadFileStream(
    method fileExists (line 195) | private async fileExists(bucket: string, path: string) {
    method cropImage (line 208) | async cropImage(
    method downloadFile (line 272) | async downloadFile(bucket: string, path: string): Promise<ReadableStre...
    method deleteDir (line 276) | async deleteDir(bucket: string, path: string, throwError: boolean = tr...

FILE: apps/nestjs-backend/src/features/attachments/plugins/s3.ts
  class S3Storage (line 29) | class S3Storage implements StorageAdapter {
    method constructor (line 36) | constructor(@StorageConfig() readonly config: IStorageConfig) {
    method checkConfig (line 115) | private checkConfig() {
    method replaceBucketEndpoint (line 169) | private replaceBucketEndpoint(bucket: string, internal?: boolean) {
    method presigned (line 177) | async presigned(bucket: string, dir: string, params: IPresignParams): ...
    method getObjectMeta (line 226) | async getObjectMeta(bucket: string, path: string): Promise<IObjectMeta> {
    method getPreviewUrl (line 292) | async getPreviewUrl(
    method uploadFileWidthPath (line 308) | uploadFileWidthPath(
    method uploadFile (line 338) | uploadFile(
    method uploadFileStream (line 347) | async uploadFileStream(
    method fileExists (line 398) | private async fileExists(bucket: string, path: string): Promise<boolea...
    method cropImage (line 415) | async cropImage(
    method downloadFile (line 472) | async downloadFile(bucket: string, path: string): Promise<Readable> {
    method deleteDir (line 481) | async deleteDir(bucket: string, path: string, throwError: boolean = tr...

FILE: apps/nestjs-backend/src/features/attachments/plugins/storage.module.ts
  class StorageModule (line 8) | class StorageModule {}

FILE: apps/nestjs-backend/src/features/attachments/plugins/types.ts
  type IPresignParams (line 1) | interface IPresignParams {
  type IPresignRes (line 9) | interface IPresignRes {
  type IObjectMeta (line 17) | interface IObjectMeta {
  type ILocalFileUpload (line 26) | interface ILocalFileUpload {
  type IRespHeaders (line 32) | type IRespHeaders = {
  type ThumbnailSize (line 37) | enum ThumbnailSize {

FILE: apps/nestjs-backend/src/features/auth/auth.controller.ts
  class AuthController (line 24) | class AuthController {
    method constructor (line 25) | constructor(
    method signout (line 35) | async signout(@Req() req: Express.Request, @Res({ passthrough: true })...
    method me (line 42) | async me(@Req() request: Express.Request) {
    method user (line 51) | async user(@Req() request: Express.Request) {
    method tempToken (line 56) | async tempToken(): Promise<IGetTempTokenVo> {
    method deleteUser (line 61) | async deleteUser(

FILE: apps/nestjs-backend/src/features/auth/auth.module.ts
  constant CONDITIONAL_MODULE_TIMEOUT (line 25) | const CONDITIONAL_MODULE_TIMEOUT = process.env.CI ? 30000 : 5000;
  class AuthModule (line 67) | class AuthModule {}

FILE: apps/nestjs-backend/src/features/auth/auth.service.ts
  class AuthService (line 14) | class AuthService {
    method constructor (line 15) | constructor(
    method getUserInfo (line 21) | async getUserInfo(user: IUserMeVo): Promise<IUserInfoVo> {
    method validateJwtToken (line 34) | async validateJwtToken(token: string) {
    method getTempToken (line 42) | async getTempToken() {
    method getTempInternalToken (line 53) | async getTempInternalToken(

FILE: apps/nestjs-backend/src/features/auth/decorators/allow-anonymous.decorator.ts
  type AllowAnonymousType (line 3) | enum AllowAnonymousType {
  constant IS_ALLOW_ANONYMOUS (line 9) | const IS_ALLOW_ANONYMOUS = 'isAllowAnonymous';

FILE: apps/nestjs-backend/src/features/auth/decorators/base-node-permissions.decorator.ts
  constant BASE_NODE_PERMISSIONS_KEY (line 4) | const BASE_NODE_PERMISSIONS_KEY = 'baseNodePermissions';

FILE: apps/nestjs-backend/src/features/auth/decorators/disabled-permission.decorator.ts
  constant IS_DISABLED_PERMISSION (line 3) | const IS_DISABLED_PERMISSION = 'isDisabledPermission';

FILE: apps/nestjs-backend/src/features/auth/decorators/ensure-login.decorator.ts
  constant ENSURE_LOGIN (line 3) | const ENSURE_LOGIN = 'ensureLogin';

FILE: apps/nestjs-backend/src/features/auth/decorators/permissions.decorator.ts
  constant PERMISSIONS_KEY (line 4) | const PERMISSIONS_KEY = 'permissions';

FILE: apps/nestjs-backend/src/features/auth/decorators/public.decorator.ts
  constant IS_PUBLIC_KEY (line 3) | const IS_PUBLIC_KEY = 'isPublic';

FILE: apps/nestjs-backend/src/features/auth/decorators/resource_meta.decorator.ts
  type IResourceMeta (line 3) | type IResourceMeta = {
  constant RESOURCE_META (line 8) | const RESOURCE_META = 'resourceMeta';

FILE: apps/nestjs-backend/src/features/auth/decorators/token.decorator.ts
  constant IS_TOKEN_ACCESS (line 3) | const IS_TOKEN_ACCESS = 'isTokenAccess';

FILE: apps/nestjs-backend/src/features/auth/guard/auth.guard.ts
  class AuthGuard (line 18) | class AuthGuard extends PassportAuthGuard([
    method constructor (line 24) | constructor(
    method validate (line 31) | async validate(context: ExecutionContext) {
    method canActivate (line 43) | async canActivate(context: ExecutionContext) {

FILE: apps/nestjs-backend/src/features/auth/guard/base-node-permission.guard.ts
  class BaseNodePermissionGuard (line 22) | class BaseNodePermissionGuard extends PermissionGuard {
    method constructor (line 23) | constructor(
    method canActivate (line 32) | async canActivate(context: ExecutionContext) {
    method checkActivate (line 60) | async checkActivate(
    method getBaseId (line 113) | getBaseId(context: ExecutionContext): string | undefined {
    method getNodeId (line 119) | getNodeId(context: ExecutionContext): string | undefined {
    method getNodeResourceType (line 124) | getNodeResourceType(context: ExecutionContext): BaseNodeResourceType {
    method getNode (line 129) | async getNode(baseId: string, nodeId?: string) {
    method getPermissionContext (line 150) | private async getPermissionContext() {

FILE: apps/nestjs-backend/src/features/auth/guard/github.guard.ts
  class GithubGuard (line 5) | class GithubGuard extends AuthGuard('github') {}

FILE: apps/nestjs-backend/src/features/auth/guard/google.guard.ts
  class GoogleGuard (line 5) | class GoogleGuard extends AuthGuard('google') {}

FILE: apps/nestjs-backend/src/features/auth/guard/local-auth.guard.ts
  class LocalAuthGuard (line 6) | class LocalAuthGuard extends AuthGuard('local') {
    method canActivate (line 7) | async canActivate(context: ExecutionContext): Promise<boolean> {

FILE: apps/nestjs-backend/src/features/auth/guard/oidc.guard.ts
  class OIDCGuard (line 5) | class OIDCGuard extends AuthGuard('openidconnect') {}

FILE: apps/nestjs-backend/src/features/auth/guard/permission.guard.ts
  class PermissionGuard (line 22) | class PermissionGuard {
    method constructor (line 25) | constructor(
    method defaultResourceId (line 31) | protected defaultResourceId(context: ExecutionContext): string | undef...
    method getResourceId (line 37) | protected getResourceId(context: ExecutionContext): string | undefined {
    method permissionCreateSpace (line 54) | private async permissionCreateSpace() {
    method permissionBaseReadAll (line 63) | private async permissionBaseReadAll() {
    method permissionSpaceRead (line 72) | private async permissionSpaceRead() {
    method permissionUserIntegrations (line 81) | private async permissionUserIntegrations() {
    method templatePermissionCheck (line 90) | protected async templatePermissionCheck(context: ExecutionContext, tem...
    method baseSharePermissionCheck (line 132) | protected async baseSharePermissionCheck(context: ExecutionContext, sh...
    method ensureBaseShareAuth (line 168) | private async ensureBaseShareAuth(context: ExecutionContext, shareId: ...
    method resourcePermission (line 185) | private async resourcePermission(resourceId: string | undefined, permi...
    method instancePermissionChecker (line 207) | protected async instancePermissionChecker(action: Action) {
    method permissionCheck (line 237) | protected async permissionCheck(context: ExecutionContext) {
    method isAnonymous (line 281) | private isAnonymous() {
    method tryBaseSharePermissionCheck (line 289) | private async tryBaseSharePermissionCheck(
    method resolveResourcePermission (line 307) | private async resolveResourcePermission(
    method resolveAnonymousPermission (line 326) | private async resolveAnonymousPermission(
    method resolvePublicFallback (line 343) | private async resolvePublicFallback(
    method tryBaseShareFallback (line 364) | private async tryBaseShareFallback(
    method permissionCheckWithPublicFallback (line 390) | protected async permissionCheckWithPublicFallback(
    method canActivate (line 448) | async canActivate(context: ExecutionContext) {

FILE: apps/nestjs-backend/src/features/auth/guard/social.guard.ts
  class SocialGuard (line 5) | class SocialGuard {
    method canActivate (line 6) | async canActivate(context: ExecutionContext): Promise<boolean> {

FILE: apps/nestjs-backend/src/features/auth/local-auth/local-auth.controller.ts
  class LocalAuthController (line 44) | class LocalAuthController {
    method constructor (line 45) | constructor(
    method signin (line 54) | async signin(@Req() req: Request): Promise<IUserMeVo> {
    method signup (line 60) | async signup(
    method joinWaitlist (line 77) | async joinWaitlist(
    method inviteWaitlist (line 86) | async inviteWaitlist(
    method getWaitlist (line 94) | async getWaitlist(): Promise<IGetWaitlistVo> {
    method genWaitlistInviteCode (line 100) | async genWaitlistInviteCode(
    method sendSignupVerificationCode (line 118) | async sendSignupVerificationCode(
    method changePassword (line 134) | async changePassword(
    method sendResetPasswordEmail (line 146) | async sendResetPasswordEmail(
    method resetPassword (line 154) | async resetPassword(
    method addPassword (line 165) | async addPassword(
    method changeEmail (line 176) | async changeEmail(
    method sendChangeEmailCode (line 188) | async sendChangeEmailCode(

FILE: apps/nestjs-backend/src/features/auth/local-auth/local-auth.module.ts
  class LocalAuthModule (line 36) | class LocalAuthModule {}

FILE: apps/nestjs-backend/src/features/auth/local-auth/local-auth.service.ts
  class LocalAuthService (line 33) | class LocalAuthService {
    method constructor (line 36) | constructor(
    method encodePassword (line 53) | private async encodePassword(password: string) {
    method comparePassword (line 59) | private async comparePassword(
    method getUserByIdOrThrow (line 68) | private as
Copy disabled (too large) Download .json
Condensed preview — 6559 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (16,737K chars).
[
  {
    "path": ".codeclimate.yml",
    "chars": 1156,
    "preview": "# @link https://docs.codeclimate.com/docs/default-analysis-configuration#sample-codeclimateyml\n\nversion: '2'\n\nchecks:\n  "
  },
  {
    "path": ".dockerignore",
    "chars": 616,
    "preview": "# All node_modules directories\n**/node_modules\n**/dist\n**/.next\n\n# All secrets\n**/.env.local\n**/.env.*.local\n\n# By defau"
  },
  {
    "path": ".gitattributes",
    "chars": 4874,
    "preview": "## Source: https://github.com/alexkaratarakis/gitattributes\n## Modified * text=auto to * text eol=lf to force LF endings"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 31,
    "preview": "github: teableio\nko_fi: teable\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 798,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: \"\"\nlabels: \"\"\nassignees: \"\"\n---\n\n**Describe the bu"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 594,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: \"\"\nlabels: \"\"\nassignees: \"\"\n---\n\n**Is your feat"
  },
  {
    "path": ".github/actions/docker-build-push/action.yml",
    "chars": 2358,
    "preview": "name: 'Docker build push (app)'\ndescription: 'Build and push Docker images with Buildx'\ninputs:\n  context:\n    descripti"
  },
  {
    "path": ".github/actions/pnpm-install/action.yml",
    "chars": 2151,
    "preview": "#######################################################################################\n# \"pnpm install\" composite actio"
  },
  {
    "path": ".github/workflows/docker-push.yml",
    "chars": 3979,
    "preview": "name: Build and Push to Docker Registry\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-prog"
  },
  {
    "path": ".github/workflows/integration-tests.yml",
    "chars": 2269,
    "preview": "name: Integration Tests\n\non:\n  push:\n    branches:\n      - develop\n  pull_request:\n    branches:\n      - develop\n    pat"
  },
  {
    "path": ".github/workflows/issue-id-check.yml",
    "chars": 9970,
    "preview": "name: Issue ID Check\n\non:\n  pull_request:\n    types: [opened, synchronize, edited, reopened]\n    branches:\n      - devel"
  },
  {
    "path": ".github/workflows/linting.yml",
    "chars": 1114,
    "preview": "name: Linting and Types\n\non:\n  pull_request:\n    branches:\n      - develop\n    paths:\n      - 'apps/**'\n      - 'package"
  },
  {
    "path": ".github/workflows/manual-preview.yml",
    "chars": 5012,
    "preview": "name: Preview PR\n\npermissions:\n  contents: read\n  pull-requests: write\n\non:\n  pull_request:\n    types:\n      - opened\n  "
  },
  {
    "path": ".github/workflows/preview-cleanup.yml",
    "chars": 2020,
    "preview": "name: Cleanup Preview Environment\n\non:\n  pull_request:\n    types: [closed]\n\nenv:\n  NAMESPACE: 38puz7wo\n  INSTANCE_NAME: "
  },
  {
    "path": ".github/workflows/templates/preview-template.yaml",
    "chars": 15256,
    "preview": "apiVersion: app.sealos.io/v1\nkind: Instance\nmetadata:\n  name: teable-__INSTANCE_NAME__\n  labels:\n    cloud.sealos.io/dep"
  },
  {
    "path": ".github/workflows/trigger-sync-to-ee.yml",
    "chars": 1805,
    "preview": "name: Trigger Sync to EE\n\non:\n  push:\n    branches:\n      - develop\n\njobs:\n  check-and-trigger:\n    runs-on: ubuntu-late"
  },
  {
    "path": ".github/workflows/unit-tests.yml",
    "chars": 1151,
    "preview": "name: Unit Tests\n\non:\n  push:\n    branches:\n      - develop\n  pull_request:\n    branches:\n      - develop\n    paths:\n   "
  },
  {
    "path": ".github/workflows/v2-benchmark-tests.yml",
    "chars": 879,
    "preview": "name: V2 Benchmarks\n\non:\n  workflow_dispatch:\n  pull_request:\n    branches:\n      - develop\n    paths:\n      - 'packages"
  },
  {
    "path": ".github/workflows/v2-core-tests.yml",
    "chars": 4271,
    "preview": "name: V2 Tests\n\non:\n  pull_request:\n    branches:\n      - develop\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ gith"
  },
  {
    "path": ".gitignore",
    "chars": 1057,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n# and https://github.com/github/gi"
  },
  {
    "path": ".gitpod.yml",
    "chars": 98,
    "preview": "tasks:\n  - init: pnpm install\n    command: make sqlite-mode && cd apps/nestjs-backend && pnpm dev\n"
  },
  {
    "path": ".husky/commit-msg",
    "chars": 25,
    "preview": "pnpm commitlint --edit $1"
  },
  {
    "path": ".husky/install.mjs",
    "chars": 207,
    "preview": "// Skip Husky install in production and CI\nif (process.env.NODE_ENV === 'production' || process.env.CI === 'true') {\n  p"
  },
  {
    "path": ".husky/pre-commit",
    "chars": 32,
    "preview": "pnpm g:lint-staged-files --debug"
  },
  {
    "path": ".idea/modules.xml",
    "chars": 1895,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": ".idea/teable.iml",
    "chars": 1086,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\">\n"
  },
  {
    "path": ".ncurc.yml",
    "chars": 326,
    "preview": "# npm-check-updates configuration used by yarn deps:check && yarn deps:update\n# convenience scripts.\n# @link https://git"
  },
  {
    "path": ".npmrc",
    "chars": 196,
    "preview": "engine-strict=true\nstrict-peer-dependencies=false\nauto-install-peers=true\nlockfile=true\n# force use npmjs.org registry\nr"
  },
  {
    "path": ".prettierignore",
    "chars": 120,
    "preview": ".idea/\n.vscode/\npnpm-lock.yaml\n**/.next\n**/.out\n**/dist\n**/build\n**/.tmp\n**/.cache\napps/playground/src/routeTree.gen.ts\n"
  },
  {
    "path": ".prettierrc.js",
    "chars": 461,
    "preview": "// @ts-check\n\nconst { getPrettierConfig } = require('@teable/eslint-config-bases/helpers');\n\nconst { overrides = [], ..."
  },
  {
    "path": ".vscode/extensions.json",
    "chars": 55,
    "preview": "{\n  \"recommendations\": [\"bradlc.vscode-tailwindcss\"]\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 4603,
    "preview": "{\n  // Use IntelliSense to learn about possible attributes.\n  // Hover to view descriptions of existing attributes.\n  //"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 1325,
    "preview": "{\n  \"cSpell.words\": [\n    \"antlr\",\n    \"AUTOINCREMENT\",\n    \"COUNTALL\",\n    \"DATETIME\",\n    \"gantt\",\n    \"ILIKE\",\n    \"L"
  },
  {
    "path": "AGPL_LICENSE",
    "chars": 35315,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5488,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4603,
    "preview": "# Contributing\n\nThe base branch is **`develop`**.\n\n## Development Setup\n\n> **Note**\n> The following commands are for Lin"
  },
  {
    "path": "LICENSE",
    "chars": 1771,
    "preview": "Copyright (c) 2023-2025 Teable, Inc.\n\nTeable Project Licensing\n\nThis project is a combination of components under differ"
  },
  {
    "path": "Makefile",
    "chars": 12075,
    "preview": "SHELL := /usr/bin/env bash\n\n# define standard colors\nifneq (,$(findstring xterm,${TERM}))\n\tBLACK        := $(shell tput "
  },
  {
    "path": "README.md",
    "chars": 10281,
    "preview": "<div align=\"center\">\n  <h1 align=\"center\">\n    <picture>\n      <source media=\"(prefers-color-scheme: dark)\" srcset=\"stat"
  },
  {
    "path": "agents.md",
    "chars": 3892,
    "preview": "# Teable v2 agent guide\n\nDDD/domain-model guidance has moved to the skill `teable-ddd-domain-model` in `.codex/skills/te"
  },
  {
    "path": "apps/nestjs-backend/.eslintrc.js",
    "chars": 1482,
    "preview": "/**\n * Specific eslint rules for this app/package, extends the base rules\n * @see https://github.com/teableio/teable/blo"
  },
  {
    "path": "apps/nestjs-backend/.gitignore",
    "chars": 98,
    "preview": "# build\nbuild\ndist\n\n# testing\n/coverage\n\n# misc\n.DS_Store\n*.pem\n.assets\n.temporary\n.webpack-cache\n"
  },
  {
    "path": "apps/nestjs-backend/.idea/modules.xml",
    "chars": 280,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": "apps/nestjs-backend/.idea/nestjs-backend.iml",
    "chars": 458,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"WEB_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\">\n"
  },
  {
    "path": "apps/nestjs-backend/README.md",
    "chars": 143,
    "preview": "# NestJS backend for teable\n\nTODO:\nremove @valibot/to-json-schema in ai-sdk6\nremove effect in ai-sdk6\nremove @ai-sdk/pro"
  },
  {
    "path": "apps/nestjs-backend/nest-cli.json",
    "chars": 211,
    "preview": "{\n  \"$schema\": \"https://json.schemastore.org/nest-cli\",\n  \"collection\": \"@nestjs/schematics\",\n  \"sourceRoot\": \"src\",\n  \""
  },
  {
    "path": "apps/nestjs-backend/package.json",
    "chars": 9665,
    "preview": "{\n  \"name\": \"@teable/backend\",\n  \"version\": \"1.10.0\",\n  \"license\": \"AGPL-3.0\",\n  \"private\": true,\n  \"main\": \"dist/index."
  },
  {
    "path": "apps/nestjs-backend/src/app.module.ts",
    "chars": 6185,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { BullModule } from '@nestjs/bullmq';\nimport type { Mod"
  },
  {
    "path": "apps/nestjs-backend/src/bootstrap.ts",
    "chars": 3477,
    "preview": "import 'dayjs/plugin/timezone';\nimport 'dayjs/plugin/utc';\nimport type { INestApplication } from '@nestjs/common';\nimpor"
  },
  {
    "path": "apps/nestjs-backend/src/cache/cache.module.ts",
    "chars": 675,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { ConfigurableModuleBuilder, type DynamicModule, Module"
  },
  {
    "path": "apps/nestjs-backend/src/cache/cache.provider.ts",
    "chars": 1507,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport path from 'path';\nimport KeyvRedis from '@keyv/redis';\n"
  },
  {
    "path": "apps/nestjs-backend/src/cache/cache.service.ts",
    "chars": 5107,
    "preview": "import { Injectable, Logger } from '@nestjs/common';\nimport { getRandomInt } from '@teable/core';\nimport type { Redis } "
  },
  {
    "path": "apps/nestjs-backend/src/cache/types.ts",
    "chars": 7831,
    "preview": "import type { IColumnMeta, IFieldVo, IOtOperation, IViewPropertyKeys, IViewVo } from '@teable/core';\nimport type { IReco"
  },
  {
    "path": "apps/nestjs-backend/src/configs/auth.config.ts",
    "chars": 2938,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { Inject } from '@nestjs/common';\nimport type { ConfigT"
  },
  {
    "path": "apps/nestjs-backend/src/configs/base.config.ts",
    "chars": 1187,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { Inject } from '@nestjs/common';\nimport type { ConfigT"
  },
  {
    "path": "apps/nestjs-backend/src/configs/bootstrap.config.ts",
    "chars": 953,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport type { ConfigType } from '@nestjs/config';\nimport { reg"
  },
  {
    "path": "apps/nestjs-backend/src/configs/cache.config.ts",
    "chars": 628,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { Inject } from '@nestjs/common';\nimport type { ConfigT"
  },
  {
    "path": "apps/nestjs-backend/src/configs/config.module.ts",
    "chars": 1627,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport path from 'path';\nimport type { DynamicModule } from '@"
  },
  {
    "path": "apps/nestjs-backend/src/configs/config.spec.ts",
    "chars": 1065,
    "preview": "import { ConfigService } from '@nestjs/config';\nimport type { TestingModule } from '@nestjs/testing';\nimport { Test } fr"
  },
  {
    "path": "apps/nestjs-backend/src/configs/env.validation.schema.ts",
    "chars": 1981,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport Joi from 'joi';\n\nexport const envValidationSchema = Joi"
  },
  {
    "path": "apps/nestjs-backend/src/configs/logger.config.ts",
    "chars": 503,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { Inject } from '@nestjs/common';\nimport type { ConfigT"
  },
  {
    "path": "apps/nestjs-backend/src/configs/mail.config.ts",
    "chars": 1643,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { Inject } from '@nestjs/common';\nimport type { ConfigT"
  },
  {
    "path": "apps/nestjs-backend/src/configs/oauth.config.ts",
    "chars": 921,
    "preview": "import { Inject } from '@nestjs/common';\nimport type { ConfigType } from '@nestjs/config';\nimport { registerAs } from '@"
  },
  {
    "path": "apps/nestjs-backend/src/configs/storage.ts",
    "chars": 2280,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { Inject } from '@nestjs/common';\nimport type { ConfigT"
  },
  {
    "path": "apps/nestjs-backend/src/configs/threshold.config.ts",
    "chars": 2976,
    "preview": "/* eslint-disable sonarjs/cognitive-complexity */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport { Inj"
  },
  {
    "path": "apps/nestjs-backend/src/configs/trash.config.ts",
    "chars": 879,
    "preview": "/* eslint-disable sonarjs/cognitive-complexity */\n/* eslint-disable @typescript-eslint/naming-convention */\n\nimport { In"
  },
  {
    "path": "apps/nestjs-backend/src/const.ts",
    "chars": 100,
    "preview": "export const X_REQUEST_ID = 'X-Request-Id';\nexport const AUTH_SESSION_COOKIE_NAME = 'auth_session';\n"
  },
  {
    "path": "apps/nestjs-backend/src/custom.exception.ts",
    "chars": 1978,
    "preview": "import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { ICustomHttpExceptionData } from '@teable/core'"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-function.abstract.ts",
    "chars": 4644,
    "preview": "import { InternalServerErrorException } from '@nestjs/common';\nimport type { FieldCore } from '@teable/core';\nimport { S"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-function.interface.ts",
    "chars": 963,
    "preview": "export type IAggregationFunctionHandler = () => string;\n\nexport interface IAggregationFunctionInterface {\n  count: IAggr"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-query.abstract.ts",
    "chars": 5197,
    "preview": "import { BadRequestException } from '@nestjs/common';\nimport type { FieldCore } from '@teable/core';\nimport { CellValueT"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/aggregation-query.interface.ts",
    "chars": 121,
    "preview": "import type { Knex } from 'knex';\n\nexport interface IAggregationQueryInterface {\n  appendBuilder(): Knex.QueryBuilder;\n}"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/postgres/__tests__/multiple-value-aggregation.adapter.spec.ts",
    "chars": 1574,
    "preview": "import type { FieldCore } from '@teable/core';\nimport { FieldType } from '@teable/core';\nimport knex from 'knex';\nimport"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/postgres/aggregation-function.postgres.ts",
    "chars": 2693,
    "preview": "import { NotImplementedException } from '@nestjs/common';\nimport { FieldType } from '@teable/core';\nimport { AbstractAgg"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/postgres/aggregation-query.postgres.ts",
    "chars": 1371,
    "preview": "import type { FieldCore } from '@teable/core';\nimport { AbstractAggregationQuery } from '../aggregation-query.abstract';"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/postgres/multiple-value/multiple-value-aggregation.adapter.ts",
    "chars": 3510,
    "preview": "import { AggregationFunctionPostgres } from '../aggregation-function.postgres';\n\nexport class MultipleValueAggregationAd"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/postgres/single-value/single-value-aggregation.adapter.ts",
    "chars": 498,
    "preview": "import { AggregationFunctionPostgres } from '../aggregation-function.postgres';\n\nexport class SingleValueAggregationAdap"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/aggregation-function.sqlite.ts",
    "chars": 2658,
    "preview": "import { NotImplementedException } from '@nestjs/common';\nimport { FieldType } from '@teable/core';\nimport { AbstractAgg"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/aggregation-query.sqlite.ts",
    "chars": 1353,
    "preview": "import type { FieldCore } from '@teable/core';\nimport { AbstractAggregationQuery } from '../aggregation-query.abstract';"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/multiple-value/multiple-value-aggregation.adapter.ts",
    "chars": 3150,
    "preview": "import { AggregationFunctionSqlite } from '../aggregation-function.sqlite';\n\nexport class MultipleValueAggregationAdapte"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/aggregation-query/sqlite/single-value/single-value-aggregation.adapter.ts",
    "chars": 514,
    "preview": "import { AggregationFunctionSqlite } from '../aggregation-function.sqlite';\n\nexport class SingleValueAggregationAdapter "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/base-query/abstract.ts",
    "chars": 255,
    "preview": "import type { Knex } from 'knex';\n\nexport abstract class BaseQueryAbstract {\n  constructor(protected readonly knex: Knex"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/base-query/base-query.postgres.ts",
    "chars": 488,
    "preview": "import type { Knex } from 'knex';\nimport { BaseQueryAbstract } from './abstract';\n\nexport class BaseQueryPostgres extend"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/base-query/base-query.sqlite.ts",
    "chars": 420,
    "preview": "import type { Knex } from 'knex';\nimport { BaseQueryAbstract } from './abstract';\n\nexport class BaseQuerySqlite extends "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field-visitor.interface.ts",
    "chars": 1473,
    "preview": "import type { TableDomain } from '@teable/core';\nimport type { Knex } from 'knex';\nimport type { IFieldInstance } from '"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field-visitor.postgres.ts",
    "chars": 15681,
    "preview": "import type {\n  AttachmentFieldCore,\n  AutoNumberFieldCore,\n  CheckboxFieldCore,\n  CreatedByFieldCore,\n  CreatedTimeFiel"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field-visitor.sqlite.ts",
    "chars": 15992,
    "preview": "import type {\n  AttachmentFieldCore,\n  AutoNumberFieldCore,\n  CheckboxFieldCore,\n  CreatedByFieldCore,\n  CreatedTimeFiel"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/create-database-column-query/create-database-column-field.util.ts",
    "chars": 661,
    "preview": "import type { FormulaFieldCore, TableDomain } from '@teable/core';\nimport type { IGeneratedColumnQuerySupportValidator }"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/create-database-column-query/index.ts",
    "chars": 194,
    "preview": "export * from './create-database-column-field-visitor.interface';\nexport * from './create-database-column-field-visitor."
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/db.provider.interface.ts",
    "chars": 8771,
    "preview": "import type {\n  DriverClient,\n  FieldCore,\n  FieldType,\n  IFilter,\n  ILookupLinkOptionsVo,\n  ISortItem,\n  TableDomain,\n}"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/db.provider.ts",
    "chars": 873,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport type { Provider } from '@nestjs/common';\nimport { Injec"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/drop-database-column-query/drop-database-column-field-visitor.interface.ts",
    "chars": 1030,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport type { Knex } from 'knex';\n\n/**\n * Operation types for "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/drop-database-column-query/drop-database-column-field-visitor.postgres.ts",
    "chars": 7825,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\nimport { Relationship } from '@teable/core';\nimport type {\n  Attachment"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/drop-database-column-query/drop-database-column-field-visitor.sqlite.ts",
    "chars": 7171,
    "preview": "import { Relationship } from '@teable/core';\nimport type {\n  AttachmentFieldCore,\n  AutoNumberFieldCore,\n  CheckboxField"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/drop-database-column-query/index.ts",
    "chars": 188,
    "preview": "export * from './drop-database-column-field-visitor.interface';\nexport * from './drop-database-column-field-visitor.post"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/duplicate-table/abstract.ts",
    "chars": 403,
    "preview": "import type { Knex } from 'knex';\n\nexport abstract class DuplicateTableQueryAbstract {\n  constructor(protected readonly "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-attachment-table-query.abstract.ts",
    "chars": 357,
    "preview": "import type { Knex } from 'knex';\n\nexport abstract class DuplicateAttachmentTableQueryAbstract {\n  constructor(protected"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-attachment-table-query.postgres.ts",
    "chars": 1682,
    "preview": "import type { Knex } from 'knex';\nimport { DuplicateAttachmentTableQueryAbstract } from './duplicate-attachment-table-qu"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-attachment-table-query.sqlite.ts",
    "chars": 1635,
    "preview": "import type { Knex } from 'knex';\nimport { DuplicateAttachmentTableQueryAbstract } from './duplicate-attachment-table-qu"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-query.postgres.ts",
    "chars": 1617,
    "preview": "import type { Knex } from 'knex';\nimport { DuplicateTableQueryAbstract } from './abstract';\n\nexport class DuplicateTable"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/duplicate-table/duplicate-query.sqlite.ts",
    "chars": 1649,
    "preview": "import type { Knex } from 'knex';\nimport { DuplicateTableQueryAbstract } from './abstract';\n\nexport class DuplicateTable"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/__tests__/field-reference.spec.ts",
    "chars": 13479,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport {\n  Ce"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/cell-value-filter.abstract.ts",
    "chars": 19396,
    "preview": "import {\n  BadRequestException,\n  InternalServerErrorException,\n  NotImplementedException,\n} from '@nestjs/common';\nimpo"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/cell-value-filter.interface.ts",
    "chars": 1231,
    "preview": "import type { IFilterOperator, IFilterValue } from '@teable/core';\nimport type { Knex } from 'knex';\nimport type { IDbPr"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/filter-query.abstract.ts",
    "chars": 7786,
    "preview": "import { Logger } from '@nestjs/common';\nimport type {\n  FieldCore,\n  IConjunction,\n  IDateTimeFieldOperator,\n  IFilter,"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/filter-query.interface.ts",
    "chars": 121,
    "preview": "import type { Knex } from 'knex';\n\nexport interface IFilterQueryInterface {\n  appendQueryBuilder(): Knex.QueryBuilder;\n}"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/cell-value-filter.postgres.ts",
    "chars": 1909,
    "preview": "import type { IFilterOperator, IFilterValue } from '@teable/core';\nimport {\n  CellValueType,\n  doesNotContain,\n  isField"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/index.ts",
    "chars": 711,
    "preview": "export * from './single-value/boolean-cell-value-filter.adapter';\nexport * from './multiple-value/multiple-boolean-cell-"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-boolean-cell-value-filter.adapter.ts",
    "chars": 1300,
    "preview": "import type { IFilterOperator, IFilterValue } from '@teable/core';\nimport { isFieldReferenceValue } from '@teable/core';"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-datetime-cell-value-filter.adapter.ts",
    "chars": 4002,
    "preview": "/* eslint-disable sonarjs/no-identical-functions */\nimport type { IDateFieldOptions, IDateFilter, IFilterOperator, IFilt"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-json-cell-value-filter.adapter.ts",
    "chars": 11408,
    "preview": "import type {\n  FieldCore,\n  IFieldReferenceValue,\n  IFilterOperator,\n  ILiteralValue,\n  ILiteralValueList,\n} from '@tea"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-number-cell-value-filter.adapter.ts",
    "chars": 10990,
    "preview": "import type {\n  FieldCore,\n  IFieldReferenceValue,\n  IFilterOperator,\n  ILiteralValue,\n  ILiteralValueList,\n} from '@tea"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/multiple-value/multiple-string-cell-value-filter.adapter.ts",
    "chars": 2000,
    "preview": "import type { IFilterOperator, ILiteralValue } from '@teable/core';\nimport type { Knex } from 'knex';\nimport { escapeJso"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/boolean-cell-value-filter.adapter.ts",
    "chars": 1212,
    "preview": "import { isFieldReferenceValue, type IFilterOperator, type IFilterValue } from '@teable/core';\nimport type { Knex } from"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/datetime-cell-value-filter.adapter.ts",
    "chars": 7584,
    "preview": "/* eslint-disable sonarjs/no-identical-functions */\nimport {\n  DateFormattingPreset,\n  isFieldReferenceValue,\n  type IDa"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/json-cell-value-filter.adapter.ts",
    "chars": 8447,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\nimport type {\n  FieldCore,\n  IFieldReferenceValue,\n  IFilterOperator,\n "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/number-cell-value-filter.adapter.ts",
    "chars": 1917,
    "preview": "import type { IFilterOperator, ILiteralValue } from '@teable/core';\nimport type { Knex } from 'knex';\nimport type { IDbP"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/cell-value-filter/single-value/string-cell-value-filter.adapter.ts",
    "chars": 2599,
    "preview": "import {\n  CellValueType,\n  isFieldReferenceValue,\n  type IFieldReferenceValue,\n  type IFilterOperator,\n  type ILiteralV"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/postgres/filter-query.postgres.ts",
    "chars": 2804,
    "preview": "import type { FieldCore, IFilter } from '@teable/core';\nimport type { Knex } from 'knex';\nimport type { IRecordQueryFilt"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/cell-value-filter.sqlite.ts",
    "chars": 2948,
    "preview": "import type { FieldCore, IFilterOperator, IFilterValue } from '@teable/core';\nimport {\n  CellValueType,\n  contains,\n  do"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/index.ts",
    "chars": 711,
    "preview": "export * from './single-value/boolean-cell-value-filter.adapter';\nexport * from './multiple-value/multiple-boolean-cell-"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-boolean-cell-value-filter.adapter.ts",
    "chars": 1496,
    "preview": "import type { IFilterOperator, IFilterValue } from '@teable/core';\nimport { isFieldReferenceValue } from '@teable/core';"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-datetime-cell-value-filter.adapter.ts",
    "chars": 4371,
    "preview": "/* eslint-disable sonarjs/no-identical-functions */\nimport type { IDateFieldOptions, IDateFilter, IFilterOperator, IFilt"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-json-cell-value-filter.adapter.ts",
    "chars": 4748,
    "preview": "import type { IFilterOperator, ILiteralValue, ILiteralValueList } from '@teable/core';\nimport type { Knex } from 'knex';"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-number-cell-value-filter.adapter.ts",
    "chars": 2420,
    "preview": "import type { IFilterOperator, ILiteralValue } from '@teable/core';\nimport type { Knex } from 'knex';\nimport { CellValue"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/multiple-value/multiple-string-cell-value-filter.adapter.ts",
    "chars": 1878,
    "preview": "import type { IFilterOperator, ILiteralValue } from '@teable/core';\nimport type { Knex } from 'knex';\nimport { CellValue"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/boolean-cell-value-filter.adapter.ts",
    "chars": 1225,
    "preview": "import { isFieldReferenceValue, type IFilterOperator, type IFilterValue } from '@teable/core';\nimport type { Knex } from"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/datetime-cell-value-filter.adapter.ts",
    "chars": 4598,
    "preview": "/* eslint-disable sonarjs/no-identical-functions */\nimport {\n  isFieldReferenceValue,\n  type IDateFieldOptions,\n  type I"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/json-cell-value-filter.adapter.ts",
    "chars": 4429,
    "preview": "import type {\n  IFieldReferenceValue,\n  IFilterOperator,\n  IFilterValue,\n  ILiteralValue,\n  ILiteralValueList,\n} from '@"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/number-cell-value-filter.adapter.ts",
    "chars": 1911,
    "preview": "import type { IFilterOperator, ILiteralValue } from '@teable/core';\nimport type { Knex } from 'knex';\nimport type { IDbP"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/cell-value-filter/single-value/string-cell-value-filter.adapter.ts",
    "chars": 2247,
    "preview": "import {\n  CellValueType,\n  isFieldReferenceValue,\n  type IFieldReferenceValue,\n  type IFilterOperator,\n  type ILiteralV"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/filter-query/sqlite/filter-query.sqlite.ts",
    "chars": 2868,
    "preview": "import type { FieldCore, IFilter } from '@teable/core';\nimport type { Knex } from 'knex';\nimport type { IRecordQueryFilt"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/__snapshots__/formula-query.spec.ts.snap",
    "chars": 34037,
    "preview": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`GeneratedColumnQuery > PostgreSQL Generated Colu"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/__snapshots__/generated-column-query.spec.ts.snap",
    "chars": 35740,
    "preview": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`GeneratedColumnQuery > PostgreSQL Generated Colu"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/__snapshots__/sql-conversion.spec.ts.snap",
    "chars": 30698,
    "preview": "// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports[`Generated Column Query End-to-End Tests > Advanc"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/generated-column-query-support-validator.spec.ts",
    "chars": 8153,
    "preview": "import { GeneratedColumnQuerySupportValidatorPostgres } from './postgres/generated-column-query-support-validator.postgr"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/generated-column-query.abstract.ts",
    "chars": 8421,
    "preview": "import type { IFormulaParamMetadata } from '@teable/core';\nimport type {\n  IFormulaConversionContext,\n  IGeneratedColumn"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/index.ts",
    "chars": 625,
    "preview": "import { DriverClient } from '@teable/core';\nimport { match } from 'ts-pattern';\nimport { GeneratedColumnQuerySupportVal"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/postgres/generated-column-query-support-validator.postgres.ts",
    "chars": 11828,
    "preview": "import type {\n  IFormulaConversionContext,\n  IGeneratedColumnQuerySupportValidator,\n} from '../../../features/record/que"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/postgres/generated-column-query.postgres.spec.ts",
    "chars": 3935,
    "preview": "import { DbFieldType } from '@teable/core';\nimport { describe, expect, it } from 'vitest';\n\nimport { GeneratedColumnQuer"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/postgres/generated-column-query.postgres.ts",
    "chars": 57298,
    "preview": "/* eslint-disable sonarjs/cognitive-complexity */\n/* eslint-disable regexp/no-unused-capturing-group */\n/* eslint-disabl"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/sqlite/generated-column-query-support-validator.sqlite.ts",
    "chars": 11338,
    "preview": "import type {\n  IFormulaConversionContext,\n  IGeneratedColumnQuerySupportValidator,\n} from '../../../features/record/que"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/sqlite/generated-column-query.sqlite.spec.ts",
    "chars": 2511,
    "preview": "import { DbFieldType } from '@teable/core';\nimport { describe, expect, it } from 'vitest';\nimport { GeneratedColumnQuery"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/generated-column-query/sqlite/generated-column-query.sqlite.ts",
    "chars": 27466,
    "preview": "/* eslint-disable sonarjs/no-identical-functions */\nimport { isTextLikeParam, resolveFormulaParamInfo } from '../../util"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/group-query/format-string.ts",
    "chars": 799,
    "preview": "import { DateFormattingPreset, TimeFormatting } from '@teable/core';\n\nexport const getPostgresDateTimeFormatString = (\n "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/group-query/group-query.abstract.ts",
    "chars": 2982,
    "preview": "import { Logger } from '@nestjs/common';\nimport type { FieldCore } from '@teable/core';\nimport { CellValueType } from '@"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/group-query/group-query.interface.ts",
    "chars": 183,
    "preview": "import type { Knex } from 'knex';\n\nexport interface IGroupQueryInterface {\n  appendGroupBuilder(): Knex.QueryBuilder;\n}\n"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/group-query/group-query.postgres.ts",
    "chars": 7263,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\nimport type { INumberFieldOptions, IDateFieldOptions, FieldCore } from "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/group-query/group-query.sqlite.ts",
    "chars": 6142,
    "preview": "import type { DateFormattingPreset, INumberFieldOptions, IDateFieldOptions } from '@teable/core';\nimport type { Knex } f"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/index-query/index-abstract-builder.ts",
    "chars": 961,
    "preview": "import type { IGetAbnormalVo } from '@teable/openapi';\nimport type { IFieldInstance } from '../../features/field/model/f"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/integrity-query/abstract.ts",
    "chars": 1183,
    "preview": "import type { Knex } from 'knex';\n\nexport abstract class IntegrityQueryAbstract {\n  constructor(protected readonly knex:"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/integrity-query/integrity-query.postgres.ts",
    "chars": 6632,
    "preview": "import type { Knex } from 'knex';\nimport { IntegrityQueryAbstract } from './abstract';\n\nexport class IntegrityQueryPostg"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/integrity-query/integrity-query.sqlite.ts",
    "chars": 7025,
    "preview": "import type { Knex } from 'knex';\nimport { IntegrityQueryAbstract } from './abstract';\n\nexport class IntegrityQuerySqlit"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/postgres.provider.ts",
    "chars": 32055,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\nimport { Logger } from '@nestjs/common';\nimport type {\n  IFilter,\n  ILo"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/search-query/abstract.ts",
    "chars": 4134,
    "preview": "import type { TableIndex } from '@teable/openapi';\nimport type { Knex } from 'knex';\nimport type { IFieldInstance } from"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/search-query/get-offset.ts",
    "chars": 270,
    "preview": "import dayjs from 'dayjs';\nimport 'dayjs/plugin/utc';\n\nexport function getOffset(timeZone: string) {\n  const offsetMinut"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/search-query/search-index-builder.postgres.ts",
    "chars": 8226,
    "preview": "/* eslint-disable regexp/no-unused-capturing-group */\n/* eslint-disable sonarjs/no-duplicate-string */\nimport { assertNe"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/search-query/search-index-builder.sqlite.ts",
    "chars": 3693,
    "preview": "/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { CellValueType } from '@teable/core';\nimport type { IGetA"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/search-query/search-query.postgres.ts",
    "chars": 12679,
    "preview": "import type { IDateFieldOptions } from '@teable/core';\nimport { CellValueType, FieldType } from '@teable/core';\nimport t"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/search-query/search-query.sqlite.ts",
    "chars": 11123,
    "preview": "import { CellValueType, type IDateFieldOptions } from '@teable/core';\nimport type { ISearchIndexByQueryRo, TableIndex } "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/search-query/types.ts",
    "chars": 724,
    "preview": "import type { CellValueType } from '@teable/core';\nimport type { TableIndex } from '@teable/openapi';\nimport type { Knex"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/select-query/index.ts",
    "chars": 280,
    "preview": "// Abstract base class\nexport { SelectQueryAbstract } from './select-query.abstract';\n\n// PostgreSQL implementation\nexpo"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/select-query/postgres/select-query.postgres.spec.ts",
    "chars": 6149,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\nimport { DbFieldType } from '@teable/core';\nimport { describe, expect, "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/select-query/postgres/select-query.postgres.ts",
    "chars": 74002,
    "preview": "/* eslint-disable regexp/no-unused-capturing-group */\n/* eslint-disable sonarjs/cognitive-complexity */\nimport { DateFor"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/select-query/select-query.abstract.ts",
    "chars": 7902,
    "preview": "import type { IFormulaParamMetadata } from '@teable/core';\nimport type {\n  ISelectQueryInterface,\n  IFormulaConversionCo"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/select-query/sqlite/select-query.sqlite.spec.ts",
    "chars": 9236,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\nimport { DbFieldType } from '@teable/core';\nimport { describe, expect, "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/select-query/sqlite/select-query.sqlite.ts",
    "chars": 27442,
    "preview": "import type { ISelectFormulaConversionContext } from '../../../features/record/query-builder/sql-conversion.visitor';\nim"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/function/sort-function.abstract.ts",
    "chars": 3941,
    "preview": "import { InternalServerErrorException } from '@nestjs/common';\nimport type { FieldCore } from '@teable/core';\nimport { S"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/function/sort-function.interface.ts",
    "chars": 310,
    "preview": "import type { Knex } from 'knex';\n\nexport type ISortFunctionHandler = (builderClient: Knex.QueryBuilder) => Knex.QueryBu"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/multiple-value/multiple-datetime-sort.adapter.ts",
    "chars": 5735,
    "preview": "import { TimeFormatting, type DateFormattingPreset, type IDateFieldOptions } from '@teable/core';\nimport type { Knex } f"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/multiple-value/multiple-json-sort.adapter.ts",
    "chars": 4887,
    "preview": "import type { ISelectFieldOptions } from '@teable/core';\nimport { FieldType } from '@teable/core';\nimport type { Knex } "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/multiple-value/multiple-number-sort.adapter.ts",
    "chars": 2950,
    "preview": "import type { INumberFieldOptions } from '@teable/core';\nimport type { Knex } from 'knex';\nimport { SortFunctionPostgres"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/single-value/date-sort.adapter.ts",
    "chars": 2836,
    "preview": "import { type IDateFieldOptions, type DateFormattingPreset, TimeFormatting } from '@teable/core';\nimport type { Knex } f"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/single-value/json-sort.adapter.ts",
    "chars": 1713,
    "preview": "import type { Knex } from 'knex';\nimport { isUserOrLink } from '../../../../utils/is-user-or-link';\nimport { SortFunctio"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/single-value/string-sort.adapter.ts",
    "chars": 2521,
    "preview": "import type { ISelectFieldOptions } from '@teable/core';\nimport { FieldType } from '@teable/core';\nimport type { Knex } "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/sort-query.function.ts",
    "chars": 1476,
    "preview": "import { DbFieldType } from '@teable/core';\nimport type { Knex } from 'knex';\nimport { AbstractSortFunction } from '../f"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/postgres/sort-query.postgres.ts",
    "chars": 2211,
    "preview": "import type { FieldCore } from '@teable/core';\nimport type { IRecordQuerySortContext } from '../../../features/record/qu"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sort-query.abstract.ts",
    "chars": 3429,
    "preview": "import { Logger } from '@nestjs/common';\nimport type { FieldCore, ISortItem } from '@teable/core';\nimport { CellValueTyp"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sort-query.interface.ts",
    "chars": 149,
    "preview": "import type { Knex } from 'knex';\n\nexport interface ISortQueryInterface {\n  appendSortBuilder(): Knex.QueryBuilder;\n  ge"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/multiple-value/multiple-datetime-sort.adapter.ts",
    "chars": 4195,
    "preview": "import { TimeFormatting, type DateFormattingPreset, type IDateFieldOptions } from '@teable/core';\nimport type { Knex } f"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/multiple-value/multiple-json-sort.adapter.ts",
    "chars": 1397,
    "preview": "import type { Knex } from 'knex';\nimport { SortFunctionSqlite } from '../sort-query.function';\n\nexport class MultipleJso"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/multiple-value/multiple-number-sort.adapter.ts",
    "chars": 2102,
    "preview": "import type { INumberFieldOptions } from '@teable/core';\nimport type { Knex } from 'knex';\nimport { SortFunctionSqlite }"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/single-value/date-sort.adapter.ts",
    "chars": 3121,
    "preview": "import { type IDateFieldOptions, type DateFormattingPreset, TimeFormatting } from '@teable/core';\nimport type { Knex } f"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/single-value/json-sort.adapter.ts",
    "chars": 1705,
    "preview": "import type { Knex } from 'knex';\nimport { isUserOrLink } from '../../../../utils/is-user-or-link';\nimport { SortFunctio"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/single-value/string-sort.adapter.ts",
    "chars": 2180,
    "preview": "import type { ISelectFieldOptions } from '@teable/core';\nimport { FieldType } from '@teable/core';\nimport type { Knex } "
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/sort-query.function.ts",
    "chars": 356,
    "preview": "import { AbstractSortFunction } from '../function/sort-function.abstract';\n\nexport class SortFunctionSqlite extends Abst"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sort-query/sqlite/sort-query.sqlite.ts",
    "chars": 2190,
    "preview": "import type { FieldCore } from '@teable/core';\nimport type { IRecordQuerySortContext } from '../../../features/record/qu"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/sqlite.provider.ts",
    "chars": 25320,
    "preview": "/* eslint-disable sonarjs/no-duplicate-string */\nimport { Logger } from '@nestjs/common';\nimport type {\n  IFilter,\n  ILo"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/utils/datetime-format.util.ts",
    "chars": 436,
    "preview": "export {\n  DATETIME_FORMAT_SQL_BUILDERS,\n  DATETIME_FORMAT_TOKEN_TO_POSTGRES,\n  DEFAULT_DATETIME_FORMAT_EXPR,\n  DEFAULT_"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/utils/default-datetime-parse-pattern.spec.ts",
    "chars": 1270,
    "preview": "import { describe, expect, it } from 'vitest';\n\nimport { getDefaultDatetimeParsePattern } from './default-datetime-parse"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/utils/default-datetime-parse-pattern.ts",
    "chars": 989,
    "preview": "/**\n * Shared default pattern used to guard DATETIME_PARSE inputs.\n * The expression must not contain any literal '?' ch"
  },
  {
    "path": "apps/nestjs-backend/src/db-provider/utils/formula-param-metadata.util.ts",
    "chars": 3760,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport { DbFieldType } from '@teable/core';\nimport type { Form"
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/decorators/emit-controller-event.decorator.ts",
    "chars": 634,
    "preview": "/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/naming-convention */\nimport"
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/event-emitter.module.ts",
    "chars": 2150,
    "preview": "/* eslint-disable @typescript-eslint/naming-convention */\nimport type { DynamicModule } from '@nestjs/common';\nimport { "
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/event-emitter.service.ts",
    "chars": 13073,
    "preview": "import { Injectable, Logger } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport type "
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/event-job/event-job.module.ts",
    "chars": 1234,
    "preview": "import { BullModule } from '@nestjs/bullmq';\nimport type { NestWorkerOptions } from '@nestjs/bullmq/dist/interfaces/work"
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/event-job/fallback/event-emitter.ts",
    "chars": 94,
    "preview": "import EventEmitter from 'events';\n\nexport const localQueueEventEmitter = new EventEmitter();\n"
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/event-job/fallback/fallback-queue.module.ts",
    "chars": 686,
    "preview": "import type { DynamicModule } from '@nestjs/common';\nimport { Module } from '@nestjs/common';\nimport { DiscoveryService "
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/event-job/fallback/fallback-queue.service.ts",
    "chars": 2317,
    "preview": "import type { OnModuleInit } from '@nestjs/common';\nimport { Injectable, Logger } from '@nestjs/common';\nimport { Reflec"
  },
  {
    "path": "apps/nestjs-backend/src/event-emitter/event-job/fallback/local-queue.provider.ts",
    "chars": 848,
    "preview": "import { getQueueToken } from '@nestjs/bullmq';\nimport type { Provider } from '@nestjs/common';\nimport { getRandomString"
  }
]

// ... and 6359 more files (download for full content)

About this extraction

This page contains the full source code of the teableio/teable GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 6559 files (34.9 MB), approximately 4.4M tokens, and a symbol index with 9517 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!