Browse Source

0.91.8 Pre-release (#2350)

* add vscode ide's ignore list

* fix passing nested query in nested getAst calls

* chore: update nocodb-sdk to local path

* fix: ignore duplicating app config

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: swagger columnNameParam type

re: #2208
Signed-off-by: mertmit <mertmit99@gmail.com>

* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

* enhancement: hide slider on escape key

Signed-off-by: Pranav C <pranavxc@gmail.com>

* Add information about maximum value for `limit` in REST API

* refactor: folder structure

* refactor: folder structure

* test: webhook (WIP)

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: webhook

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test/cypress: corrections post develop branch refactoring

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: handle null

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: path correction

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: assign validation for correct column(LTAR)

re #2228

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: disable api docs access for viewer role

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* docs: Repair broken link

* fix: DatePickerCell invalid date handling

Signed-off-by: mertmit <mertmit99@gmail.com>

* fix: nested insert correction in belongs to

re #2228

Signed-off-by: Pranav C <pranavxc@gmail.com>

* feat: compare with non-os products

Signed-off-by: mertmit <mertmit99@gmail.com>

* fix: Persian language moving across table

Signed-off-by: mertmit <mertmit99@gmail.com>

* docs: env variables

* docs: env variables reorder

* docs: env variables reorder

* fix: i18n corrections (WeT-Klb)

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* chore: image text corrections (@WeT-Klb)

* chore: upgrade nc-help

Signed-off-by: Pranav C <pranavxc@gmail.com>

* docs: security.md

* Update packages/nocodb/src/lib/noco/meta/api/swagger/helpers/templates/params.ts

Co-authored-by: աɨռɢӄաօռɢ <wingkwong.code@gmail.com>

* Update SqliteUi.ts - set float for decimal case in getAbstractType (#2260)

* set float for decimal case in getAbstractType

* fix: add cross-env to nc-gui package.json (#2275)

* add cross-env to nc-gui package.json

* fix: sanitize project title

* chore: disable pr release for draft

* chore: attachment log during airtable import

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* modification of the traduction

I aslo add some stuff according to the README (it was a different display so i didn't add a lot)

* docs: update README.md [skip ci]

* docs: update .all-contributorsrc [skip ci]

* fix: change password cache logic

* fix: add missing job name back

* fix: prop types for FlipCard component

Signed-off-by: mertmit <mertmit99@gmail.com>

* fix: invalid char in content-disposition header

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: question mark in CONCAT

* fix: handling lookup column reference in formula

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: throw err if user is already a project user

* chore: revise error msg

* fix: package lock corrections

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test/ trigger

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: lock file version

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: package lock after npm/node upgrade

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* fix: cypress package lock json

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* test: lock node-version to 16.15.0

Signed-off-by: Raju Udava <86527202+dstala@users.noreply.github.com>

* enhancement: allow custom limit values

* chore: update query limit description

* chore: bump to 16.15.0

* fix: node version

* fix: handle invalid limit numbers

Signed-off-by: Pranav C <pranavxc@gmail.com>

* docs: update default value of pagination max limit value

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: pg database type money

Signed-off-by: mertmit <mertmit99@gmail.com>

* fix: hasmany pagination - api correction

re #2242

Signed-off-by: Pranav C <pranavxc@gmail.com>

* script: add nc_017_add_user_token_exp_column

* fix: add token_expired

* fix: return unauthorized if token is expired

* chore: revise toast message

* chore: sign out n redirect to sign in page after changing password

* fix: SingeSelect/MultiSelect webhook trigger (#2309)

* fix: SingleSelect webhook trigger

Signed-off-by: mertmit <mertmit99@gmail.com>

* fix: MultiSelect webhook trigger

Signed-off-by: mertmit <mertmit99@gmail.com>

* Fix: Remove user reference from webhook context (#2337)

* fix: remove user info from webhook handlebar context

Signed-off-by: Pranav C <pranavxc@gmail.com>

* docs: update webhook context variables docs

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: only check token_expired in non-public base

* fix: make rating readonly in lookup column (#2340)

re #2045

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: exclude sensitive data related to server from SMTP test api

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: session across broswers

* fix: reload related table metadata after relation column delete (#2345)

re #2344

Signed-off-by: Pranav C <pranavxc@gmail.com>

* Fix: Sanitise comment data  (#2343)

* fix: sanitise row comment description

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: add dom purify and sanitize content

- Add DOMPurify in nuxt
- On update value encode html tags to render as text in comment

Signed-off-by: Pranav C <pranavxc@gmail.com>

* fix: add missing dependency

Signed-off-by: Pranav C <pranavxc@gmail.com>

Co-authored-by: cattong <tangym@jifenbang.net>
Co-authored-by: LepkoQQ <LepkoQQ@users.noreply.github.com>
Co-authored-by: Pranav C <pranavxc@gmail.com>
Co-authored-by: mertmit <mertmit99@gmail.com>
Co-authored-by: navi <oof1lab@gmail.com>
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
Co-authored-by: Nils Reichardt <nils@reichardt.io>
Co-authored-by: Raju Udava <86527202+dstala@users.noreply.github.com>
Co-authored-by: Toon van Ramshorst <ramshorst@gmail.com>
Co-authored-by: GurukiranMH <89529565+GurukiranMH@users.noreply.github.com>
Co-authored-by: QuentinDstl <qdesautel@gmail.com>
pull/2351/head 0.91.8
աɨռɢӄաօռɢ 3 years ago committed by GitHub
parent
commit
b2f8f0674e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      .all-contributorsrc
  2. 24
      .github/workflows/ci-cd.yml
  3. 5
      .github/workflows/release-docker.yml
  4. 7
      .github/workflows/release-npm.yml
  5. 13
      .github/workflows/release-pr.yml
  6. 3
      .github/workflows/update-sdk-path.yml
  7. 4
      .gitignore
  8. 2
      .run/Clear metadb.run.xml
  9. 2
      README.md
  10. 7
      SECURITY.md
  11. 24322
      package-lock.json
  12. 1
      package.json
  13. 2
      packages/nc-gui/components/ProjectTreeView.vue
  14. 4
      packages/nc-gui/components/apiClient/Headers.vue
  15. 15
      packages/nc-gui/components/global/NcSlider.vue
  16. 5
      packages/nc-gui/components/project/spreadsheet/RowsXcDataTable.vue
  17. 8
      packages/nc-gui/components/project/spreadsheet/components/EditableCell.vue
  18. 7
      packages/nc-gui/components/project/spreadsheet/components/ExpandedForm.vue
  19. 111
      packages/nc-gui/components/project/spreadsheet/components/FlipCard.vue
  20. 44
      packages/nc-gui/components/project/spreadsheet/components/SpreadsheetNavDrawer.vue
  21. 5
      packages/nc-gui/components/project/spreadsheet/components/VirtualHeaderCell.vue
  22. 7
      packages/nc-gui/components/project/spreadsheet/components/cell/CurrencyCell.vue
  23. 23
      packages/nc-gui/components/project/spreadsheet/components/editColumn/CurrencyOptions.vue
  24. 12
      packages/nc-gui/components/project/spreadsheet/components/editableCell/DatePickerCell.vue
  25. 1
      packages/nc-gui/components/project/spreadsheet/components/editableCell/EnumListEditableCell.vue
  26. 2
      packages/nc-gui/components/project/spreadsheet/components/editableCell/RatingCell.vue
  27. 1
      packages/nc-gui/components/project/spreadsheet/components/editableCell/SetListEditableCell.vue
  28. 5
      packages/nc-gui/components/project/spreadsheet/helpers/getPlainText.js
  29. 2
      packages/nc-gui/components/project/spreadsheet/helpers/imageExt.js
  30. 25
      packages/nc-gui/components/project/spreadsheet/public/XcForm.vue
  31. 15
      packages/nc-gui/components/project/spreadsheet/views/GridView.vue
  32. 6
      packages/nc-gui/components/project/tableTabs/webhook/HttpWebhook.vue
  33. 11
      packages/nc-gui/components/project/tableTabs/webhook/WebhookEditor.vue
  34. 2
      packages/nc-gui/components/project/tableTabs/webhook/WebhookList.vue
  35. 2
      packages/nc-gui/components/project/tableTabs/webhook/WebhookSlider.vue
  36. 3
      packages/nc-gui/helpers/rolePermissionsEE.js
  37. 18
      packages/nc-gui/lang/de.json
  38. 4
      packages/nc-gui/nuxt.config.js
  39. 13103
      packages/nc-gui/package-lock.json
  40. 12
      packages/nc-gui/package.json
  41. 4
      packages/nc-gui/pages/user/settings/index.vue
  42. 2
      packages/nc-gui/plugins/axiosInterceptor.js
  43. 4
      packages/nc-gui/plugins/domPurify.js
  44. 14
      packages/nc-gui/store/project.js
  45. 6
      packages/noco-docs-prev/content/en/getting-started/installation.md
  46. 8
      packages/noco-docs/content/en/developer-resources/webhooks.md
  47. 30
      packages/noco-docs/content/en/getting-started/installation.md
  48. 2
      packages/noco-docs/content/en/index.md
  49. 30
      packages/noco-docs/content/en/setup-and-usages/usage-information.md
  50. 17
      packages/nocodb-sdk/src/lib/Api.ts
  51. 1
      packages/nocodb-sdk/src/lib/sqlUi/SqliteUi.ts
  52. 2
      packages/nocodb/docker/index.js
  53. 1097
      packages/nocodb/package-lock.json
  54. 31
      packages/nocodb/package.json
  55. 2
      packages/nocodb/src/__tests__/TemplateParser.test.ts
  56. 4
      packages/nocodb/src/__tests__/formula.test.ts
  57. 18
      packages/nocodb/src/__tests__/graphql.test.ts
  58. 30
      packages/nocodb/src/lib/Noco.ts
  59. 0
      packages/nocodb/src/lib/cache/CacheMgr.ts
  60. 0
      packages/nocodb/src/lib/cache/NocoCache.ts
  61. 0
      packages/nocodb/src/lib/cache/RedisCacheMgr.ts
  62. 0
      packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts
  63. 0
      packages/nocodb/src/lib/db/sql-data-mapper/README.md
  64. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/conditionClause.test.js
  65. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/conditionGraph.test.js
  66. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/city.meta.js
  67. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/city.model.js
  68. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/country.meta.js
  69. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/country.model.js
  70. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/film.meta.js
  71. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/film.model.js
  72. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/index.js
  73. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/sql.test.js
  74. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/whereClause.test.js
  75. 0
      packages/nocodb/src/lib/db/sql-data-mapper/__tests__/xSelect.test.js
  76. 0
      packages/nocodb/src/lib/db/sql-data-mapper/index.ts
  77. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts
  78. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/DbFactory.ts
  79. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts
  80. 55
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  81. 2
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts
  82. 16
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts
  83. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/customValidators.ts
  84. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulaQueryBuilderFromString.ts
  85. 16
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts
  86. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/commonFns.ts
  87. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts
  88. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mysql.ts
  89. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts
  90. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts
  91. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelect.ts
  92. 6
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelectv2.ts
  93. 8
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/helpers/getAst.ts
  94. 0
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/mapFunctionName.ts
  95. 12
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts
  96. 0
      packages/nocodb/src/lib/db/sql-mgr/ProjectMgr.ts
  97. 8
      packages/nocodb/src/lib/db/sql-mgr/SqlMgr.ts
  98. 6
      packages/nocodb/src/lib/db/sql-mgr/code/BaseRender.ts
  99. 2
      packages/nocodb/src/lib/db/sql-mgr/code/gql-policies/xc-ts/ExpressXcTsPolicyGql.ts
  100. 0
      packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/BaseGqlXcTsSchema.ts
  101. Some files were not shown because too many files have changed in this diff Show More

18
.all-contributorsrc

@ -783,6 +783,24 @@
"contributions": [
"code"
]
},
{
"login": "LepkoQQ",
"name": "LepkoQQ",
"avatar_url": "https://avatars.githubusercontent.com/u/2662937?v=4",
"profile": "https://github.com/LepkoQQ",
"contributions": [
"code"
]
},
{
"login": "QuentinDstl",
"name": "quentin",
"avatar_url": "https://avatars.githubusercontent.com/u/56829191?v=4",
"profile": "https://cornernewclub.fr",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,

24
.github/workflows/ci-cd.yml

@ -25,7 +25,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -70,7 +70,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -115,7 +115,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -160,7 +160,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -205,7 +205,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -250,7 +250,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -295,7 +295,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -340,7 +340,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -385,7 +385,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -430,7 +430,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -475,7 +475,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:
@ -520,7 +520,7 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: 16
node-version: 16.15.0
- name: Checkout
uses: actions/checkout@v2
with:

5
.github/workflows/release-docker.yml

@ -44,9 +44,6 @@ jobs:
runs-on: ubuntu-latest
env:
working-directory: ./packages/nocodb
strategy:
matrix:
node-version: [16]
steps:
- name: Get Docker Repository
id: get-docker-repository
@ -77,7 +74,7 @@ jobs:
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
node-version: 16.15.0
- name: upgrade packages for nightly build or pr build
if: ${{ github.event.inputs.targetEnv == 'DEV' || inputs.targetEnv == 'DEV' }}

7
.github/workflows/release-npm.yml

@ -35,20 +35,17 @@ jobs:
runs-on: ubuntu-latest
env:
working-directory: ./packages/nocodb
strategy:
matrix:
node-version: [16]
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
ref: ${{ github.ref }}
- name: NPM Setup and Publish with ${{ matrix.node-version }}
- name: NPM Setup and Publish with 16.15.0
# Setup .npmrc file to publish to npm
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
node-version: 16.15.0
registry-url: 'https://registry.npmjs.org'
- run: |
targetEnv=${{ github.event.inputs.targetEnv || inputs.targetEnv }} targetVersion=${{ github.event.inputs.tag || inputs.tag }} node scripts/bumpNocodbSdkVersion.js &&

13
.github/workflows/release-pr.yml

@ -5,7 +5,8 @@ on:
# opened: pull request is created
# reopened: closed pull request is reopened
# synchronize: commit(s) pushed to the pull request
types: [opened, reopened, synchronize]
# ready_for_review: non PR release
types: [opened, reopened, synchronize, ready_for_review]
paths:
- "packages/nocodb-sdk/**"
- "packages/nc-gui/**"
@ -14,7 +15,7 @@ on:
jobs:
# Validate Branch
validate-branch:
if: ${{ github.actor != 'dependabot[bot]' }}
if: ${{ github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
steps:
- run: |
@ -25,7 +26,7 @@ jobs:
# enrich tag for pr release
set-tag:
if: ${{ github.actor != 'dependabot[bot]' }}
if: ${{ github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false }}
runs-on: 'ubuntu-latest'
needs: [validate-branch]
steps:
@ -53,7 +54,7 @@ jobs:
# Build, install, publish frontend and backend to npm
release-npm:
if: ${{ github.actor != 'dependabot[bot]' }}
if: ${{ github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false }}
needs: [set-tag]
uses: ./.github/workflows/release-npm.yml
with:
@ -64,7 +65,7 @@ jobs:
# Build docker image and push to docker hub
release-docker:
if: ${{ github.actor != 'dependabot[bot]' }}
if: ${{ github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false }}
needs: [release-npm, set-tag]
uses: ./.github/workflows/release-docker.yml
with:
@ -84,7 +85,7 @@ jobs:
# echo docker run -d -p 8888:8080 nocodb/nocodb-timely:${{ needs.set-tag.outputs.current_version }}-${{ needs.set-tag.outputs.target_tag }}
leave-comment:
if: ${{ github.actor != 'dependabot[bot]' }}
if: ${{ github.actor != 'dependabot[bot]' && github.event.pull_request.draft == false }}
runs-on: 'ubuntu-latest'
needs: [release-docker, set-tag]
steps:

3
.github/workflows/update-sdk-path.yml

@ -8,9 +8,6 @@ on:
jobs:
release:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16]
steps:
- name: Checkout
uses: actions/checkout@v2

4
.gitignore vendored

@ -44,6 +44,10 @@ logs/
build/
uploads/
# Visual Studio Code
# =========
.vscode
# Sublime editor
# ==============
.sublime-project

2
.run/Clear metadb.run.xml

@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Drop metadb" type="NodeJSConfigurationType" path-to-js-file="deleteMetaDb.js" working-dir="$PROJECT_DIR$/packages/nocodb/src/example">
<configuration default="false" name="Drop metadb" type="NodeJSConfigurationType" path-to-js-file="$PROJECT_DIR$/packages/nocodb/src/run/deleteMetaDb.js" working-dir="$PROJECT_DIR$/packages/nocodb/src/run">
<method v="2" />
</configuration>
</component>

2
README.md

@ -473,6 +473,8 @@ Our mission is to provide the most powerful no-code interface for databases whic
<tr>
<td align="center"><a href="https://www.youyi.io"><img src="https://avatars.githubusercontent.com/u/49471274?v=4?s=100" width="100px;" alt=""/><br /><sub><b>youyiio</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=youyiio" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/RK311y"><img src="https://avatars.githubusercontent.com/u/65210753?v=4?s=100" width="100px;" alt=""/><br /><sub><b>River Kelly</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=RK311y" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/LepkoQQ"><img src="https://avatars.githubusercontent.com/u/2662937?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LepkoQQ</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=LepkoQQ" title="Code">💻</a></td>
<td align="center"><a href="https://cornernewclub.fr"><img src="https://avatars.githubusercontent.com/u/56829191?v=4?s=100" width="100px;" alt=""/><br /><sub><b>quentin</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=QuentinDstl" title="Code">💻</a></td>
</tr>
</table>

7
SECURITY.md

@ -0,0 +1,7 @@
# Security Policy
### Reporting a Vulnerability
Please report (suspected) security vulnerabilities to security@nocodb.com
- You will receive a response from us within 3 working days.
- If the issue is confirmed, we will release a patch as soon as possible depending on complexity but historically within a few days.

24322
package-lock.json generated

File diff suppressed because it is too large Load Diff

1
package.json

@ -33,6 +33,7 @@
"stop:pg": "docker-compose -f ./scripts/cypress/docker-compose-pg.yml down"
},
"dependencies": {
"express": "^4.18.1",
"mysql2": "^2.3.3",
"pg": "^8.7.3",
"sqlite3": "^5.0.2"

2
packages/nc-gui/components/ProjectTreeView.vue

@ -681,6 +681,7 @@
</div>
<v-divider />
<template v-if="_isUIAllowed('apiDocs')">
<div
v-t="['e:api-docs']"
class="caption pointer nc-docs pb-2 pl-5 pr-3 pt-2 d-flex align-center"
@ -691,6 +692,7 @@
</v-icon>
{{ $t('title.apiDocs') }}
</div>
</template>
<template v-if="_isUIAllowed('settings')">
<div class="pl-5 pr-3 d-flex align-center pb-2">

4
packages/nc-gui/components/apiClient/Headers.vue

@ -32,7 +32,7 @@
<v-combobox
v-model="item.name"
v-ge="['api-client-headers','enable']"
class="body-2 caption"
class="body-2 caption nc-input-hook-header-key"
:items="headerListAuto"
:disabled="!item.enabled"
hide-details
@ -46,7 +46,7 @@
<td style="height: auto">
<xAutoComplete
v-model="item.value"
class="body-2 caption"
class="body-2 caption nc-input-hook-header-value"
:disabled="!item.enabled"
placeholder="Value"
hide-details

15
packages/nc-gui/components/global/NcSlider.vue

@ -26,9 +26,22 @@ export default {
mounted() {
(document.querySelector('[data-app]') || this.$root.$el).append(this.$el)
},
destroyed() {
this.$el.parentNode && this.$el.parentNode.removeChild(this.$el)
},
created() {
document.body.addEventListener('keyup', this.onKeyup, true)
},
beforeDestroy() {
document.body.removeEventListener('keyup', this.onKeyup, true)
},
methods: {
onKeyup(e) {
if (e.key === 'Escape') {
this.modal = false
}
}
}
}
</script>

5
packages/nc-gui/components/project/spreadsheet/RowsXcDataTable.vue

@ -755,6 +755,7 @@ import Pagination from '~/components/project/spreadsheet/components/Pagination'
import ColumnFilter from '~/components/project/spreadsheet/components/ColumnFilterMenu'
import MoreActions from '~/components/project/spreadsheet/components/MoreActions'
import ShareViewMenu from '~/components/project/spreadsheet/components/ShareViewMenu'
import getPlainText from '~/components/project/spreadsheet/helpers/getPlainText'
export default {
name: 'RowsXcDataTable',
@ -1217,8 +1218,8 @@ export default {
fk_model_id: this.meta.id,
column_name: column.title,
row_id: id,
value: rowObj[column.title],
prev_value: oldRow[column.title]
value: getPlainText(rowObj[column.title]),
prev_value: getPlainText(oldRow[column.title])
})
.then(() => {})

8
packages/nc-gui/components/project/spreadsheet/components/EditableCell.vue

@ -86,6 +86,7 @@
:is-form="isForm"
:column="column"
v-on="parentListeners"
@input="$emit('save')"
/>
<json-editable-cell
@ -101,6 +102,7 @@
v-model="localState"
:column="column"
v-on="parentListeners"
@input="$emit('save')"
/>
<set-list-cell
v-else-if="isSet"
@ -197,9 +199,9 @@ export default {
if (val !== this.value) {
this.changed = true
this.$emit('input', val)
if (this.isAttachment || this.isEnum || this.isBoolean || this.isRating || this.isSet || this.isTime || this.isDateTime || this.isDate) {
if (this.isAttachment || this.isBoolean || this.isRating || this.isTime || this.isDateTime || this.isDate) {
this.syncData()
} else if (!this.isCurrency) {
} else if (!this.isCurrency && !this.isEnum && !this.isSet) {
this.syncDataDebounce(this)
}
}
@ -228,7 +230,7 @@ export default {
// this.$refs.input.focus();
},
beforeDestroy() {
if (this.changed && !(this.isAttachment || this.isEnum || this.isBoolean || this.isRating || this.isSet || this.isTime || this.isDateTime)) {
if (this.changed && !(this.isAttachment || this.isBoolean || this.isRating || this.isTime || this.isDateTime)) {
this.changed = false
this.$emit('change')
}

7
packages/nc-gui/components/project/spreadsheet/components/ExpandedForm.vue

@ -242,9 +242,9 @@
<p
v-else
v-dompurify-html="log.details"
class="caption mb-0"
style="word-break: break-all"
v-html="log.details"
/>
<p class="time text-right mb-0">
@ -329,6 +329,7 @@ import EditableCell from '~/components/project/spreadsheet/components/EditableCe
import colors from '@/mixins/colors'
import VirtualCell from '~/components/project/spreadsheet/components/VirtualCell'
import VirtualHeaderCell from '~/components/project/spreadsheet/components/VirtualHeaderCell'
import getPlainText from '~/components/project/spreadsheet/helpers/getPlainText'
const relativeTime = require('dayjs/plugin/relativeTime')
const utc = require('dayjs/plugin/utc')
@ -555,8 +556,8 @@ export default {
fk_model_id: this.meta.id,
column_name: key,
row_id: id,
value: updatedObj[key],
prev_value: this.oldRow[key]
value: getPlainText(updatedObj[key]),
prev_value: getPlainText(this.oldRow[key])
})
.then(() => {
})

111
packages/nc-gui/components/project/spreadsheet/components/FlipCard.vue

@ -0,0 +1,111 @@
<template>
<div
class="flip-card"
:style="{ height, width }"
@click="handleClick"
@mouseover="handleHover(true)"
@mouseleave="handleHover(false)"
>
<div class="flipper" :style="{ transform: flipped ? 'rotateY(180deg)' : '' }">
<div class="front" :style="{ 'pointer-events': flipped ? 'none' : 'auto' }">
<slot name="front" />
</div>
<div class="back" :style="{ 'pointer-events': flipped ? 'auto' : 'none' }">
<slot name="back" />
</div>
</div>
</div>
</template>
<script>
export default {
name: 'FlipCard',
props: {
width: {
type: String,
required: true
},
height: {
type: String,
required: true
},
onHover: {
type: Boolean,
default: true
},
onClick: {
type: Boolean,
default: false
},
onTime: {
type: Number,
default: 0
}
},
data: () => ({
flipped: false,
hovered: false,
flipTimer: null
}),
mounted() {
if (this.onTime > 0) {
this.flipTimer = setInterval(() => {
if (!this.hovered) {
this.flipped = !this.flipped
}
}, this.onTime)
}
},
unmounted() {
if (this.flipTimer) {
clearInterval(this.flipTimer)
}
},
methods: {
handleHover(val) {
this.hovered = val
if (this.onHover) {
this.flipped = val
}
},
handleClick() {
if (this.onClick) {
this.flipped = !this.flipped
}
}
}
}
</script>
<style lang="scss" scoped>
.flip-card {
background-color: transparent;
perspective: 1000px;
}
.flipper {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.front, .back {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.front {
color: black;
}
.back {
color: black;
transform: rotateY(180deg);
}
</style>

44
packages/nc-gui/components/project/spreadsheet/components/SpreadsheetNavDrawer.vue

@ -294,7 +294,7 @@
class="caption d-100 mt-2"
@click="webhookSliderModal=true"
>
<v-icon small class="mr-2">
<v-icon small class="mr-2 nc-btn-webhook">
mdi-hook
</v-icon> Webhooks
</v-btn>
@ -308,23 +308,37 @@
<v-icon small class="close-icon" @click="hideMiniSponsorCard">
mdi-close-circle-outline
</v-icon>
<!-- <extras />-->
<v-divider class="mb-2" />
<extras class="pl-1" />
<flip-card width="100%" height="100px" :on-time="30 * 1000" :on-hover="false">
<template #front>
<extras class="pl-1 mt-1" />
<v-btn
v-t="['e:hiring']"
color="primary"
outlined
class="caption d-100 my-2 "
class="caption d-100 mt-4 "
href="https://angel.co/company/nocodb"
target="_blank"
>
🚀 We are Hiring! 🚀
</v-btn>
<!-- <sponsor-mini nav />-->
</template>
<template #back>
<span class="caption text-left body-1 textColor--text text--lighten-1">{{ supportCost }}</span>
<v-btn
color="primary"
class="caption d-100 my-2"
outlined
href="https://github.com/sponsors/nocodb"
target="_blank"
>
<v-icon small color="red" class="mr-2">
mdi-cards-heart
</v-icon>
{{ $t('activity.sponsorUs') }}
</v-btn>
</template>
</flip-card>
</div>
</div>
</v-container>
@ -443,10 +457,11 @@ import { copyTextToClipboard } from '~/helpers/xutils'
import SponsorMini from '~/components/SponsorMini'
import CodeSnippet from '~/components/project/spreadsheet/components/CodeSnippet'
import WebhookSlider from '~/components/project/tableTabs/webhook/WebhookSlider'
import FlipCard from '~/components/project/spreadsheet/components/FlipCard'
export default {
name: 'SpreadsheetNavDrawer',
components: { WebhookSlider, CodeSnippet, SponsorMini, Extras, CreateViewDialog, draggable },
components: { WebhookSlider, CodeSnippet, SponsorMini, Extras, CreateViewDialog, draggable, FlipCard },
props: {
extraViewParams: Object,
showAdvanceOptions: Boolean,
@ -570,6 +585,13 @@ export default {
viewType = 'view'
}
return `${this.dashboardUrl}#/nc/${viewType}/${this.shareLink.uuid}`
},
supportCost() {
const cost = parseInt(this.$store.getters['project/GtrProjectCost'])
if (cost > 0) {
return `This costs ~$${cost}/year in non-open source products.`
}
return 'Your donations will help us to make this product better.'
}
},
watch: {
@ -953,8 +975,8 @@ export default {
.close-icon {
position: absolute;
right: 10px;
top: 10px;
right: 4px;
top: 12px;
z-index: 9;
opacity: 0;
transition: 0.4s opacity;

5
packages/nc-gui/components/project/spreadsheet/components/VirtualHeaderCell.vue

@ -252,6 +252,11 @@ export default {
async deleteColumn() {
try {
await this.$api.dbTableColumn.delete(this.column.id)
if (this.column.uidt === UITypes.LinkToAnotherRecord && this.column.colOptions) {
this.$store.dispatch('meta/ActLoadMeta', { force: true, id: this.column.colOptions.fk_related_model_id }).then(() => {})
}
this.$emit('saved')
this.columnDeleteDialog = false
} catch (e) {

7
packages/nc-gui/components/project/spreadsheet/components/cell/CurrencyCell.vue

@ -13,8 +13,11 @@ export default {
computed: {
currency() {
try {
return new Intl.NumberFormat(this.currencyMeta.currency_locale || 'en-US',
{ style: 'currency', currency: this.currencyMeta.currency_code || 'USD' }).format(this.value)
return isNaN(this.value)
? this.value
: new Intl.NumberFormat(this.currencyMeta.currency_locale || 'en-US',
{ style: 'currency', currency: this.currencyMeta.currency_code || 'USD' })
.format(this.value)
} catch (e) {
return this.value
}

23
packages/nc-gui/components/project/spreadsheet/components/editColumn/CurrencyOptions.vue

@ -1,5 +1,7 @@
<template>
<v-row class="currency-wrapper">
<v-tooltip top :disabled="!(isMoney && isPG)">
<template #activator="{ on, attrs }">
<v-row class="currency-wrapper" v-bind="attrs" v-on="on">
<v-col cols="6">
<!--label="Format Locale"-->
<v-autocomplete
@ -11,6 +13,7 @@
:items="currencyLocaleList"
outlined
hide-details
:disabled="isMoney && isPG"
/>
</v-col>
<v-col cols="6">
@ -24,10 +27,14 @@
:items="currencyList"
outlined
hide-details
:disabled="isMoney && isPG"
/>
</v-col>
</v-row>
</template>
<span>{{ message }}</span>
</v-tooltip>
</template>
<script>
import { currencyCodes, currencyLocales, validateCurrencyCode, validateCurrencyLocale } from '~/helpers/currencyHelper'
@ -49,6 +56,20 @@ export default {
return validateCurrencyCode(value) || 'Invalid Currency Code'
}
}),
computed: {
isMoney() {
return this.column.dt === 'money'
},
isPG() {
return ['pg'].includes(this.$store.getters['project/GtrClientType'])
},
message() {
if (this.isMoney && this.isPG) {
return "PostgreSQL 'money' type has own currency settings"
}
return ''
}
},
watch: {
value() {
this.colMeta = this.value || {}

12
packages/nc-gui/components/project/spreadsheet/components/editableCell/DatePickerCell.vue

@ -1,7 +1,7 @@
<template>
<v-menu>
<template #activator="{on}">
<input v-model="localState" class="value" v-on="on">
<input :value="date" class="value" v-on="on">
</template>
<v-date-picker
v-model="localState"
@ -23,13 +23,21 @@ export default {
computed: {
localState: {
get() {
if (!this.value) { return this.value }
if (!this.value || !dayjs(this.value).isValid()) { return undefined }
return (/^\d+$/.test(this.value) ? dayjs(+this.value) : dayjs(this.value)).format('YYYY-MM-DD')
},
set(val) {
if (dayjs(val).isValid()) {
this.$emit('input', val && dayjs(val).format('YYYY-MM-DD'))
}
}
},
date() {
if (!this.value || this.localState) {
return this.localState
}
return 'Invalid Date'
},
parentListeners() {
const $listeners = {}

1
packages/nc-gui/components/project/spreadsheet/components/editableCell/EnumListEditableCell.vue

@ -54,7 +54,6 @@ export default {
},
set(val) {
this.$emit('input', val)
this.$emit('update')
}
},
enumValues() {

2
packages/nc-gui/components/project/spreadsheet/components/editableCell/RatingCell.vue

@ -5,7 +5,7 @@
:length="ratingMeta.max"
dense
x-small
:disabled="readOnly"
:readonly="readOnly"
clearable
>
<template #item="{isFilled, click}">

1
packages/nc-gui/components/project/spreadsheet/components/editableCell/SetListEditableCell.vue

@ -57,7 +57,6 @@ export default {
},
set(val) {
this.$emit('input', val.filter(v => this.setValues.includes(v)).join(','))
this.$emit('update')
}
},
setValues() {

5
packages/nc-gui/components/project/spreadsheet/helpers/getPlainText.js

@ -0,0 +1,5 @@
export default function getPlainText(htmlString) {
const div = document.createElement('div')
div.textContent = htmlString || ''
return div.innerHTML
}

2
packages/nc-gui/components/project/spreadsheet/helpers/imageExt.js

@ -13,7 +13,7 @@ const imageExt = [
export default imageExt
const isImage = (name, type) => {
return imageExt.some(e => name.toLowerCase().endsWith(`.${e}`)) || (type || '').startsWith('image/')
return imageExt.some(e => (name && name.toLowerCase().endsWith(`.${e}`))) || (type || '').startsWith('image/')
}
export { isImage }

25
packages/nc-gui/components/project/spreadsheet/public/XcForm.vue

@ -128,18 +128,6 @@
>
Field is required.
</div>
<!-- todo: optimize -->
<template
v-if="col.bt && $v.localState && $v.localState.$dirty && $v.localState[meta.columns.find(c => c.column_name === col.bt.column_name).title]"
>
<div
v-if="!$v.localState[meta.columns.find(c => c.column_name === col.bt.column_name).title].required"
class="error--text caption"
>
Field is required.
</div>
</template>
</div>
<template v-else>
<div
@ -270,6 +258,17 @@ export default {
},
computed: {
btColumnsRefs() {
return (this.columns || []).reduce((aggObj, column) => {
if (column.uidt === UITypes.LinkToAnotherRecord && column.colOptions && column.colOptions.type === RelationTypes.BELONGS_TO) {
const col = this.meta.columns.find(c => c.id === column.colOptions.fk_child_column_id)
aggObj[column.title] = col
}
return aggObj
}, {})
},
sqlUiLoc() {
// todo: replace with correct client
return this.client && SqlUiFactory.create({ client: this.client })
@ -376,7 +375,7 @@ export default {
const col = this.meta.columns.find(c => c.id === column.colOptions.fk_child_column_id)
if ((col && col.rqd && !col.cdf) || column.required) {
obj.localState[col.title] = { required }
if (col) { obj.virtual[column.title] = { required } }
}
} else if (isVirtualCol(column) && column.required) {
obj.virtual[column.title] = {

15
packages/nc-gui/components/project/spreadsheet/views/GridView.vue

@ -390,7 +390,8 @@ export default {
aggCount: [],
dragOver: false,
gridViewCols: {},
unsaved: false
unsaved: false,
rightToLeftLanguages: ['fa']
}),
computed: {
selectAll: {
@ -660,13 +661,21 @@ export default {
break
// left
case 37:
if (this.selected.col > 0) {
if (this.rightToLeftLanguages.includes(this.$store.state.settings.language)) {
if (this.selected.col < this.colLength - 1) {
this.selected.col++
}
} else if (this.selected.col > 0) {
this.selected.col--
}
break
// right
case 39:
if (this.selected.col < this.colLength - 1) {
if (this.rightToLeftLanguages.includes(this.$store.state.settings.language)) {
if (this.selected.col > 0) {
this.selected.col--
}
} else if (this.selected.col < this.colLength - 1) {
this.selected.col++
}
break

6
packages/nc-gui/components/project/tableTabs/webhook/HttpWebhook.vue

@ -5,7 +5,7 @@
v-model="api.method"
outlined
dense
class="caption"
class="caption nc-select-hook-url-method"
:items="Object.keys(apiMethodMeta)"
style="max-width:100px;"
/>
@ -14,7 +14,7 @@
outlined
placeholder="http://example.com"
dense
class="flex-grow-1 ml-2 caption"
class="flex-grow-1 ml-2 caption nc-text-field-hook-url-path"
/>
</div>
@ -33,7 +33,7 @@
>({{ paramsCount }})</b></span>
</v-tab>
<v-tab v-ge="['api-client','headers']" class="caption">
<span class="text-capitalize">Headers&nbsp;<b
<span class="text-capitalize nc-tab-hook-header">Headers&nbsp;<b
v-if="headersCount"
class="green--text"
>({{

11
packages/nc-gui/components/project/tableTabs/webhook/WebhookEditor.vue

@ -2,7 +2,7 @@
<v-form v-if="hook" ref="form" v-model="valid" class="mx-4" lazy-validation>
<div>
<a class="pointer mx-4" @click="$emit('backToList')">
<v-icon class="ml-n1">mdi-arrow-left-bold</v-icon>
<v-icon class="ml-n1 nc-icon-hook-navigate-left">mdi-arrow-left-bold</v-icon>
</a>
</div>
<v-card-title>
@ -15,6 +15,7 @@
outlined
tooltip="Save"
small
class="nc-btn-webhook-test"
:disabled="loading || !valid || !hook.event"
@click.prevent="$refs.webhookTest.testWebhook()"
>
@ -24,6 +25,7 @@
tooltip="Save"
color="primary"
small
class="nc-btn-webhook-save"
:disabled="loading || !valid || !hook.event"
@click.prevent="saveHooks"
>
@ -39,7 +41,7 @@
<v-card-text>
<v-text-field
v-model="hook.title"
class="caption"
class="caption nc-text-field-hook-title"
outlined
dense
:label="$t('general.title')"
@ -49,6 +51,7 @@
<v-row>
<v-col>
<webhook-event
class="nc-text-field-hook-event"
:event.sync="hook.event"
:operation.sync="hook.operation"
/>
@ -61,7 +64,7 @@
required
:items="notificationList"
:rules="[(v) => !!v || `${$t('general.required')}`]"
class="caption"
class="caption nc-text-field-hook-notification-type"
:prepend-inner-icon="notificationIcon[hook.notification.type]"
@change="onNotTypeChange"
>
@ -178,7 +181,7 @@
v-model="hook.condition"
dense
hide-details
class="mt-1"
class="mt-1 nc-check-box-hook-condition"
label="On Condition"
/>

2
packages/nc-gui/components/project/tableTabs/webhook/WebhookList.vue

@ -5,7 +5,7 @@
<v-spacer />
<v-btn
tooltip="Save"
class="primary"
class="primary nc-btn-create-webhook"
@click.prevent="$emit('add')"
>
Create Webhook

2
packages/nc-gui/components/project/tableTabs/webhook/WebhookSlider.vue

@ -72,6 +72,6 @@ export default {
<style scoped lang="scss">
::v-deep{
.nc-content{max-width: 600px !important}
.nc-content{max-width: 700px !important}
}
</style>

3
packages/nc-gui/helpers/rolePermissionsEE.js

@ -14,7 +14,8 @@ export default {
fieldsSync: true,
gridColUpdate: true,
filterSync: true,
csvImport: true
csvImport: true,
apiDocs: true
},
commenter: {
smartSheet: true,

18
packages/nc-gui/lang/de.json

@ -121,7 +121,7 @@
"DateTime": "Datum/Zeit",
"CreateTime": "Zeit erstellen",
"LastModifiedTime": "Zuletzt bearbeitet",
"AutoNumber": "Auto-Numerierung",
"AutoNumber": "Auto-Nummerierung",
"Barcode": "Barcode",
"Button": "Taste",
"Password": "Passwort",
@ -172,7 +172,7 @@
"resetPassword": "Passwort zurücksetzen",
"teamAndSettings": "Team & Settings",
"apiDocs": "API Docs",
"importFromAirtable": "Import From Airtable"
"importFromAirtable": "Import aus Airtable"
},
"labels": {
"notifyVia": "Benachrichtigen mit",
@ -192,7 +192,7 @@
"port": "Port-Nummer",
"username": "Benutzername",
"password": "Passwort",
"schemaName": "Schema name",
"schemaName": "Name des Schemas",
"action": "Aktion",
"actions": "Aktionen",
"operation": "Vorgang",
@ -229,7 +229,7 @@
"bookDemo": "Eine kostenlose Demo buchen",
"getAnswered": "Erhalten Sie Antworten auf Ihre Fragen",
"joinDiscord": "Discord beitreten",
"joinCommunity": "Join NocoDB Community",
"joinCommunity": "NocoDB Community beitreten",
"joinReddit": "/r/NocoDB beitreten",
"followNocodb": "Folgen Sie NocoDB"
},
@ -332,7 +332,7 @@
"copyUrl": "URL kopieren",
"openTab": "Neue Registerkarte öffnen",
"iFrame": "Eingebetteten HTML-Code kopieren",
"addWebhook": "Neuen WebHook hinzufügen",
"addWebhook": "Neuen Webhook hinzufügen",
"newToken": "Neuen Token hinzufügen",
"exportZip": "Zip-Datei exportieren",
"importZip": "Zip-Datei importieren",
@ -385,7 +385,7 @@
},
"searchProjectTree": "Tabellen suchen",
"searchFields": "Felder suchen",
"searchColumn": "Spalten {search} suchen",
"searchColumn": "Spalten suchen {search}",
"searchApps": "Apps suchen",
"searchModels": "Modelle suchen",
"noItemsFound": "Keine Elemente gefunden",
@ -399,7 +399,7 @@
"upload_sub": "oder Drag & Drop Datei",
"excelSupport": "Unterstützt: .xls ,.xlsx ,.xlsm, .ods, .ots",
"excelURL": "Excel-Datei-URL eingeben",
"csvURL": "Enter CSV file URL",
"csvURL": "CSV-Datei-URL eingeben",
"footMsg": "Anzahl der Zeilen, um den Datentyp analysieren zu können",
"excelImport": "Blatt/Blätter stehen für den Import zur Verfügung",
"exportMetadata": "Möchten Sie Metadaten von Meta-Tabellen exportieren?",
@ -412,7 +412,7 @@
"deleteProject": "Möchten Sie das Projekt löschen?",
"shareBasePrivate": "Öffentlich freigegebene Nur-Lese-Datenbank generieren",
"shareBasePublic": "Für Jeden im Internet mit diesem Link sichtbar",
"userInviteNoSMTP": "Es sieht so aus, als hätten Sie den Mailer noch nicht konfiguriert!\nBitte kopieren Sie den obigen Einladungs-Link und senden Sie ihn an",
"userInviteNoSMTP": "Es sieht so aus, als hätten Sie den Mailer noch nicht konfiguriert! \\ n Bitte kopieren Sie den obigen Einladungs-Link und senden Sie ihn an",
"dragDropHide": "Ziehen Sie die Felder hierher, um sie zu verstecken",
"formInput": "Formularbezeichnung eingeben",
"formHelpText": "Einen Hilfs-Text hinzufügen",
@ -511,7 +511,7 @@
"projInfo": "Projektinformationen in die Zwischenablage kopiert",
"inviteUrlCopy": "Einladungs-URL in die Zwischenablage kopiert",
"createView": "Ansicht erfolgreich erstellt",
"formEmailSMTP": "Bitte aktivieren Sie das SMTP-Plugin im App-Store, um die E-Mail-Benachrichtigung zu aktivieren",
"formEmailSMTP": "Bitte aktivieren Sie das SMTP-Plug-In im App-Store, um die E-Mail-Benachrichtigung zu aktivieren",
"collabView": "Erfolgreich auf die kollaborative Ansicht gewechselt",
"lockedView": "Erfolgreich auf gesperrte Ansicht gewechselt",
"futureRelease": "Kommt bald!"

4
packages/nc-gui/nuxt.config.js

@ -66,6 +66,10 @@ export default {
src: '~plugins/confetti.js',
ssr: false
},
{
src: '~plugins/domPurify.js',
ssr: false
},
{
src: '~plugins/axiosInterceptor.js',
ssr: false

13103
packages/nc-gui/package-lock.json generated

File diff suppressed because it is too large Load Diff

12
packages/nc-gui/package.json

@ -2,12 +2,12 @@
"name": "nc-gui",
"version": "0.11.35",
"scripts": {
"dev": "EE=true nuxt",
"build": "EE=true nuxt build",
"dev": "cross-env EE=true nuxt",
"build": "cross-env EE=true nuxt build",
"lint": "eslint . --ext .js,.vue --fix --quiet",
"start": "EE=true nuxt start",
"start": "cross-env EE=true nuxt start",
"generate": "nuxt generate",
"build:copy": "EE=true npm run build; rm -rf ../nc-lib-gui/lib/dist/; rsync -rvzh ./dist/ ../nc-lib-gui/lib/dist/",
"build:copy": "cross-env EE=true npm run build; rm -rf ../nc-lib-gui/lib/dist/; rsync -rvzh ./dist/ ../nc-lib-gui/lib/dist/",
"build:copy:jsdeliver": "npm run build; rm -rf ../nc-lib-gui/lib/dist/; rsync -rvzh ./dist/ ../nc-lib-gui/lib/dist/ ; npm publish ../nc-lib-gui"
},
"dependencies": {
@ -31,7 +31,7 @@
"monaco-editor": "^0.19.3",
"monaco-themes": "^0.2.5",
"nano-assign": "^1.0.1",
"nocodb-sdk": "0.91.7",
"nocodb-sdk": "file:../nocodb-sdk",
"nuxt": "^2.14.0",
"odometer": "^0.4.8",
"papaparse": "^5.3.1",
@ -43,6 +43,7 @@
"uuid": "^8.3.2",
"v-clipboard": "^2.2.3",
"vee-validate": "^3.3.9",
"vue-dompurify-html": "^2.6.0",
"vue-github-buttons": "^3.1.0",
"vue-i18n": "^8.20.0",
"vue-kanban": "^1.8.0",
@ -69,6 +70,7 @@
"@nuxtjs/vuetify": "^1.11.2",
"@types/httpsnippet": "^1.23.1",
"babel-eslint": "^10.1.0",
"cross-env": "^7.0.3",
"eslint": "^7.31.0",
"monaco-editor-webpack-plugin": "^1.9.1",
"sass": "~1.32.12",

4
packages/nc-gui/pages/user/settings/index.vue

@ -227,8 +227,10 @@ export default {
newPassword: this.passwordDetails.newPassword
}
)
this.$toast.success('Password changed successfully.').goAway(3000)
this.$toast.success('Password changed successfully. Please login again.').goAway(3000)
this.$refs.formType[0].reset()
await this.$store.dispatch('users/ActSignOut')
this.$router.push('/user/authentication/signin')
} catch (e) {
this.$toast
.error(await this._extractSdkResponseErrorMsg(e))

2
packages/nc-gui/plugins/axiosInterceptor.js

@ -77,7 +77,7 @@ export default ({ store, $axios, redirect, $toast, route, app }) => {
redirect('/')
} else {
$toast.clear()
$toast.info('Token expired please login to continue', {
$toast.info('Token Expired. Please login again.', {
position: 'bottom-center'
}).goAway(5000)
redirect('/user/authentication/signin')

4
packages/nc-gui/plugins/domPurify.js

@ -0,0 +1,4 @@
import Vue from 'vue'
import VueDOMPurifyHTML from 'vue-dompurify-html'
Vue.use(VueDOMPurifyHTML)

14
packages/nc-gui/store/project.js

@ -102,7 +102,11 @@ export const mutations = {
},
MutAppInfo(state, appInfo) {
state.appInfo = appInfo
}
},
MutProjectCost(state, cost) {
state.project.cost = cost
},
}
function getSerializedEnvObj(data) {
@ -293,6 +297,9 @@ export const getters = {
&& state.unserializedList[0].projectJson
&& state.unserializedList[0].projectJson.envs ? Object.keys(state.unserializedList[0].projectJson.envs) : []
},
GtrProjectCost(state) {
return state.project.cost || 0
},
}
@ -351,6 +358,11 @@ export const actions = {
this.$ncApis.clear()
this.$ncApis.setProjectId(projectId)
}
this.$api.project.cost(projectId).then(res => {
if (res.cost) commit('MutProjectCost', res.cost)
})
} catch (e) {
console.log(e)
this.$toast.error(e).goAway(3000)

6
packages/noco-docs-prev/content/en/getting-started/installation.md

@ -146,10 +146,8 @@ If you plan to input some special characters, you may need to change the charact
| PORT | No | For setting app running port | `8080` |
| NC_SENTRY_DSN | No | For Sentry monitoring | |
| NC_DISABLE_ERR_REPORT | No | Disable error reporting | |
| AWS_ACCESS_KEY_ID | No | For Litestream - S3 access key id | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 |
| AWS_SECRET_ACCESS_KEY | No | For Litestream - S3 secret access key | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 |
| AWS_BUCKET | No | For Litestream - S3 bucket | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 |
| AWS_BUCKET_PATH | No | For Litestream - S3 bucket path (like folder within S3 bucket) | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 |
### Docker Compose

8
packages/noco-docs/content/en/developer-resources/webhooks.md

@ -66,15 +66,9 @@ For INSERT/ UPDATE based triggers, use following handlebars to access correspond
Note that, for Update trigger - all the fields in the ROW will be accessible, not just the field updated.
For DELETE based triggers, **only** {{ data.id }} is accessible representing ID of the column deleted.
For all trigger, following **user** information associated with person trigger can be accessed.
- {{ **user**.id }} : Unique auto incremented NocoDB system value
- {{ **user**.email }} : User E-mail.
- {{ **user**.roles }} : User Role amongst [Owner, Creator, Editor, Commenter, Viewer].
### JSON format
Use {{ json data }} {{ json user }} to dump complete data & user information available in JSON format
Use {{ json data }} to dump complete data & user information available in JSON format
### Additional references:

30
packages/noco-docs/content/en/getting-started/installation.md

@ -166,31 +166,24 @@ Tip 2: If you plan to input some special characters, you may need to change the
</alert>
## Production Setup
By default, SQLite is used for storing meta data. However, you can specify your own database. The connection params for this database can be specified in `NC_DB` environment variable. Moreover, we also provide the below environment variables for configuration.
It is mandatory to configure `NC_DB` environment variables for production usecases.
### Environment variables
| Variable | Mandatory | Comments | If absent | |
|------------------------------------|-----------|-------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------|---|
| AWS_ACCESS_KEY_ID | No | For Litestream - S3 access key id | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_SECRET_ACCESS_KEY | No | For Litestream - S3 secret access key | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET | No | For Litestream - S3 bucket | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET_PATH | No | For Litestream - S3 bucket path (like folder within S3 bucket) | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| DB_QUERY_LIMIT_DEFAULT | No | Default pagination limit | 25 | |
| DB_QUERY_LIMIT_MAX | No | Maximum allowed pagination limit | 100 | |
| DB_QUERY_LIMIT_MIN | No | Minimum allowed pagination limit | 1 | |
| DATABASE_URL | No | JDBC URL Format. Can be used instead of NC_DB. Used in 1-Click Heroku deployment | | |
| DATABASE_URL_FILE | No | path to file containing JDBC URL Format. Can be used instead of NC_DB. Used in 1-Click Heroku deployment | | |
| PORT | No | For setting app running port | `8080` | |
| NC_DB | Yes | See our database URLs | A local SQLite will be created in root folder | |
| NC_DB_JSON | Yes | Can be used instead of `NC_DB` and value should be valid knex connection JSON | | |
| NC_DB_JSON_FILE | Yes | Can be used instead of `NC_DB` and value should be a valid path to knex connection JSON | | |
| NC_DASHBOARD_URL | No | Custom dashboard url path | `/dashboard` | |
| DATABASE_URL | No | JDBC URL Format. Can be used instead of NC_DB. Used in 1-Click Heroku deployment | | |
| DATABASE_URL_FILE | No | Can be used instead of DATABASE_URL: path to file containing JDBC URL Format. | | |
| NC_AUTH_JWT_SECRET | Yes | JWT secret used for auth and storing other secrets | A Random secret will be generated | |
| PORT | No | For setting app running port | `8080` | |
| DB_QUERY_LIMIT_DEFAULT | No | Default pagination limit | 25 | |
| DB_QUERY_LIMIT_MAX | No | Maximum allowed pagination limit | 1000 | |
| DB_QUERY_LIMIT_MIN | No | Minimum allowed pagination limit | 1 | |
| NC_TOOL_DIR | No | App directory to keep metadata and app related files | Defaults to current working directory. In docker maps to `/usr/app/data/` for mounting volume. | |
| NC_PUBLIC_URL | Yes | Used for sending Email invitations | Best guess from http request params | |
| NC_AUTH_JWT_SECRET | Yes | JWT secret used for auth and storing other secrets | A Random secret will be generated | |
| NC_JWT_EXPIRES_IN | No | JWT token expiry time | `10h` | |
| NC_CONNECT_TO_EXTERNAL_DB_DISABLED | No | Disable Project creation with external database | | |
| NC_INVITE_ONLY_SIGNUP | No | Allow users to signup only via invite url, value should be any non-empty string. | | |
@ -198,16 +191,21 @@ By default, SQLite is used for storing meta data. However, you can specify your
| NC_REQUEST_BODY_SIZE | No | Request body size [limit](https://expressjs.com/en/resources/middleware/body-parser.html#limit) | `1048576` | |
| NC_EXPORT_MAX_TIMEOUT | No | After NC_EXPORT_MAX_TIMEOUT csv gets downloaded in batches | Default value 5000(in millisecond) will be used | |
| NC_DISABLE_TELE | No | Disable telemetry | | |
| NC_DASHBOARD_URL | No | Custom dashboard url path | `/dashboard` | |
| NC_GOOGLE_CLIENT_ID | No | Google client id to enable google authentication | | |
| NC_GOOGLE_CLIENT_SECRET | No | Google client secret to enable google authentication | | |
| NC_MIGRATIONS_DISABLED | No | Disable NocoDB migration | | |
| NC_ONE_CLICK | No | Used for Heroku one-click deployment | | |
| NC_MIN | No | If set to any non-empty string the default splash screen(initial welcome animation) and matrix screensaver will disable | | |
| NC_SENTRY_DSN | No | For Sentry monitoring | | |
| NC_DISABLE_ERR_REPORT | No | Disable error reporting | | |
| NC_REDIS_URL | No | Custom Redis URL. Example: `redis://:authpassword@127.0.0.1:6380/4` | Meta data will be stored in memory | |
| NC_DISABLE_ERR_REPORT | No | Disable error reporting | | |
| NC_DISABLE_CACHE | No | To be used only while debugging. On setting this to `true` - meta data be fetched from db instead of redis/cache. | `false` | |
| NC_BASEURL_INTERNAL | No | Used as base url for internal(server) API calls | Default value in docker will be `http://localhost:$PORT` and in all other case it's populated from request object | |
| AWS_ACCESS_KEY_ID | No | For Litestream - S3 access key id | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_SECRET_ACCESS_KEY | No | For Litestream - S3 secret access key | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET | No | For Litestream - S3 bucket | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
| AWS_BUCKET_PATH | No | For Litestream - S3 bucket path (like folder within S3 bucket) | If Litestream is configured and NC_DB is not present. SQLite gets backed up to S3 | |
### AWS ECS (Fargate)

2
packages/noco-docs/content/en/index.md

@ -91,7 +91,7 @@ Please refer to [Development Setup](https://github.com/nocodb/nocodb#development
### Committing Changes
We encourage all contributors to commit messages following [Commit Message Convention](./COMMIT_CONVENTION.md).
We encourage all contributors to commit messages following [Commit Message Convention](https://github.com/nocodb/nocodb/blob/master/.github/COMMIT_CONVENTION.md).
### Applying License

30
packages/noco-docs/content/en/setup-and-usages/usage-information.md

@ -26,44 +26,22 @@ However, these above actions alone are often insufficient
## What we collect ?
We collect actions made on models (project, table, view, sharedView, user, hook, image, sharedBase etc) periodically with :
- Unique machine ID (generated with node-machine-id)
- Environment (dev, staging, production)
- System information (OS, node version, docker or npm)
- Environment (dev, staging, production)
- Instance information (Unique machine ID, database type, count of projects and users)
- Failures.
Here is an example :
```
{
"machine_id" : "a0885e8e6a38d9fbb5d39e7d04a44da7773d4f",
"evt_type": "project:created"
"package_id" : "0.84.15",
"os_type" : "Linux",
"os_platform" : "linux",
"os_release" : "5.10.25-linuxkit",
"node_version" : "14.18.2",
"docker" : "true",
"xc_version" : "a0885e8e6a38d9fbb5d39e7d04a44da7773d4f",
"env" : "dev",
}
```
Our UI Dashboard is a Vuejs-Nuxtjs app. Actions taken on UI with completely anonymized route names are sent as payload.
Here is an example :
```
{
"id": "a0885e8e6a38d9fbb5d39e7d04a44da7773d4f",
"event": "table:create",
"path": "/nc/:project_id",
}
```
## What we DO NOT collect ?
We do not collect any private or sensitive information, such as:
- Personally identifiable information
- Credential information (endpoints, ports, DB connections, username/password)
- User data
- Database/User data
## Opt-out

17
packages/nocodb-sdk/src/lib/Api.ts

@ -1311,6 +1311,23 @@ export class Api<
...params,
}),
/**
* @description Project compare cost
*
* @tags Project
* @name Cost
* @summary Project compare cost
* @request GET:/api/v1/db/meta/projects/{projectId}/cost
* @response `200` `object` OK
*/
cost: (projectId: string, params: RequestParams = {}) =>
this.request<object, any>({
path: `/api/v1/db/meta/projects/${projectId}/cost`,
method: 'GET',
format: 'json',
...params,
}),
/**
* No description
*

1
packages/nocodb-sdk/src/lib/sqlUi/SqliteUi.ts

@ -714,6 +714,7 @@ export class SqliteUi {
case 'double':
case 'double precision':
case 'float':
case 'decimal':
case 'numeric':
return 'float';

2
packages/nocodb/docker/index.js

@ -1,4 +1,4 @@
const Noco = require("../build/main/lib/noco/Noco").default;
const Noco = require("../build/main/lib/Noco").default;
const express = require('express');
const cors = require('cors');
const server = express();

1097
packages/nocodb/package-lock.json generated

File diff suppressed because it is too large Load Diff

31
packages/nocodb/package.json

@ -38,11 +38,11 @@
"reset": "git clean -dfx && git reset --hard && npm i",
"clean": "trash build src/test",
"prepare-release": "run-s reset src/test cov:check doc:html version doc:publish",
"start-graphql": "ts-node src/example/index.gql.ts",
"start-rest": "ts-node src/example/index.rest.ts",
"start-grpc": "ts-node src/example/index.grpc.ts",
"start-api": "ts-node src/example/index.ts",
"start-xc-tool-api": "ts-node src/example/xc-tool-apis.ts",
"start-graphql": "ts-node src/run/index.gql.ts",
"start-rest": "ts-node src/run/index.rest.ts",
"start-grpc": "ts-node src/run/index.grpc.ts",
"start-api": "ts-node src/run/index.ts",
"start-xc-tool-api": "ts-node src/run/xc-tool-apis.ts",
"docker-test": "node docker/index.js",
"test:dev:travis": "cross-env NODE_ENV=dev npm run test:rest && NODE_ENV=dev npm run test:graphql && NODE_ENV=dev npm run test:grpc",
"test:travis": "cross-env NODE_ENV=test npm run test:rest && NODE_ENV=test npm run test:graphql && NODE_ENV=test npm run test:grpc",
@ -63,17 +63,17 @@
"docker:s3:build:publish:image": "npm run build && npm run docker:build && npm run docker:s3:image:build && npm run docker:s3:image:deploy",
"docker:oracle:image:build": "docker build . -t xc-instant-oracle -f Dockerfile-ORACLE --no-cache",
"help:a": "node docker/test",
"help:seed": "ts-node ./src/example/seedts.ts",
"help:seed": "ts-node src/run/seedts.ts",
"help:c": "ts-node ./help/a",
"watch:build": "nodemon -e ts,js -w ./src -x npm run build",
"watch:serve": "nodemon -e ts -w ./build -x npm run debug-local ",
"watch:run": "cross-env NC_DISABLE_TELE1=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/docker --log-error --project tsconfig.json\"",
"watch:run:cypress": "cross-env EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/docker --log-error --project tsconfig.json\"",
"watch:run:mysql": "cross-env NC_DISABLE_TELE=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/dockerRunMysql --log-error --project tsconfig.json\"",
"watch:run:pg": "cross-env NC_DISABLE_TELE=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/dockerRunPG --log-error --project tsconfig.json\"",
"run": "ts-node src/example/docker",
"watch:try": "nodemon -e ts,js -w ./src -x \"ts-node src/example/try --log-error --project tsconfig.json\"",
"example:docker": "ts-node ./src/example/docker.ts"
"watch:run": "cross-env NC_DISABLE_TELE1=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/run/docker --log-error --project tsconfig.json\"",
"watch:run:cypress": "cross-env EE=true nodemon -e ts,js -w ./src -x \"ts-node src/run/docker --log-error --project tsconfig.json\"",
"watch:run:mysql": "cross-env NC_DISABLE_TELE=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/run/dockerRunMysql --log-error --project tsconfig.json\"",
"watch:run:pg": "cross-env NC_DISABLE_TELE=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/run/dockerRunPG --log-error --project tsconfig.json\"",
"run": "ts-node src/run/docker",
"watch:try": "nodemon -e ts,js -w ./src -x \"ts-node src/run/try --log-error --project tsconfig.json\"",
"example:docker": "ts-node src/run/docker.ts"
},
"scripts-info": {
"info": "Display information about the package scripts",
@ -133,6 +133,7 @@
"ioredis": "^4.28.5",
"ioredis-mock": "^7.1.0",
"is-docker": "^2.2.1",
"isomorphic-dompurify": "^0.19.0",
"js-beautify": "^1.11.0",
"jsep": "^1.3.6",
"json2csv": "^5.0.6",
@ -152,11 +153,11 @@
"mysql2": "^2.2.5",
"nanoid": "^3.1.20",
"nc-common": "0.0.6",
"nc-help": "0.2.59",
"nc-help": "0.2.61",
"nc-lib-gui": "0.91.7",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
"nocodb-sdk": "0.91.7",
"nocodb-sdk": "file:../nocodb-sdk",
"nodemailer": "^6.4.10",
"object-hash": "^3.0.0",
"ora": "^4.0.4",

2
packages/nocodb/src/__tests__/TemplateParser.test.ts

@ -1,6 +1,6 @@
import { expect } from 'chai';
import 'mocha';
import NcTemplateParser from '../lib/templateParser/NcTemplateParser';
import NcTemplateParser from '../lib/v1-legacy/templates/NcTemplateParser';
import template from './template';
describe('Template parser', () => {

4
packages/nocodb/src/__tests__/formula.test.ts

@ -1,7 +1,7 @@
import { expect } from 'chai';
import 'mocha';
import knex from '../lib/dataMapper/lib/sql/CustomKnex';
import formulaQueryBuilderFromString from '../lib/dataMapper/lib/sql/formulaQueryBuilderFromString';
import knex from '../lib/db/sql-data-mapper/lib/sql/CustomKnex';
import formulaQueryBuilderFromString from '../lib/db/sql-data-mapper/lib/sql/formulaQueryBuilderFromString';
process.env.TEST = 'test';

18
packages/nocodb/src/__tests__/graphql.test.ts

@ -84,7 +84,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Signup with valid email', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignUp(data : { email: "${EMAIL_ID}", password: "${VALID_PASSWORD}"}){ token }}`
// })
@ -104,7 +104,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Signup with invalid email', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignUp(data : { email: "test", password: "${VALID_PASSWORD}"}){ token }}`
// })
@ -120,7 +120,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Signin with valid email', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignIn(data : { email: "${EMAIL_ID}", password: "${VALID_PASSWORD}"}){ token }}`
// })
@ -140,7 +140,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('me', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .set({'xc-auth': token})
// .send({
// query: `{ Me{ email id }}`
@ -159,7 +159,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Signin with invalid email', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ SignIn(data : { email: "abc@abcc.com", password: "randomPassord"}){ token }}`
// })
@ -175,7 +175,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Forgot password with a non-existing email id', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ PasswordForgot(email: "abc@abcc.com")}`
// })
@ -190,7 +190,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Forgot password with an existing email id', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ PasswordForgot(email: "${EMAIL_ID}")}`
// })
@ -204,7 +204,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Email validate with an invalid token', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ EmailValidate(tokenId: "invalid-token-id")}`
// })
@ -218,7 +218,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
//
// it('Reset Password with an invalid token', function (done) {
// request(app)
// .post('/v1/graphql')
// .post('/v1-legacy/graphql')
// .send({
// query: `mutation{ PasswordReset(password:"somePassword",tokenId: "invalid-token-id")}`
// })

30
packages/nocodb/src/lib/noco/Noco.ts → packages/nocodb/src/lib/Noco.ts

@ -15,32 +15,33 @@ import NcToolGui from 'nc-lib-gui';
import requestIp from 'request-ip';
import { v4 as uuidv4 } from 'uuid';
import { NcConfig } from '../../interface/config';
import Migrator from '../migrator/SqlMigrator/lib/KnexMigrator';
import NcConfigFactory from '../utils/NcConfigFactory';
import { NcConfig } from '../interface/config';
import Migrator from './db/sql-migrator/lib/KnexMigrator';
import NcConfigFactory from './utils/NcConfigFactory';
import NcProjectBuilderCE from './NcProjectBuilder';
import NcProjectBuilderEE from './NcProjectBuilderEE';
import { GqlApiBuilder } from './gql/GqlApiBuilder';
import NcProjectBuilderCE from './v1-legacy/NcProjectBuilder';
import NcProjectBuilderEE from './v1-legacy/NcProjectBuilderEE';
import { GqlApiBuilder } from './v1-legacy/gql/GqlApiBuilder';
import NcMetaIO from './meta/NcMetaIO';
import NcMetaImplCE from './meta/NcMetaIOImpl';
import NcMetaImplEE from './meta/NcMetaIOImplEE';
import NcMetaMgrCE from './meta/NcMetaMgr';
import NcMetaMgrEE from './meta/NcMetaMgrEE';
import { RestApiBuilder } from './rest/RestApiBuilder';
import RestAuthCtrlCE from './rest/RestAuthCtrl';
import RestAuthCtrlEE from './rest/RestAuthCtrlEE';
import { RestApiBuilder } from './v1-legacy/rest/RestApiBuilder';
import RestAuthCtrlCE from './v1-legacy/rest/RestAuthCtrl';
import RestAuthCtrlEE from './v1-legacy/rest/RestAuthCtrlEE';
import mkdirp from 'mkdirp';
import MetaAPILogger from './meta/MetaAPILogger';
import NcUpgrader from './upgrader/NcUpgrader';
import NcUpgrader from './version-upgrader/NcUpgrader';
import NcMetaMgrv2 from './meta/NcMetaMgrv2';
import NocoCache from '../noco-cache/NocoCache';
import NocoCache from './cache/NocoCache';
import registerMetaApis from './meta/api';
import NcPluginMgrv2 from './meta/helpers/NcPluginMgrv2';
import User from '../noco-models/User';
import User from './models/User';
import { Tele } from 'nc-help';
import * as http from 'http';
import weAreHiring from '../utils/weAreHiring';
import weAreHiring from './utils/weAreHiring';
import getInstance from './utils/getInstance';
const log = debug('nc:app');
require('dotenv').config();
@ -263,6 +264,9 @@ export default class Noco {
}
next();
});
Tele.init({
instance: getInstance
});
Tele.emit('evt_app_started', await User.count());
weAreHiring();
return this.router;

0
packages/nocodb/src/lib/noco-cache/CacheMgr.ts → packages/nocodb/src/lib/cache/CacheMgr.ts vendored

0
packages/nocodb/src/lib/noco-cache/NocoCache.ts → packages/nocodb/src/lib/cache/NocoCache.ts vendored

0
packages/nocodb/src/lib/noco-cache/RedisCacheMgr.ts → packages/nocodb/src/lib/cache/RedisCacheMgr.ts vendored

0
packages/nocodb/src/lib/noco-cache/RedisMockCacheMgr.ts → packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts vendored

0
packages/nocodb/src/lib/dataMapper/README.md → packages/nocodb/src/lib/db/sql-data-mapper/README.md

0
packages/nocodb/src/lib/dataMapper/__tests__/conditionClause.test.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/conditionClause.test.js

0
packages/nocodb/src/lib/dataMapper/__tests__/conditionGraph.test.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/conditionGraph.test.js

0
packages/nocodb/src/lib/dataMapper/__tests__/models/city.meta.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/city.meta.js

0
packages/nocodb/src/lib/dataMapper/__tests__/models/city.model.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/city.model.js

0
packages/nocodb/src/lib/dataMapper/__tests__/models/country.meta.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/country.meta.js

0
packages/nocodb/src/lib/dataMapper/__tests__/models/country.model.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/country.model.js

0
packages/nocodb/src/lib/dataMapper/__tests__/models/film.meta.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/film.meta.js

0
packages/nocodb/src/lib/dataMapper/__tests__/models/film.model.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/film.model.js

0
packages/nocodb/src/lib/dataMapper/__tests__/models/index.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/models/index.js

0
packages/nocodb/src/lib/dataMapper/__tests__/sql.test.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/sql.test.js

0
packages/nocodb/src/lib/dataMapper/__tests__/whereClause.test.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/whereClause.test.js

0
packages/nocodb/src/lib/dataMapper/__tests__/xSelect.test.js → packages/nocodb/src/lib/db/sql-data-mapper/__tests__/xSelect.test.js

0
packages/nocodb/src/lib/dataMapper/index.ts → packages/nocodb/src/lib/db/sql-data-mapper/index.ts

4
packages/nocodb/src/lib/dataMapper/lib/BaseModel.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts

@ -838,13 +838,13 @@ abstract class BaseModel {
* @param {String} [args.max] - maximum value
* @param {String} [args.step] - step value
* @returns {Promise<object[]>} Distributions of column values in table
* @example
* @run
* table.distribution({
* cn : 'price',
* steps: '0,100,200,300,400',
* func: 'sum,avg'
* })
* @example
* @run
* table.distribution({
* cn : 'price',
* min: '0',

0
packages/nocodb/src/lib/dataMapper/lib/DbFactory.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/DbFactory.ts

4
packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts

@ -1118,13 +1118,13 @@ class BaseModelSql extends BaseModel {
* @param {String} [args.max] - maximum value
* @param {String} [args.step] - step value
* @returns {Promise<Object[]>} Distributions of column values in table
* @example
* @run
* table.distribution({
* cn : 'price',
* steps: '0,100,200,300,400',
* func: 'sum,avg'
* })
* @example
* @run
* table.distribution({
* cn : 'price',
* min: '0',

55
packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSqlv2.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts

@ -1,23 +1,23 @@
import autoBind from 'auto-bind';
import _ from 'lodash';
import Model from '../../../noco-models/Model';
import { XKnex } from '../..';
import LinkToAnotherRecordColumn from '../../../noco-models/LinkToAnotherRecordColumn';
import RollupColumn from '../../../noco-models/RollupColumn';
import LookupColumn from '../../../noco-models/LookupColumn';
import Model from '../../../../models/Model';
import { XKnex } from '../../index';
import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordColumn';
import RollupColumn from '../../../../models/RollupColumn';
import LookupColumn from '../../../../models/LookupColumn';
import DataLoader from 'dataloader';
import Column from '../../../noco-models/Column';
import Column from '../../../../models/Column';
import { XcFilter, XcFilterWithAlias } from '../BaseModel';
import conditionV2 from './conditionV2';
import Filter from '../../../noco-models/Filter';
import Filter from '../../../../models/Filter';
import sortV2 from './sortV2';
import Sort from '../../../noco-models/Sort';
import FormulaColumn from '../../../noco-models/FormulaColumn';
import Sort from '../../../../models/Sort';
import FormulaColumn from '../../../../models/FormulaColumn';
import genRollupSelectv2 from './genRollupSelectv2';
import formulaQueryBuilderv2 from './formulav2/formulaQueryBuilderv2';
import { QueryBuilder } from 'knex';
import View from '../../../noco-models/View';
import View from '../../../../models/View';
import {
AuditOperationSubTypes,
AuditOperationTypes,
@ -26,21 +26,21 @@ import {
UITypes,
ViewTypes
} from 'nocodb-sdk';
import formSubmissionEmailTemplate from '../../../noco/common/formSubmissionEmailTemplate';
import formSubmissionEmailTemplate from '../../../../utils/common/formSubmissionEmailTemplate';
import ejs from 'ejs';
import Audit from '../../../noco-models/Audit';
import FormView from '../../../noco-models/FormView';
import Hook from '../../../noco-models/Hook';
import NcPluginMgrv2 from '../../../noco/meta/helpers/NcPluginMgrv2';
import Audit from '../../../../models/Audit';
import FormView from '../../../../models/FormView';
import Hook from '../../../../models/Hook';
import NcPluginMgrv2 from '../../../../meta/helpers/NcPluginMgrv2';
import {
_transformSubmittedFormDataForEmail,
invokeWebhook,
parseBody
} from '../../../noco/meta/helpers/webhookHelpers';
invokeWebhook
} from '../../../../meta/helpers/webhookHelpers';
import Validator from 'validator';
import { customValidators } from './customValidators';
import { NcError } from '../../../noco/meta/helpers/catchError';
import { NcError } from '../../../../meta/helpers/catchError';
import { customAlphabet } from 'nanoid';
import DOMPurify from 'isomorphic-dompurify';
const GROUP_COL = '__nc_group_id';
@ -70,9 +70,9 @@ class BaseModelSqlv2 {
private _columns = {};
private config: any = {
limitDefault: 25,
limitMin: 1,
limitMax: 1000
limitDefault: Math.max(+process.env.DB_QUERY_LIMIT_DEFAULT || 25, 1),
limitMin: Math.max(+process.env.DB_QUERY_LIMIT_MIN || 1, 1),
limitMax: Math.max(+process.env.DB_QUERY_LIMIT_MAX || 1000, 1)
};
constructor({
@ -1370,6 +1370,7 @@ class BaseModelSqlv2 {
get isPg() {
return this.clientType === 'pg';
}
get isMySQL() {
return this.clientType === 'mysql2' || this.clientType === 'mysql';
}
@ -1406,7 +1407,7 @@ class BaseModelSqlv2 {
switch (colOptions.type) {
case RelationTypes.BELONGS_TO:
{
const parentCol = await colOptions.getParentColumn();
const parentCol = await colOptions.getChildColumn();
insertObj[parentCol.column_name] =
nestedData?.[parentCol.title];
}
@ -1716,7 +1717,9 @@ class BaseModelSqlv2 {
row_id: id,
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.INSERT,
description: `${id} inserted into ${this.model.title}`,
description: DOMPurify.sanitize(
`${id} inserted into ${this.model.title}`
),
// details: JSON.stringify(data),
ip: req?.clientIp,
user: req?.user?.email
@ -1760,7 +1763,7 @@ class BaseModelSqlv2 {
row_id: id,
op_type: AuditOperationTypes.DATA,
op_sub_type: AuditOperationSubTypes.DELETE,
description: `${id} deleted from ${this.model.title}`,
description: DOMPurify.sanitize(`${id} deleted from ${this.model.title}`),
// details: JSON.stringify(data),
ip: req?.clientIp,
user: req?.user?.email
@ -1790,7 +1793,7 @@ class BaseModelSqlv2 {
// todo: notification template
(await NcPluginMgrv2.emailAdapter())?.mailSend({
to: emails.join(','),
subject: parseBody('NocoDB Form', req, data, {}),
subject: 'NocoDB Form',
html: ejs.render(formSubmissionEmailTemplate, {
data: transformedData,
tn: this.model.table_name,

2
packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts

@ -5,7 +5,7 @@ const types = require('pg').types;
types.setTypeParser(1082, val => val);
import { BaseModelSql } from './BaseModelSql';
import Filter from '../../../noco-models/Filter';
import Filter from '../../../../models/Filter';
const opMappingGen = {
eq: '=',

16
packages/nocodb/src/lib/dataMapper/lib/sql/conditionV2.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts

@ -1,15 +1,15 @@
import Filter from '../../../noco-models/Filter';
import LinkToAnotherRecordColumn from '../../../noco-models/LinkToAnotherRecordColumn';
import Filter from '../../../../models/Filter';
import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordColumn';
import { QueryBuilder } from 'knex';
import { XKnex } from '../..';
import Column from '../../../noco-models/Column';
import LookupColumn from '../../../noco-models/LookupColumn';
import { XKnex } from '../../index';
import Column from '../../../../models/Column';
import LookupColumn from '../../../../models/LookupColumn';
import genRollupSelectv2 from './genRollupSelectv2';
import RollupColumn from '../../../noco-models/RollupColumn';
import RollupColumn from '../../../../models/RollupColumn';
import formulaQueryBuilderv2 from './formulav2/formulaQueryBuilderv2';
import FormulaColumn from '../../../noco-models/FormulaColumn';
import FormulaColumn from '../../../../models/FormulaColumn';
import { RelationTypes, UITypes } from 'nocodb-sdk';
// import LookupColumn from '../../../noco-models/LookupColumn';
// import LookupColumn from '../../../models/LookupColumn';
export default async function conditionV2(
conditionObj: Filter | Filter[],

0
packages/nocodb/src/lib/dataMapper/lib/sql/customValidators.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/customValidators.ts

0
packages/nocodb/src/lib/dataMapper/lib/sql/formulaQueryBuilderFromString.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulaQueryBuilderFromString.ts

16
packages/nocodb/src/lib/dataMapper/lib/sql/formulav2/formulaQueryBuilderv2.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts

@ -1,12 +1,12 @@
import jsep from 'jsep';
import mapFunctionName from '../mapFunctionName';
import Model from '../../../../noco-models/Model';
import Model from '../../../../../models/Model';
import genRollupSelectv2 from '../genRollupSelectv2';
import RollupColumn from '../../../../noco-models/RollupColumn';
import FormulaColumn from '../../../../noco-models/FormulaColumn';
import { XKnex } from '../../..';
import LinkToAnotherRecordColumn from '../../../../noco-models/LinkToAnotherRecordColumn';
import LookupColumn from '../../../../noco-models/LookupColumn';
import RollupColumn from '../../../../../models/RollupColumn';
import FormulaColumn from '../../../../../models/FormulaColumn';
import { XKnex } from '../../../index';
import LinkToAnotherRecordColumn from '../../../../../models/LinkToAnotherRecordColumn';
import LookupColumn from '../../../../../models/LookupColumn';
import { jsepCurlyHook, UITypes } from 'nocodb-sdk';
// todo: switch function based on database
@ -246,7 +246,7 @@ export default async function formulaQueryBuilderv2(
>();
// if (relation.type !== 'bt') continue;
const colOptions = (await col.getColOptions()) as LinkToAnotherRecordColumn;
const colOptions = (await lookupColumn.getColOptions()) as LinkToAnotherRecordColumn;
const childColumn = await colOptions.getChildColumn();
const parentColumn = await colOptions.getParentColumn();
const childModel = await childColumn.getModel();
@ -627,7 +627,7 @@ export default async function formulaQueryBuilderv2(
}
return query;
})
.join()})${colAlias}`
.join()})${colAlias}`.replace(/\?/g, '\\?')
);
} else if (pt.type === 'Literal') {
return knex.raw(`?${colAlias}`, [pt.value]);

0
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/commonFns.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/commonFns.ts

0
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts

0
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mysql.ts

0
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts

0
packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts

0
packages/nocodb/src/lib/dataMapper/lib/sql/genRollupSelect.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelect.ts

6
packages/nocodb/src/lib/dataMapper/lib/sql/genRollupSelectv2.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelectv2.ts

@ -1,6 +1,6 @@
import RollupColumn from '../../../noco-models/RollupColumn';
import { XKnex } from '../..';
import LinkToAnotherRecordColumn from '../../../noco-models/LinkToAnotherRecordColumn';
import RollupColumn from '../../../../models/RollupColumn';
import { XKnex } from '../../index';
import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordColumn';
import { QueryBuilder } from 'knex';
import { RelationTypes } from 'nocodb-sdk';

8
packages/nocodb/src/lib/dataMapper/lib/sql/helpers/getAst.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/helpers/getAst.ts

@ -1,7 +1,7 @@
import View from '../../../../noco-models/View';
import View from '../../../../../models/View';
import { isSystemColumn, UITypes } from 'nocodb-sdk';
import Model from '../../../../noco-models/Model';
import LinkToAnotherRecordColumn from '../../../../noco-models/LinkToAnotherRecordColumn';
import Model from '../../../../../models/Model';
import LinkToAnotherRecordColumn from '../../../../../models/LinkToAnotherRecordColumn';
const getAst = async ({
query,
@ -72,7 +72,7 @@ const getAst = async ({
value = await getAst({
model,
query: query?.nested,
query: query?.nested?.[col.title],
extractOnlyPrimaries: nestedFields !== '*'
});
}

0
packages/nocodb/src/lib/dataMapper/lib/sql/mapFunctionName.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/mapFunctionName.ts

12
packages/nocodb/src/lib/dataMapper/lib/sql/sortV2.ts → packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts

@ -1,12 +1,12 @@
import { QueryBuilder } from 'knex';
import { XKnex } from '../..';
import Sort from '../../../noco-models/Sort';
import LinkToAnotherRecordColumn from '../../../noco-models/LinkToAnotherRecordColumn';
import { XKnex } from '../../index';
import Sort from '../../../../models/Sort';
import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordColumn';
import genRollupSelectv2 from './genRollupSelectv2';
import RollupColumn from '../../../noco-models/RollupColumn';
import LookupColumn from '../../../noco-models/LookupColumn';
import RollupColumn from '../../../../models/RollupColumn';
import LookupColumn from '../../../../models/LookupColumn';
import formulaQueryBuilderv2 from './formulav2/formulaQueryBuilderv2';
import FormulaColumn from '../../../noco-models/FormulaColumn';
import FormulaColumn from '../../../../models/FormulaColumn';
import { RelationTypes, UITypes } from 'nocodb-sdk';
export default async function sortV2(

0
packages/nocodb/src/lib/sqlMgr/ProjectMgr.ts → packages/nocodb/src/lib/db/sql-mgr/ProjectMgr.ts

8
packages/nocodb/src/lib/sqlMgr/SqlMgr.ts → packages/nocodb/src/lib/db/sql-mgr/SqlMgr.ts

@ -11,9 +11,9 @@ import slash from 'slash';
// import debug from 'debug';
const log = new Debug('SqlMgr');
import KnexMigrator from '../migrator/SqlMigrator/lib/KnexMigrator';
// import {XKnex} from "../dataMapper";
import NcConnectionMgr from '../noco/common/NcConnectionMgr';
import KnexMigrator from '../sql-migrator/lib/KnexMigrator';
// import {XKnex} from "../sql-data-mapper";
import NcConnectionMgr from '../../utils/common/NcConnectionMgr';
import { customAlphabet } from 'nanoid';
const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 20);
@ -728,7 +728,7 @@ export default class SqlMgr {
const result = new Result();
log.api(`${func}:args:`, args);
// await this.migrator().clean(args);
// await this.sql-migrator().clean(args);
await this._project.remove(args);
return result;

6
packages/nocodb/src/lib/sqlMgr/code/BaseRender.ts → packages/nocodb/src/lib/db/sql-mgr/code/BaseRender.ts

@ -7,9 +7,9 @@
// import js_beautify from "js-beautify";
// import fsExtra from "fs-extra";
// import md5 from "md5";
// import dayjs from "dayjs";import Emit from "../../migrator/util/emit";
import Debug from '../../migrator/util/Debug';
import Emit from '../../migrator/util/emit';
// import dayjs from "dayjs";import Emit from "../../sql-migrator/util/emit";
import Debug from '../../sql-migrator/util/Debug';
import Emit from '../../sql-migrator/util/emit';
// const beautify = js_beautify.js;

2
packages/nocodb/src/lib/sqlMgr/code/gql-policies/xc-ts/ExpressXcTsPolicyGql.ts → packages/nocodb/src/lib/db/sql-mgr/code/gql-policies/xc-ts/ExpressXcTsPolicyGql.ts

@ -20,7 +20,7 @@ class ExpressXcPolicyGql extends BaseRender {
prepare(): any {
let data = {};
/* example of simple variable */
/* run of simple variable */
data = this.ctx;
return data;

0
packages/nocodb/src/lib/sqlMgr/code/gql-schema/xc-ts/BaseGqlXcTsSchema.ts → packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/BaseGqlXcTsSchema.ts

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save