Separate Prettier and ESLint according to best practices (#9565)

* Separate Prettier and ESLint according to best practices

- Create standalone .prettierrc configuration file
- Remove eslint-plugin-prettier integration from ESLint config
- Replace with eslint-config-prettier to disable conflicting rules
- Remove eslint-plugin-prettier dependency
- Add dedicated format and format:check scripts
- Update lint-staged to run Prettier and ESLint separately
- Format entire codebase with new Prettier configuration

This follows the recommended approach from Prettier documentation:
https://prettier.io/docs/integrating-with-linters#notes

* Remove test comment

---------

Co-authored-by: codegen-sh[bot] <131295404+codegen-sh[bot]@users.noreply.github.com>
This commit is contained in:
codegen-sh[bot]
2025-07-08 18:01:48 -04:00
committed by GitHub
parent 68f87f7254
commit 97f8d0f265
123 changed files with 1291 additions and 1081 deletions
+4 -13
View File
@@ -21,10 +21,7 @@
[ [
"transform-inline-environment-variables", "transform-inline-environment-variables",
{ {
"include": [ "include": ["SOURCE_COMMIT", "SOURCE_VERSION"]
"SOURCE_COMMIT",
"SOURCE_VERSION"
]
} }
], ],
"tsconfig-paths-module-resolver" "tsconfig-paths-module-resolver"
@@ -39,16 +36,10 @@
} }
] ]
], ],
"ignore": [ "ignore": ["**/__mocks__", "**/*.test.ts"]
"**/__mocks__",
"**/*.test.ts"
]
}, },
"development": { "development": {
"ignore": [ "ignore": ["**/__mocks__", "**/*.test.ts"]
"**/__mocks__",
"**/*.test.ts"
]
}, },
"test": { "test": {
"presets": [ "presets": [
@@ -65,4 +56,4 @@
] ]
} }
} }
} }
+1 -8
View File
@@ -15,7 +15,7 @@
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
"plugin:import/recommended", "plugin:import/recommended",
"plugin:import/typescript", "plugin:import/typescript",
"plugin:prettier/recommended" "prettier"
], ],
"plugins": [ "plugins": [
"es", "es",
@@ -162,13 +162,6 @@
} }
] ]
} }
],
"prettier/prettier": [
"error",
{
"printWidth": 80,
"trailingComma": "es5"
}
] ]
}, },
"settings": { "settings": {
+56 -56
View File
@@ -2,62 +2,62 @@ name: Bug report
description: File a bug to help us improve description: File a bug to help us improve
labels: ["bug"] labels: ["bug"]
body: body:
- type: checkboxes - type: checkboxes
attributes: attributes:
label: Is there an existing issue for this? label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered. description: Please search to see if an issue already exists for the bug you encountered.
options: options:
- label: I have searched the existing issues - label: I have searched the existing issues
required: true required: true
- type: checkboxes - type: checkboxes
attributes: attributes:
label: This is not related to configuring Outline label: This is not related to configuring Outline
description: I understand that questions related to configuring self-hosted Outline should be asked in the [community forum](https://github.com/outline/outline/discussions/categories/self-hosting). description: I understand that questions related to configuring self-hosted Outline should be asked in the [community forum](https://github.com/outline/outline/discussions/categories/self-hosting).
options: options:
- label: The issue is not related to self-hosting config - label: The issue is not related to self-hosting config
required: true required: true
- type: textarea - type: textarea
attributes: attributes:
label: Current Behavior label: Current Behavior
description: A concise description of what you're experiencing. description: A concise description of what you're experiencing.
validations: validations:
required: false required: false
- type: textarea - type: textarea
attributes: attributes:
label: Expected Behavior label: Expected Behavior
description: A concise description of what you expected to happen. description: A concise description of what you expected to happen.
validations: validations:
required: false required: false
- type: textarea - type: textarea
attributes: attributes:
label: Steps To Reproduce label: Steps To Reproduce
description: Steps to reproduce the behavior. description: Steps to reproduce the behavior.
placeholder: | placeholder: |
1. In this environment... 1. In this environment...
1. With this config... 1. With this config...
1. Run '...' 1. Run '...'
1. See error... 1. See error...
validations: validations:
required: false required: false
- type: textarea - type: textarea
attributes: attributes:
label: Environment label: Environment
description: | description: |
examples: examples:
- **Outline**: Outline 0.80.0 - **Outline**: Outline 0.80.0
- **Browser**: Safari - **Browser**: Safari
value: | value: |
- Outline: - Outline:
- Browser: - Browser:
render: markdown render: markdown
validations: validations:
required: false required: false
- type: textarea - type: textarea
attributes: attributes:
label: Anything else? label: Anything else?
description: | description: |
Links? References? Anything that will give us more context about the issue you are encountering! Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in. Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations: validations:
required: false required: false
+2 -2
View File
@@ -2,9 +2,9 @@
addReviewers: true addReviewers: true
# A list of reviewers to be added to pull requests (GitHub user name) # A list of reviewers to be added to pull requests (GitHub user name)
reviewers: reviewers:
- tommoor - tommoor
# A list of keywords to be skipped the process that add reviewers if pull requests include it # A list of keywords to be skipped the process that add reviewers if pull requests include it
skipKeywords: skipKeywords:
- wip - wip
+1 -1
View File
@@ -2,7 +2,7 @@ name: Auto Close Unsigned PRs
on: on:
schedule: schedule:
- cron: '0 0 * * *' # Run daily at midnight UTC - cron: "0 0 * * *" # Run daily at midnight UTC
jobs: jobs:
close-unsigned-prs: close-unsigned-prs:
+60 -60
View File
@@ -2,9 +2,9 @@ name: CI
on: on:
push: push:
branches: [ main ] branches: [main]
pull_request: pull_request:
branches: [ main ] branches: [main]
env: env:
NODE_ENV: test NODE_ENV: test
@@ -25,39 +25,39 @@ jobs:
node-version: [20.x, 22.x] node-version: [20.x, 22.x]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }} - name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: ${{ matrix.node-version }} node-version: ${{ matrix.node-version }}
cache: 'yarn' cache: "yarn"
- name: Install dependencies - name: Install dependencies
run: yarn install --frozen-lockfile run: yarn install --frozen-lockfile
lint: lint:
needs: build needs: build
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22.x node-version: 22.x
cache: 'yarn' cache: "yarn"
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn lint - run: yarn lint
types: types:
needs: build needs: build
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22.x node-version: 22.x
cache: 'yarn' cache: "yarn"
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn tsc - run: yarn tsc
changes: changes:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -89,13 +89,13 @@ jobs:
matrix: matrix:
test-group: [app, shared] test-group: [app, shared]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22.x node-version: 22.x
cache: 'yarn' cache: "yarn"
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn test:${{ matrix.test-group }} - run: yarn test:${{ matrix.test-group }}
test-server: test-server:
needs: [build, changes] needs: [build, changes]
@@ -115,7 +115,7 @@ jobs:
--health-interval 10s --health-interval 10s
--health-timeout 5s --health-timeout 5s
--health-retries 5 --health-retries 5
redis: redis:
image: redis:5.0 image: redis:5.0
ports: ports:
@@ -129,37 +129,37 @@ jobs:
strategy: strategy:
matrix: matrix:
shard: [1, 2, 3] shard: [1, 2, 3]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22.x node-version: 22.x
cache: 'yarn' cache: "yarn"
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn sequelize db:migrate - run: yarn sequelize db:migrate
- name: Run server tests - name: Run server tests
run: | run: |
TESTFILES=$(find . -name "*.test.ts" -path "*/server/*" | sort | split -n -d -l $(($(find . -name "*.test.ts" -path "*/server/*" | wc -l)/${{ matrix.shard }})) - | sed -n "${{ matrix.shard }}p") TESTFILES=$(find . -name "*.test.ts" -path "*/server/*" | sort | split -n -d -l $(($(find . -name "*.test.ts" -path "*/server/*" | wc -l)/${{ matrix.shard }})) - | sed -n "${{ matrix.shard }}p")
yarn test --maxWorkers=2 $TESTFILES yarn test --maxWorkers=2 $TESTFILES
bundle-size: bundle-size:
needs: [build, types, changes] needs: [build, types, changes]
if: ${{ needs.changes.outputs.app == 'true' && github.repository == 'outline/outline' }} if: ${{ needs.changes.outputs.app == 'true' && github.repository == 'outline/outline' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 22.x node-version: 22.x
cache: 'yarn' cache: "yarn"
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- name: Set environment to production - name: Set environment to production
run: echo "NODE_ENV=production" >> $GITHUB_ENV run: echo "NODE_ENV=production" >> $GITHUB_ENV
- run: yarn vite:build - run: yarn vite:build
- name: Send bundle stats to RelativeCI - name: Send bundle stats to RelativeCI
uses: relative-ci/agent-action@v2 uses: relative-ci/agent-action@v2
with: with:
key: ${{ secrets.RELATIVE_CI_KEY }} key: ${{ secrets.RELATIVE_CI_KEY }}
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
webpackStatsFile: ./build/app/webpack-stats.json webpackStatsFile: ./build/app/webpack-stats.json
+29 -29
View File
@@ -13,12 +13,12 @@ name: "CodeQL"
on: on:
push: push:
branches: [ main ] branches: [main]
pull_request: pull_request:
# The branches below must be a subset of the branches above # The branches below must be a subset of the branches above
branches: [ main ] branches: [main]
schedule: schedule:
- cron: '28 15 * * 2' - cron: "28 15 * * 2"
jobs: jobs:
analyze: analyze:
@@ -32,39 +32,39 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
language: [ 'javascript' ] language: ["javascript"]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support # Learn more about CodeQL language support at https://git.io/codeql-language-support
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v2 uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file. # By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file. # Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main # queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell. # ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl # 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project # and modify them (or add more) to build your code if your project
# uses a compiled language # uses a compiled language
#- run: | #- run: |
# make bootstrap # make bootstrap
# make release # make release
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v2
+1 -1
View File
@@ -209,4 +209,4 @@ jobs:
- name: Inspect image - name: Inspect image
run: | run: |
docker buildx imagetools inspect ${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} docker buildx imagetools inspect ${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
+3 -3
View File
@@ -2,7 +2,7 @@ name: Lint
on: on:
pull_request: pull_request:
branches: [ main ] branches: [main]
jobs: jobs:
run-linters: run-linters:
@@ -20,11 +20,11 @@ jobs:
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 20.x node-version: 20.x
cache: 'yarn' cache: "yarn"
- run: yarn install --frozen-lockfile - run: yarn install --frozen-lockfile
- run: yarn lint --fix - run: yarn lint --fix
- name: Commit changes - name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5 uses: stefanzweifel/git-auto-commit-action@v5
with: with:
commit_message: 'Applied automatic fixes' commit_message: "Applied automatic fixes"
+4
View File
@@ -0,0 +1,4 @@
{
"printWidth": 80,
"trailingComma": "es5"
}
+1 -1
View File
@@ -1 +1 @@
export default ''; export default "";
+5 -5
View File
@@ -1,19 +1,19 @@
const storage = {}; const storage = {};
export default { export default {
setItem: function(key, value) { setItem: function (key, value) {
storage[key] = value || ''; storage[key] = value || "";
}, },
getItem: function(key) { getItem: function (key) {
return key in storage ? storage[key] : null; return key in storage ? storage[key] : null;
}, },
removeItem: function(key) { removeItem: function (key) {
delete storage[key]; delete storage[key];
}, },
get length() { get length() {
return Object.keys(storage).length; return Object.keys(storage).length;
}, },
key: function(i) { key: function (i) {
var keys = Object.keys(storage); var keys = Object.keys(storage);
return keys[i] || null; return keys[i] || null;
}, },
+2 -8
View File
@@ -3,13 +3,7 @@
"description": "Open source wiki and knowledge base for growing teams", "description": "Open source wiki and knowledge base for growing teams",
"website": "https://www.getoutline.com/", "website": "https://www.getoutline.com/",
"repository": "https://github.com/outline/outline", "repository": "https://github.com/outline/outline",
"keywords": [ "keywords": ["wiki", "team", "node", "markdown", "slack"],
"wiki",
"team",
"node",
"markdown",
"slack"
],
"success_url": "/", "success_url": "/",
"formation": { "formation": {
"web": { "web": {
@@ -222,4 +216,4 @@
"required": false "required": false
} }
} }
} }
+5 -5
View File
@@ -1,12 +1,12 @@
/* eslint-disable */ /* eslint-disable */
import stores from "~/stores"; import stores from "~/stores";
describe('Collection model', () => { describe("Collection model", () => {
test('should initialize with data', () => { test("should initialize with data", () => {
const collection = stores.collections.add({ const collection = stores.collections.add({
id: "123", id: "123",
name: 'Engineering' name: "Engineering",
}); });
expect(collection.name).toBe('Engineering'); expect(collection.name).toBe("Engineering");
}); });
}); });
+11 -9
View File
@@ -1,11 +1,13 @@
/* eslint-disable */ /* eslint-disable */
export const client = { export const client = {
post: jest.fn(() => Promise.resolve({ post: jest.fn(() =>
data: { Promise.resolve({
user: {}, data: {
team: {}, user: {},
groups: [], team: {},
groupUsers: [], groups: [],
} groupUsers: [],
})) },
})
),
}; };
+2 -2
View File
@@ -1,5 +1,5 @@
commit_message: 'fix: New %language% translations from Crowdin [ci skip]' commit_message: "fix: New %language% translations from Crowdin [ci skip]"
append_commit_message: append_commit_message:
files: files:
- source: /shared/i18n/locales/en_US/translation.json - source: /shared/i18n/locales/en_US/translation.json
translation: /shared/i18n/locales/%locale_with_underscore%/translation.json translation: /shared/i18n/locales/%locale_with_underscore%/translation.json
+10 -10
View File
@@ -8,19 +8,19 @@ In the interest of fostering an open and welcoming environment, we as contributo
Examples of behavior that contributes to creating a positive environment include: Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language - Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences - Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism - Gracefully accepting constructive criticism
* Focusing on what is best for the community - Focusing on what is best for the community
* Showing empathy towards other community members - Showing empathy towards other community members
Examples of unacceptable behavior by participants include: Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances - The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks - Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment - Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission - Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting - Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities ## Our Responsibilities
+3 -3
View File
@@ -32,14 +32,14 @@ At least one worker process is required to process the [queues](../server/queues
## Collaboration ## Collaboration
The collaboration server coordinates all realtime editing and updating of documents, The collaboration server coordinates all realtime editing and updating of documents,
it can be ran on the same box as the web server or separately. it can be ran on the same box as the web server or separately.
```bash ```bash
yarn start --services=collaboration yarn start --services=collaboration
``` ```
If the collaboration service is hosted on a separate domain then the `COLLABORATION_URL` If the collaboration service is hosted on a separate domain then the `COLLABORATION_URL`
env must be set to the publicly accessible URL. For example, if the app is hosted at env must be set to the publicly accessible URL. For example, if the app is hosted at
`https://docs.example.com` you may use something like: `https://docs.example.com` you may use something like:
`COLLABORATION_URL=wss://docs-collaboration.example.com`. `COLLABORATION_URL=wss://docs-collaboration.example.com`.
+3 -3
View File
@@ -1,6 +1,6 @@
# Translation # Translation
Outline is localized through community contributions. The text in Outline's user interface is in American English by default, we're very thankful for all help that the community provides bringing the app to different languages. Outline is localized through community contributions. The text in Outline's user interface is in American English by default, we're very thankful for all help that the community provides bringing the app to different languages.
## Externalizing strings ## Externalizing strings
@@ -17,7 +17,7 @@ To manage the translation process we use [CrowdIn](https://translate.getoutline.
You'll need to create a free account to use CrowdIn. Once you have joined, you can provide translations by following these steps: You'll need to create a free account to use CrowdIn. Once you have joined, you can provide translations by following these steps:
1. Select the language for which you want to contribute (or vote for) a translation (below the language you can see the progress of the translation) 1. Select the language for which you want to contribute (or vote for) a translation (below the language you can see the progress of the translation)
![CrowdIn UI](https://i.imgur.com/AkbDY60.png) ![CrowdIn UI](https://i.imgur.com/AkbDY60.png)
2. Please choose the translation.json file from your desired language 2. Please choose the translation.json file from your desired language
@@ -31,4 +31,4 @@ If you are interested in becoming a proof reader, please contact one of the proj
## Release ## Release
Updated translations are automatically PR'd against the codebase by a bot and will be merged regularly so that new translations appear in the next release of Outline. Updated translations are automatically PR'd against the codebase by a bot and will be merged regularly so that new translations appear in the next release of Outline.
+2 -1
View File
@@ -1,7 +1,8 @@
export default { export default {
// Efficiently run prettier and translation updates on changes to JS and // Run prettier first for formatting, then eslint for linting, and translation updates on changes to JS and
// TypeScript files // TypeScript files
"**/*.[tj]s?(x)": [ "**/*.[tj]s?(x)": [
(f) => `prettier --write ${f.join(" ")}`,
(f) => (f.length > 20 ? `yarn lint --fix` : `eslint ${f.join(" ")} --fix`), (f) => (f.length > 20 ? `yarn lint --fix` : `eslint ${f.join(" ")} --fix`),
() => `yarn build:i18n`, () => `yarn build:i18n`,
() => "git add shared/i18n/locales/en_US/translation.json", () => "git add shared/i18n/locales/en_US/translation.json",
+2 -1
View File
@@ -15,6 +15,8 @@
"dev:watch": "NODE_ENV=development yarn concurrently -n backend,frontend \"yarn dev:backend\" \"yarn vite:dev\"", "dev:watch": "NODE_ENV=development yarn concurrently -n backend,frontend \"yarn dev:backend\" \"yarn vite:dev\"",
"lint": "eslint app server shared plugins", "lint": "eslint app server shared plugins",
"lint:changed": "git diff --name-only --diff-filter=ACMRTUXB | grep -E '\\.(js|jsx|ts|tsx)$' | xargs -r yarn eslint --fix", "lint:changed": "git diff --name-only --diff-filter=ACMRTUXB | grep -E '\\.(js|jsx|ts|tsx)$' | xargs -r yarn eslint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"prepare": "husky install", "prepare": "husky install",
"postinstall": "yarn patch-package", "postinstall": "yarn patch-package",
"install-local-ssl": "node ./server/scripts/install-local-ssl.js", "install-local-ssl": "node ./server/scripts/install-local-ssl.js",
@@ -356,7 +358,6 @@
"eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-lodash": "^7.4.0", "eslint-plugin-lodash": "^7.4.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.5.1",
"eslint-plugin-react": "^7.37.5", "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-hooks": "^4.6.2",
"husky": "^8.0.3", "husky": "^8.0.3",
+5 -5
View File
@@ -1,6 +1,6 @@
{ {
"id": "discord", "id": "discord",
"name": "Discord", "name": "Discord",
"priority": 10, "priority": 10,
"description": "Adds a Discord authentication provider." "description": "Adds a Discord authentication provider."
} }
+1 -1
View File
@@ -2,4 +2,4 @@
"id": "notion", "id": "notion",
"name": "Notion", "name": "Notion",
"description": "Adds a Notion integration for importing data." "description": "Adds a Notion integration for importing data."
} }
+2 -5
View File
@@ -3,8 +3,5 @@
"name": "Umami", "name": "Umami",
"priority": 50, "priority": 50,
"description": "Adds support for reporting analytics to a Umami server.", "description": "Adds support for reporting analytics to a Umami server.",
"deployments": [ "deployments": ["community", "enterprise"]
"community", }
"enterprise"
]
}
@@ -1,8 +1,7 @@
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
const [teams, metaData] = await queryInterface.sequelize.query( const [teams, metaData] =
`SELECT * FROM teams` await queryInterface.sequelize.query(`SELECT * FROM teams`);
);
const teamIds = teams.map((team) => team.id); const teamIds = teams.map((team) => team.id);
await Promise.all( await Promise.all(
@@ -2,12 +2,15 @@
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.removeIndex("documents", "documents_id_atlas_id_deleted_at"); await queryInterface.removeIndex(
"documents",
"documents_id_atlas_id_deleted_at"
);
await queryInterface.removeIndex("apiKeys", "api_keys_secret_deleted_at"); await queryInterface.removeIndex("apiKeys", "api_keys_secret_deleted_at");
await queryInterface.removeIndex("groups", "groups_deleted_at"); await queryInterface.removeIndex("groups", "groups_deleted_at");
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
// noop // noop
} },
}; };
+18 -13
View File
@@ -57,10 +57,13 @@ module.exports = {
await queryInterface.addIndex("pins", ["collectionId"]); await queryInterface.addIndex("pins", ["collectionId"]);
const createdAt = new Date(); const createdAt = new Date();
const [documents] = await queryInterface.sequelize.query(`SELECT "id","collectionId","teamId","pinnedById" FROM documents WHERE "pinnedById" IS NOT NULL`); const [documents] = await queryInterface.sequelize.query(
`SELECT "id","collectionId","teamId","pinnedById" FROM documents WHERE "pinnedById" IS NOT NULL`
);
for (const document of documents) { for (const document of documents) {
await queryInterface.sequelize.query(` await queryInterface.sequelize.query(
`
INSERT INTO pins ( INSERT INTO pins (
"id", "id",
"documentId", "documentId",
@@ -79,17 +82,19 @@ module.exports = {
:createdAt, :createdAt,
:updatedAt :updatedAt
) )
`, { `,
replacements: { {
id: v4(), replacements: {
documentId: document.id, id: v4(),
collectionId: document.collectionId, documentId: document.id,
teamId: document.teamId, collectionId: document.collectionId,
createdById: document.pinnedById, teamId: document.teamId,
updatedAt: createdAt, createdById: document.pinnedById,
createdAt, updatedAt: createdAt,
}, createdAt,
}); },
}
);
} }
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
@@ -26,16 +26,28 @@ module.exports = {
// somehow these indexes were being used sometimes, but i'll never know how. // somehow these indexes were being used sometimes, but i'll never know how.
// Note: These are not recreated in the down method // Note: These are not recreated in the down method
await queryInterface.removeIndex("documents", "documents_id_atlas_id_published_at"); await queryInterface.removeIndex(
await queryInterface.removeIndex("documents", "documents_id_team_id_deleted_at"); "documents",
"documents_id_atlas_id_published_at"
);
await queryInterface.removeIndex(
"documents",
"documents_id_team_id_deleted_at"
);
await queryInterface.removeIndex("documents", "documents_id_deleted_at"); await queryInterface.removeIndex("documents", "documents_id_deleted_at");
await queryInterface.removeIndex("collections", "atlases_id_deleted_at"); await queryInterface.removeIndex("collections", "atlases_id_deleted_at");
await queryInterface.removeIndex("collections", "atlases_id_team_id_deleted_at"); await queryInterface.removeIndex(
"collections",
"atlases_id_team_id_deleted_at"
);
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
await queryInterface.removeIndex("views", "views_last_editing_at"); await queryInterface.removeIndex("views", "views_last_editing_at");
await queryInterface.removeIndex("pins", "pins_team_id"); await queryInterface.removeIndex("pins", "pins_team_id");
await queryInterface.removeIndex("collections", "collections_team_id_deleted_at"); await queryInterface.removeIndex(
"collections",
"collections_team_id_deleted_at"
);
await queryInterface.removeIndex("stars", "stars_user_id_document_id"); await queryInterface.removeIndex("stars", "stars_user_id_document_id");
await queryInterface.removeIndex("documents", "documents_collection_id"); await queryInterface.removeIndex("documents", "documents_collection_id");
await queryInterface.removeIndex("documents", "documents_published_at"); await queryInterface.removeIndex("documents", "documents_published_at");
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -11,5 +11,5 @@ module.exports = {
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn("teams", "defaultCollectionId"); await queryInterface.removeColumn("teams", "defaultCollectionId");
} },
}; };
@@ -6,58 +6,58 @@ module.exports = {
id: { id: {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false, allowNull: false,
primaryKey: true primaryKey: true,
}, },
data: { data: {
type: Sequelize.JSONB, type: Sequelize.JSONB,
allowNull: false allowNull: false,
}, },
documentId: { documentId: {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false, allowNull: false,
onDelete: "cascade", onDelete: "cascade",
references: { references: {
model: "documents" model: "documents",
} },
}, },
parentCommentId: { parentCommentId: {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
onDelete: "cascade", onDelete: "cascade",
references: { references: {
model: "comments" model: "comments",
} },
}, },
createdById: { createdById: {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false, allowNull: false,
references: { references: {
model: "users" model: "users",
} },
}, },
resolvedAt: { resolvedAt: {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: true allowNull: true,
}, },
resolvedById: { resolvedById: {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
references: { references: {
model: "users" model: "users",
} },
}, },
createdAt: { createdAt: {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: false allowNull: false,
}, },
updatedAt: { updatedAt: {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: false allowNull: false,
}, },
deletedAt: { deletedAt: {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: true allowNull: true,
} },
}); });
await queryInterface.addIndex("comments", ["documentId"]); await queryInterface.addIndex("comments", ["documentId"]);
@@ -66,5 +66,5 @@ module.exports = {
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
queryInterface.dropTable("comments"); queryInterface.dropTable("comments");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -16,6 +16,9 @@ module.exports = {
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeIndex("views", "views_updated_at"); await queryInterface.removeIndex("views", "views_updated_at");
await queryInterface.removeIndex("views", "views_user_id"); await queryInterface.removeIndex("views", "views_user_id");
await queryInterface.removeIndex("collection_users", "collection_users_user_id"); await queryInterface.removeIndex(
} "collection_users",
"collection_users_user_id"
);
},
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -9,5 +9,5 @@ module.exports = {
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeIndex("events", "events_created_at"); await queryInterface.removeIndex("events", "events_created_at");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -11,5 +11,5 @@ module.exports = {
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn("teams", "memberCollectionCreate"); await queryInterface.removeColumn("teams", "memberCollectionCreate");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -8,7 +8,7 @@ module.exports = {
allowNull: true, allowNull: true,
references: { references: {
model: "shares", model: "shares",
key: "id" key: "id",
}, },
}); });
}, },
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -23,7 +23,7 @@ module.exports = {
}); });
await queryInterface.changeColumn("stars", "documentId", { await queryInterface.changeColumn("stars", "documentId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true allowNull: true,
}); });
await queryInterface.changeColumn("stars", "documentId", { await queryInterface.changeColumn("stars", "documentId", {
type: Sequelize.UUID, type: Sequelize.UUID,
@@ -46,9 +46,9 @@ module.exports = {
await queryInterface.removeColumn("stars", "collectionId"); await queryInterface.removeColumn("stars", "collectionId");
await queryInterface.changeColumn("stars", "documentId", { await queryInterface.changeColumn("stars", "documentId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false allowNull: false,
}); });
await queryInterface.removeConstraint("stars", "stars_documentId_fkey") await queryInterface.removeConstraint("stars", "stars_documentId_fkey");
await queryInterface.removeConstraint("stars", "stars_userId_fkey") await queryInterface.removeConstraint("stars", "stars_userId_fkey");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -10,5 +10,5 @@ module.exports = {
down: async (queryInterface) => { down: async (queryInterface) => {
return queryInterface.removeColumn("users", "flags"); return queryInterface.removeColumn("users", "flags");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -13,5 +13,5 @@ module.exports = {
down: async (queryInterface) => { down: async (queryInterface) => {
return queryInterface.removeColumn("users", "invitedById"); return queryInterface.removeColumn("users", "invitedById");
} },
}; };
@@ -1,11 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn("teams", "inviteRequired", { await queryInterface.addColumn("teams", "inviteRequired", {
type: Sequelize.BOOLEAN, type: Sequelize.BOOLEAN,
defaultValue: false, defaultValue: false,
allowNull: false allowNull: false,
}); });
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
@@ -5,65 +5,80 @@ const { v4 } = require("uuid");
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.createTable("team_domains", { await queryInterface.createTable(
id: { "team_domains",
type: Sequelize.UUID, {
allowNull: false, id: {
primaryKey: true, type: Sequelize.UUID,
}, allowNull: false,
teamId: { primaryKey: true,
type: Sequelize.UUID, },
allowNull: false, teamId: {
onDelete: "cascade", type: Sequelize.UUID,
references: { allowNull: false,
model: "teams", onDelete: "cascade",
references: {
model: "teams",
},
},
createdById: {
type: Sequelize.UUID,
allowNull: false,
references: {
model: "users",
},
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
}, },
}, },
createdById: { {
type: Sequelize.UUID, transaction,
allowNull: false, }
references: { );
model: "users",
},
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
allowNull: false,
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false,
},
}, {
transaction
});
await queryInterface.addIndex("team_domains", ["teamId", "name"], { await queryInterface.addIndex("team_domains", ["teamId", "name"], {
transaction, transaction,
unique: true, unique: true,
}); });
const currentAllowedDomainsEnv = process.env.ALLOWED_DOMAINS || process.env.GOOGLE_ALLOWED_DOMAINS; const currentAllowedDomainsEnv =
const currentAllowedDomains = currentAllowedDomainsEnv ? currentAllowedDomainsEnv.split(",") : []; process.env.ALLOWED_DOMAINS || process.env.GOOGLE_ALLOWED_DOMAINS;
const currentAllowedDomains = currentAllowedDomainsEnv
? currentAllowedDomainsEnv.split(",")
: [];
if (currentAllowedDomains.length > 0) { if (currentAllowedDomains.length > 0) {
const [adminUserIDs] = await queryInterface.sequelize.query('select id from users where "isAdmin" = true limit 1', { transaction }) const [adminUserIDs] = await queryInterface.sequelize.query(
const adminUserID = adminUserIDs[0]?.id 'select id from users where "isAdmin" = true limit 1',
{ transaction }
);
const adminUserID = adminUserIDs[0]?.id;
if (adminUserID) { if (adminUserID) {
const [teams] = await queryInterface.sequelize.query('select id from teams', { transaction }) const [teams] = await queryInterface.sequelize.query(
"select id from teams",
{ transaction }
);
const now = new Date(); const now = new Date();
for (const team of teams) { for (const team of teams) {
for (const domain of currentAllowedDomains) { for (const domain of currentAllowedDomains) {
await queryInterface.sequelize.query(` await queryInterface.sequelize.query(
`
INSERT INTO team_domains ("id", "teamId", "createdById", "name", "createdAt", "updatedAt") INSERT INTO team_domains ("id", "teamId", "createdById", "name", "createdAt", "updatedAt")
VALUES (:id, :teamId, :createdById, :name, :createdAt, :updatedAt) VALUES (:id, :teamId, :createdById, :name, :createdAt, :updatedAt)
`, { `,
{
replacements: { replacements: {
id: v4(), id: v4(),
teamId: team.id, teamId: team.id,
@@ -1,11 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn("file_operations", "format", { await queryInterface.addColumn("file_operations", "format", {
type: Sequelize.STRING, type: Sequelize.STRING,
defaultValue: "outline-markdown", defaultValue: "outline-markdown",
allowNull: false allowNull: false,
}); });
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
@@ -1,23 +1,26 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface) => { up: async (queryInterface) => {
let again = 1; let again = 1;
while (again) { while (again) {
console.log("Backfilling collection sort…"); console.log("Backfilling collection sort…");
const [, metadata] = await queryInterface.sequelize.query(` const [, metadata] = await queryInterface.sequelize.query(
`
WITH rows AS ( WITH rows AS (
SELECT id FROM collections WHERE "sort" IS NULL ORDER BY id LIMIT 1000 SELECT id FROM collections WHERE "sort" IS NULL ORDER BY id LIMIT 1000
) )
UPDATE collections UPDATE collections
SET "sort" = :sort::jsonb SET "sort" = :sort::jsonb
WHERE EXISTS (SELECT * FROM rows WHERE collections.id = rows.id) WHERE EXISTS (SELECT * FROM rows WHERE collections.id = rows.id)
`, { `,
replacements: { {
sort: JSON.stringify({ field: "title", direction: "asc" }), replacements: {
sort: JSON.stringify({ field: "title", direction: "asc" }),
},
} }
}); );
again = metadata.rowCount; again = metadata.rowCount;
} }
@@ -25,5 +28,5 @@ WHERE EXISTS (SELECT * FROM rows WHERE collections.id = rows.id)
down: async () => { down: async () => {
// cannot be undone // cannot be undone
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -6,13 +6,17 @@ module.exports = {
await queryInterface.addColumn("user_authentications", "expiresAt", { await queryInterface.addColumn("user_authentications", "expiresAt", {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: true, allowNull: true,
transaction transaction,
});
await queryInterface.addColumn("user_authentications", "lastValidatedAt", {
type: Sequelize.DATE,
allowNull: true,
transaction
}); });
await queryInterface.addColumn(
"user_authentications",
"lastValidatedAt",
{
type: Sequelize.DATE,
allowNull: true,
transaction,
}
);
}); });
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
@@ -21,12 +25,12 @@ module.exports = {
"user_authentications", "user_authentications",
"lastValidatedAt", "lastValidatedAt",
{ {
transaction transaction,
} }
); );
await queryInterface.removeColumn("user_authentications", "expiresAt", { await queryInterface.removeColumn("user_authentications", "expiresAt", {
transaction transaction,
}); });
}); });
}, },
}; };
@@ -1,10 +1,10 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn("webhook_subscriptions", "deletedAt", { await queryInterface.addColumn("webhook_subscriptions", "deletedAt", {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: true allowNull: true,
}); });
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up(queryInterface) { async up(queryInterface) {
@@ -16,7 +16,9 @@ module.exports = {
); );
if (teams[0].count > 0 && authenticationProviders[0].count === 0) { if (teams[0].count > 0 && authenticationProviders[0].count === 0) {
throw Error("Refusing to destroy deprecated columns without authentication providers"); throw Error(
"Refusing to destroy deprecated columns without authentication providers"
);
} }
} }
@@ -34,28 +36,28 @@ module.exports = {
type: Sequelize.STRING(4096), type: Sequelize.STRING(4096),
allowNull: false, allowNull: false,
defaultValue: "", defaultValue: "",
transaction transaction,
}); });
await queryInterface.addColumn("users", "service", { await queryInterface.addColumn("users", "service", {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: true, allowNull: true,
transaction transaction,
}); });
await queryInterface.addColumn("users", "serviceId", { await queryInterface.addColumn("users", "serviceId", {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: true, allowNull: true,
transaction transaction,
}); });
await queryInterface.addColumn("teams", "slackId", { await queryInterface.addColumn("teams", "slackId", {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: true, allowNull: true,
transaction transaction,
}); });
await queryInterface.addColumn("teams", "googleId", { await queryInterface.addColumn("teams", "googleId", {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: true, allowNull: true,
transaction transaction,
}); });
}); });
} },
}; };
@@ -1,14 +1,14 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.removeColumn("events", "updatedAt"); await queryInterface.removeColumn("events", "updatedAt");
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.addColumn("events", "updatedAt", { await queryInterface.addColumn("events", "updatedAt", {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: false, allowNull: false,
defaultValue: Sequelize.fn('NOW'), defaultValue: Sequelize.fn("NOW"),
}); });
} },
}; };
@@ -1,21 +1,27 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.removeConstraint("authentication_providers", "authentication_providers_providerId_key"); await queryInterface.removeConstraint(
"authentication_providers",
"authentication_providers_providerId_key"
);
await queryInterface.addConstraint("authentication_providers", { await queryInterface.addConstraint("authentication_providers", {
type: 'unique', type: "unique",
fields: ["providerId", "teamId"], fields: ["providerId", "teamId"],
name: "authentication_providers_providerId_teamId_uk" name: "authentication_providers_providerId_teamId_uk",
}); });
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeConstraint("authentication_providers", "authentication_providers_providerId_teamId_uk"); await queryInterface.removeConstraint(
"authentication_providers",
"authentication_providers_providerId_teamId_uk"
);
await queryInterface.addConstraint("authentication_providers", { await queryInterface.addConstraint("authentication_providers", {
type: 'unique', type: "unique",
fields: ["providerId"], fields: ["providerId"],
name: "authentication_providers_providerId_key" name: "authentication_providers_providerId_key",
}); });
} },
}; };
@@ -1,21 +1,27 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.removeConstraint("user_authentications", "user_authentications_providerId_key"); await queryInterface.removeConstraint(
"user_authentications",
"user_authentications_providerId_key"
);
await queryInterface.addConstraint("user_authentications", { await queryInterface.addConstraint("user_authentications", {
type: 'unique', type: "unique",
fields: ["providerId", "userId"], fields: ["providerId", "userId"],
name: "user_authentications_providerId_userId_uk" name: "user_authentications_providerId_userId_uk",
}); });
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeConstraint("user_authentications", "user_authentications_providerId_userId_uk"); await queryInterface.removeConstraint(
"user_authentications",
"user_authentications_providerId_userId_uk"
);
await queryInterface.addConstraint("user_authentications", { await queryInterface.addConstraint("user_authentications", {
type: 'unique', type: "unique",
fields: ["providerId"], fields: ["providerId"],
name: "user_authentications_providerId_key" name: "user_authentications_providerId_key",
}); });
} },
}; };
@@ -1,11 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface) { async up(queryInterface) {
await queryInterface.addIndex("users", ["email"]); await queryInterface.addIndex("users", ["email"]);
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeIndex("users", ["email"]); await queryInterface.removeIndex("users", ["email"]);
} },
}; };
@@ -1,10 +1,10 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn("shares", "views", { await queryInterface.addColumn("shares", "views", {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
defaultValue: 0 defaultValue: 0,
}); });
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
@@ -1,14 +1,14 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
return queryInterface.addColumn("users", "preferences", { return queryInterface.addColumn("users", "preferences", {
type: Sequelize.JSONB, type: Sequelize.JSONB,
allowNull: true, allowNull: true,
}); });
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
return queryInterface.removeColumn("users", "preferences"); return queryInterface.removeColumn("users", "preferences");
} },
}; };
@@ -1,12 +1,28 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeConstraint("notifications", "notifications_userId_fkey", { transaction }) await queryInterface.removeConstraint(
await queryInterface.removeConstraint("notifications", "notifications_actorId_fkey", { transaction }) "notifications",
await queryInterface.removeConstraint("notifications", "notifications_teamId_fkey", { transaction }) "notifications_userId_fkey",
await queryInterface.removeConstraint("notifications", "notifications_documentId_fkey", { transaction }) { transaction }
);
await queryInterface.removeConstraint(
"notifications",
"notifications_actorId_fkey",
{ transaction }
);
await queryInterface.removeConstraint(
"notifications",
"notifications_teamId_fkey",
{ transaction }
);
await queryInterface.removeConstraint(
"notifications",
"notifications_documentId_fkey",
{ transaction }
);
}); });
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.changeColumn("notifications", "userId", { await queryInterface.changeColumn("notifications", "userId", {
@@ -49,10 +65,26 @@ module.exports = {
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeConstraint("notifications", "notifications_userId_fkey", { transaction }) await queryInterface.removeConstraint(
await queryInterface.removeConstraint("notifications", "notifications_actorId_fkey", { transaction }) "notifications",
await queryInterface.removeConstraint("notifications", "notifications_teamId_fkey", { transaction }) "notifications_userId_fkey",
await queryInterface.removeConstraint("notifications", "notifications_documentId_fkey", { transaction }) { transaction }
);
await queryInterface.removeConstraint(
"notifications",
"notifications_actorId_fkey",
{ transaction }
);
await queryInterface.removeConstraint(
"notifications",
"notifications_teamId_fkey",
{ transaction }
);
await queryInterface.removeConstraint(
"notifications",
"notifications_documentId_fkey",
{ transaction }
);
}); });
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.changeColumn("notifications", "userId", { await queryInterface.changeColumn("notifications", "userId", {
@@ -87,5 +119,5 @@ module.exports = {
transaction, transaction,
}); });
}); });
} },
}; };
@@ -1,14 +1,14 @@
"use strict"; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
return queryInterface.addColumn("webhook_subscriptions", "secret", { return queryInterface.addColumn("webhook_subscriptions", "secret", {
type: Sequelize.BLOB, type: Sequelize.BLOB,
allowNull: true, allowNull: true,
}); });
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
return queryInterface.removeColumn("webhook_subscriptions", "secret"); return queryInterface.removeColumn("webhook_subscriptions", "secret");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -29,5 +29,5 @@ module.exports = {
transaction, transaction,
}); });
}); });
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -15,5 +15,5 @@ module.exports = {
await queryInterface.changeColumn("users", "teamId", { await queryInterface.changeColumn("users", "teamId", {
type: Sequelize.UUID, type: Sequelize.UUID,
}); });
} },
}; };
@@ -20,29 +20,28 @@ module.exports = {
transaction, transaction,
}); });
await queryInterface.addIndex("documents", ["importId"], { await queryInterface.addIndex("documents", ["importId"], {
transaction transaction,
}); });
await queryInterface.addIndex("collections", ["importId"], { await queryInterface.addIndex("collections", ["importId"], {
transaction transaction,
}); });
}); });
}, },
async down(queryInterface) { async down(queryInterface) {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeIndex("collections", ["importId"], { await queryInterface.removeIndex("collections", ["importId"], {
transaction transaction,
}); });
await queryInterface.removeIndex("documents", ["importId"], { await queryInterface.removeIndex("documents", ["importId"], {
transaction transaction,
}); });
await queryInterface.removeColumn("collections", "importId", { await queryInterface.removeColumn("collections", "importId", {
transaction transaction,
}); });
await queryInterface.removeColumn("documents", "importId", { await queryInterface.removeColumn("documents", "importId", {
transaction transaction,
}); });
}); });
} },
}; };
@@ -9,14 +9,18 @@ module.exports = {
transaction, transaction,
}); });
await queryInterface.addIndex("attachments", ["expiresAt"], { await queryInterface.addIndex("attachments", ["expiresAt"], {
transaction transaction,
}); });
}); });
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeColumn("attachments", "expiresAt", { transaction }); await queryInterface.removeColumn("attachments", "expiresAt", {
await queryInterface.removeIndex("attachments", ["expiresAt"], { transaction }); transaction,
});
await queryInterface.removeIndex("attachments", ["expiresAt"], {
transaction,
});
}); });
}, },
}; };
@@ -4,15 +4,11 @@ module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
try { try {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn( await queryInterface.addColumn("shares", "urlId", {
"shares", type: Sequelize.STRING,
"urlId", allowNull: true,
{ transaction,
type: Sequelize.STRING, });
allowNull: true,
transaction,
},
);
await queryInterface.addConstraint("shares", { await queryInterface.addConstraint("shares", {
fields: ["urlId", "teamId"], fields: ["urlId", "teamId"],
@@ -20,7 +16,7 @@ module.exports = {
transaction, transaction,
}); });
}); });
} catch(err) { } catch (err) {
throw err; throw err;
} }
}, },
@@ -1,8 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("webhook_subscriptions", "webhook_subscriptions_teamId_fkey") await queryInterface.removeConstraint(
"webhook_subscriptions",
"webhook_subscriptions_teamId_fkey"
);
await queryInterface.changeColumn("webhook_subscriptions", "teamId", { await queryInterface.changeColumn("webhook_subscriptions", "teamId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false, allowNull: false,
@@ -14,7 +17,10 @@ module.exports = {
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("webhook_subscriptions", "webhook_subscriptions_teamId_fkey") await queryInterface.removeConstraint(
"webhook_subscriptions",
"webhook_subscriptions_teamId_fkey"
);
await queryInterface.changeColumn("webhook_subscriptions", "teamId", { await queryInterface.changeColumn("webhook_subscriptions", "teamId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false, allowNull: false,
@@ -22,5 +28,5 @@ module.exports = {
model: "teams", model: "teams",
}, },
}); });
} },
}; };
@@ -1,8 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("integrations", "integrations_collectionId_fkey") await queryInterface.removeConstraint(
"integrations",
"integrations_collectionId_fkey"
);
await queryInterface.changeColumn("integrations", "collectionId", { await queryInterface.changeColumn("integrations", "collectionId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
@@ -11,7 +14,10 @@ module.exports = {
model: "collections", model: "collections",
}, },
}); });
await queryInterface.removeConstraint("integrations", "integrations_teamId_fkey") await queryInterface.removeConstraint(
"integrations",
"integrations_teamId_fkey"
);
await queryInterface.changeColumn("integrations", "teamId", { await queryInterface.changeColumn("integrations", "teamId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false, allowNull: false,
@@ -23,7 +29,10 @@ module.exports = {
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("integrations", "integrations_collectionId_fkey") await queryInterface.removeConstraint(
"integrations",
"integrations_collectionId_fkey"
);
await queryInterface.changeColumn("integrations", "collectionId", { await queryInterface.changeColumn("integrations", "collectionId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
@@ -31,7 +40,10 @@ module.exports = {
model: "collections", model: "collections",
}, },
}); });
await queryInterface.removeConstraint("integrations", "integrations_teamId_fkey") await queryInterface.removeConstraint(
"integrations",
"integrations_teamId_fkey"
);
await queryInterface.changeColumn("integrations", "teamId", { await queryInterface.changeColumn("integrations", "teamId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: false, allowNull: false,
@@ -39,5 +51,5 @@ module.exports = {
model: "teams", model: "teams",
}, },
}); });
} },
}; };
@@ -1,8 +1,8 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("stars", "stars_collectionId_fkey") await queryInterface.removeConstraint("stars", "stars_collectionId_fkey");
await queryInterface.changeColumn("stars", "collectionId", { await queryInterface.changeColumn("stars", "collectionId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
@@ -14,7 +14,7 @@ module.exports = {
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("stars", "stars_collectionId_fkey") await queryInterface.removeConstraint("stars", "stars_collectionId_fkey");
await queryInterface.changeColumn("stars", "collectionId", { await queryInterface.changeColumn("stars", "collectionId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
@@ -22,5 +22,5 @@ module.exports = {
model: "collections", model: "collections",
}, },
}); });
} },
}; };
@@ -1,11 +1,19 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addIndex("integrations", ["teamId", "type", "service"]); await queryInterface.addIndex("integrations", [
"teamId",
"type",
"service",
]);
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeIndex("integrations", ["teamId", "type", "service"]); await queryInterface.removeIndex("integrations", [
} "teamId",
"type",
"service",
]);
},
}; };
@@ -20,7 +20,7 @@ module.exports = {
"SELECT id FROM users", "SELECT id FROM users",
{ {
type: queryInterface.sequelize.QueryTypes.SELECT, type: queryInterface.sequelize.QueryTypes.SELECT,
transaction transaction,
} }
); );
@@ -30,12 +30,11 @@ module.exports = {
{ {
type: queryInterface.sequelize.QueryTypes.SELECT, type: queryInterface.sequelize.QueryTypes.SELECT,
replacements: { userId: user.id }, replacements: { userId: user.id },
transaction transaction,
} }
); );
const eventTypes = settings.map((setting) => setting.event); const eventTypes = settings.map((setting) => setting.event);
if (eventTypes.length > 0) { if (eventTypes.length > 0) {
const notificationSettings = {}; const notificationSettings = {};
@@ -52,7 +51,7 @@ module.exports = {
userId: user.id, userId: user.id,
notificationSettings: JSON.stringify(notificationSettings), notificationSettings: JSON.stringify(notificationSettings),
}, },
transaction transaction,
} }
); );
} }
@@ -60,7 +59,7 @@ module.exports = {
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
return queryInterface.removeColumn("users", "notificationSettings"); return queryInterface.removeColumn("users", "notificationSettings");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
@@ -31,8 +31,8 @@ module.exports = {
}, },
down: async (queryInterface) => { down: async (queryInterface) => {
await queryInterface.removeColumn("notifications", "collectionId") await queryInterface.removeColumn("notifications", "collectionId");
await queryInterface.removeColumn("notifications", "revisionId") await queryInterface.removeColumn("notifications", "revisionId");
await queryInterface.removeColumn("notifications", "commentId") await queryInterface.removeColumn("notifications", "commentId");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up(queryInterface) { async up(queryInterface) {
@@ -7,7 +7,7 @@ module.exports = {
} }
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
// Convert collection members to admins where the user is the only // Convert collection members to admins where the user is the only
// membership in the collection. // membership in the collection.
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`UPDATE collection_users cu `UPDATE collection_users cu
@@ -52,5 +52,5 @@ module.exports = {
type: queryInterface.sequelize.QueryTypes.SELECT, type: queryInterface.sequelize.QueryTypes.SELECT,
} }
); );
} },
}; };
@@ -1,11 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.dropTable("notification_settings"); await queryInterface.dropTable("notification_settings");
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
throw new Error("Cannot undo this migration.") throw new Error("Cannot undo this migration.");
} },
}; };
@@ -1,7 +1,7 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("file_operations", "includeAttachments", { await queryInterface.addColumn("file_operations", "includeAttachments", {
type: Sequelize.BOOLEAN, type: Sequelize.BOOLEAN,
allowNull: false, allowNull: false,
@@ -9,7 +9,7 @@ module.exports = {
}); });
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeColumn("file_operations", "includeAttachments"); await queryInterface.removeColumn("file_operations", "includeAttachments");
} },
}; };
@@ -1,7 +1,7 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("documents", "insightsEnabled", { await queryInterface.addColumn("documents", "insightsEnabled", {
type: Sequelize.BOOLEAN, type: Sequelize.BOOLEAN,
allowNull: false, allowNull: false,
@@ -9,7 +9,7 @@ module.exports = {
}); });
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeColumn("documents", "insightsEnabled"); await queryInterface.removeColumn("documents", "insightsEnabled");
} },
}; };
@@ -1,57 +1,93 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeConstraint("file_operations", "file_operations_collectionId_fkey", { transaction }); await queryInterface.removeConstraint(
await queryInterface.changeColumn("file_operations", "collectionId", { "file_operations",
type: Sequelize.UUID, "file_operations_collectionId_fkey",
allowNull: true, { transaction }
onDelete: "cascade", );
references: { await queryInterface.changeColumn(
model: "collections", "file_operations",
"collectionId",
{
type: Sequelize.UUID,
allowNull: true,
onDelete: "cascade",
references: {
model: "collections",
},
}, },
}, { {
transaction, transaction,
}); }
);
await queryInterface.removeConstraint("file_operations", "file_operations_teamId_fkey", { transaction }); await queryInterface.removeConstraint(
await queryInterface.changeColumn("file_operations", "teamId", { "file_operations",
type: Sequelize.UUID, "file_operations_teamId_fkey",
allowNull: false, { transaction }
onDelete: "cascade", );
references: { await queryInterface.changeColumn(
model: "teams", "file_operations",
"teamId",
{
type: Sequelize.UUID,
allowNull: false,
onDelete: "cascade",
references: {
model: "teams",
},
}, },
}, { {
transaction transaction,
}); }
);
}); });
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.sequelize.transaction(async (transaction) => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeConstraint("file_operations", "file_operations_collectionId_fkey", { transaction }); await queryInterface.removeConstraint(
await queryInterface.changeColumn("file_operations", "collectionId", { "file_operations",
type: Sequelize.UUID, "file_operations_collectionId_fkey",
allowNull: true, { transaction }
references: { );
model: "collections", await queryInterface.changeColumn(
"file_operations",
"collectionId",
{
type: Sequelize.UUID,
allowNull: true,
references: {
model: "collections",
},
}, },
}, { {
transaction, transaction,
}); }
);
await queryInterface.removeConstraint("file_operations", "file_operations_teamId_fkey", { transaction }); await queryInterface.removeConstraint(
await queryInterface.changeColumn("file_operations", "teamId", { "file_operations",
type: Sequelize.UUID, "file_operations_teamId_fkey",
allowNull: false, { transaction }
references: { );
model: "teams", await queryInterface.changeColumn(
"file_operations",
"teamId",
{
type: Sequelize.UUID,
allowNull: false,
references: {
model: "teams",
},
}, },
}, { {
transaction, transaction,
}); }
);
}); });
} },
}; };
@@ -1,14 +1,14 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("revisions", "emoji", { await queryInterface.addColumn("revisions", "emoji", {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: true, allowNull: true,
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("revisions", "emoji"); await queryInterface.removeColumn("revisions", "emoji");
} },
}; };
@@ -1,14 +1,14 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("file_operations", "deletedAt", { await queryInterface.addColumn("file_operations", "deletedAt", {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: true, allowNull: true,
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("file_operations", "deletedAt"); await queryInterface.removeColumn("file_operations", "deletedAt");
} },
}; };
@@ -1,7 +1,7 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("shares", "domain", { await queryInterface.addColumn("shares", "domain", {
type: Sequelize.STRING, type: Sequelize.STRING,
allowNull: true, allowNull: true,
@@ -9,7 +9,7 @@ module.exports = {
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("shares", "domain"); await queryInterface.removeColumn("shares", "domain");
} },
}; };
@@ -1,14 +1,14 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("documents", "sourceMetadata", { await queryInterface.addColumn("documents", "sourceMetadata", {
type: Sequelize.JSONB, type: Sequelize.JSONB,
allowNull: true, allowNull: true,
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("documents", "sourceMetadata"); await queryInterface.removeColumn("documents", "sourceMetadata");
} },
}; };
@@ -1,7 +1,7 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("documents", "content", { await queryInterface.addColumn("documents", "content", {
type: Sequelize.JSONB, type: Sequelize.JSONB,
allowNull: true, allowNull: true,
@@ -12,8 +12,8 @@ module.exports = {
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("revisions", "content"); await queryInterface.removeColumn("revisions", "content");
await queryInterface.removeColumn("documents", "content"); await queryInterface.removeColumn("documents", "content");
} },
}; };
@@ -1,8 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("webhook_subscriptions", "webhook_subscriptions_createdById_fkey") await queryInterface.removeConstraint(
"webhook_subscriptions",
"webhook_subscriptions_createdById_fkey"
);
await queryInterface.changeColumn("webhook_subscriptions", "createdById", { await queryInterface.changeColumn("webhook_subscriptions", "createdById", {
type: Sequelize.UUID, type: Sequelize.UUID,
onDelete: "cascade", onDelete: "cascade",
@@ -13,12 +16,15 @@ module.exports = {
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("webhook_subscriptions", "webhook_subscriptions_createdById_fkey") await queryInterface.removeConstraint(
"webhook_subscriptions",
"webhook_subscriptions_createdById_fkey"
);
await queryInterface.changeColumn("webhook_subscriptions", "createdById", { await queryInterface.changeColumn("webhook_subscriptions", "createdById", {
type: Sequelize.UUID, type: Sequelize.UUID,
references: { references: {
model: "users", model: "users",
}, },
}); });
} },
}; };
@@ -11,7 +11,10 @@ module.exports = {
allowNull: true, allowNull: true,
}); });
await queryInterface.removeConstraint("user_permissions", "user_permissions_documentId_fkey") await queryInterface.removeConstraint(
"user_permissions",
"user_permissions_documentId_fkey"
);
await queryInterface.changeColumn("user_permissions", "documentId", { await queryInterface.changeColumn("user_permissions", "documentId", {
type: Sequelize.UUID, type: Sequelize.UUID,
onDelete: "cascade", onDelete: "cascade",
@@ -21,7 +24,10 @@ module.exports = {
}); });
}, },
async down(queryInterface) { async down(queryInterface) {
await queryInterface.removeConstraint("user_permissions", "user_permissions_documentId_fkey") await queryInterface.removeConstraint(
"user_permissions",
"user_permissions_documentId_fkey"
);
await queryInterface.changeColumn("user_permissions", "documentId", { await queryInterface.changeColumn("user_permissions", "documentId", {
type: Sequelize.UUID, type: Sequelize.UUID,
references: { references: {
@@ -1,8 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("comments", "comments_createdById_fkey") await queryInterface.removeConstraint(
"comments",
"comments_createdById_fkey"
);
await queryInterface.changeColumn("comments", "createdById", { await queryInterface.changeColumn("comments", "createdById", {
type: Sequelize.UUID, type: Sequelize.UUID,
onDelete: "cascade", onDelete: "cascade",
@@ -11,7 +14,10 @@ module.exports = {
}, },
}); });
await queryInterface.removeConstraint("comments", "comments_resolvedById_fkey") await queryInterface.removeConstraint(
"comments",
"comments_resolvedById_fkey"
);
await queryInterface.changeColumn("comments", "resolvedById", { await queryInterface.changeColumn("comments", "resolvedById", {
type: Sequelize.UUID, type: Sequelize.UUID,
onDelete: "set null", onDelete: "set null",
@@ -22,7 +28,10 @@ module.exports = {
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("comments", "comments_resolvedById_fkey") await queryInterface.removeConstraint(
"comments",
"comments_resolvedById_fkey"
);
await queryInterface.changeColumn("comments", "resolvedById", { await queryInterface.changeColumn("comments", "resolvedById", {
type: Sequelize.UUID, type: Sequelize.UUID,
references: { references: {
@@ -30,12 +39,15 @@ module.exports = {
}, },
}); });
await queryInterface.removeConstraint("comments", "comments_createdById_fkey") await queryInterface.removeConstraint(
"comments",
"comments_createdById_fkey"
);
await queryInterface.changeColumn("comments", "createdById", { await queryInterface.changeColumn("comments", "createdById", {
type: Sequelize.UUID, type: Sequelize.UUID,
references: { references: {
model: "users", model: "users",
}, },
}); });
} },
}; };
@@ -6,7 +6,6 @@ module.exports = {
type: Sequelize.JSONB, type: Sequelize.JSONB,
allowNull: true, allowNull: true,
}); });
}, },
async down(queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("events", "changes"); await queryInterface.removeColumn("events", "changes");
@@ -1,8 +1,11 @@
'use strict'; "use strict";
module.exports = { module.exports = {
up: async (queryInterface, Sequelize) => { up: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("search_queries", "search_queries_shareId_fkey") await queryInterface.removeConstraint(
"search_queries",
"search_queries_shareId_fkey"
);
await queryInterface.changeColumn("search_queries", "shareId", { await queryInterface.changeColumn("search_queries", "shareId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
@@ -14,7 +17,10 @@ module.exports = {
}, },
down: async (queryInterface, Sequelize) => { down: async (queryInterface, Sequelize) => {
await queryInterface.removeConstraint("search_queries", "search_queries_shareId_fkey") await queryInterface.removeConstraint(
"search_queries",
"search_queries_shareId_fkey"
);
await queryInterface.changeColumn("search_queries", "shareId", { await queryInterface.changeColumn("search_queries", "shareId", {
type: Sequelize.UUID, type: Sequelize.UUID,
allowNull: true, allowNull: true,
@@ -22,5 +28,5 @@ module.exports = {
model: "shares", model: "shares",
}, },
}); });
} },
}; };
@@ -1,14 +1,14 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("authentications", "refreshToken", { await queryInterface.addColumn("authentications", "refreshToken", {
type: Sequelize.BLOB, type: Sequelize.BLOB,
allowNull: true, allowNull: true,
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("authentications", "refreshToken"); await queryInterface.removeColumn("authentications", "refreshToken");
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
@@ -42,5 +42,5 @@ module.exports = {
transaction, transaction,
}); });
}); });
} },
}; };
@@ -1,7 +1,7 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addColumn("users", "role", { await queryInterface.addColumn("users", "role", {
type: Sequelize.ENUM("admin", "member", "viewer", "guest"), type: Sequelize.ENUM("admin", "member", "viewer", "guest"),
allowNull: true, allowNull: true,
@@ -35,7 +35,7 @@ module.exports = {
}); });
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.removeColumn("users", "role"); await queryInterface.removeColumn("users", "role");
} },
}; };
@@ -1,15 +1,15 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
'ALTER TABLE users ALTER COLUMN role SET NOT NULL;' "ALTER TABLE users ALTER COLUMN role SET NOT NULL;"
); );
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
'ALTER TABLE users ALTER COLUMN role DROP NOT NULL;' "ALTER TABLE users ALTER COLUMN role DROP NOT NULL;"
); );
} },
}; };
@@ -1,4 +1,4 @@
'use strict'; "use strict";
module.exports = { module.exports = {
async up(queryInterface) { async up(queryInterface) {
@@ -38,5 +38,5 @@ module.exports = {
} }
); );
}); });
} },
}; };
@@ -3,7 +3,7 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn( await queryInterface.addColumn(
"documents", "documents",
"icon", "icon",
@@ -69,7 +69,7 @@ module.exports = {
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeColumn("documents", "icon", { transaction }); await queryInterface.removeColumn("documents", "icon", { transaction });
await queryInterface.removeColumn("revisions", "icon", { transaction }); await queryInterface.removeColumn("revisions", "icon", { transaction });
await queryInterface.removeColumn("documents", "color", { transaction }); await queryInterface.removeColumn("documents", "color", { transaction });
@@ -3,14 +3,14 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeColumn("documents", "emoji", { transaction }); await queryInterface.removeColumn("documents", "emoji", { transaction });
await queryInterface.removeColumn("revisions", "emoji", { transaction }); await queryInterface.removeColumn("revisions", "emoji", { transaction });
}); });
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn( await queryInterface.addColumn(
"documents", "documents",
"emoji", "emoji",
@@ -11,7 +11,10 @@ module.exports = {
allowNull: true, allowNull: true,
}); });
await queryInterface.removeConstraint("group_permissions", "group_permissions_documentId_fkey") await queryInterface.removeConstraint(
"group_permissions",
"group_permissions_documentId_fkey"
);
await queryInterface.changeColumn("group_permissions", "documentId", { await queryInterface.changeColumn("group_permissions", "documentId", {
type: Sequelize.UUID, type: Sequelize.UUID,
onDelete: "cascade", onDelete: "cascade",
@@ -21,7 +24,10 @@ module.exports = {
}); });
}, },
async down(queryInterface) { async down(queryInterface) {
await queryInterface.removeConstraint("group_permissions", "group_permissions_documentId_fkey") await queryInterface.removeConstraint(
"group_permissions",
"group_permissions_documentId_fkey"
);
await queryInterface.changeColumn("group_permissions", "documentId", { await queryInterface.changeColumn("group_permissions", "documentId", {
type: Sequelize.UUID, type: Sequelize.UUID,
references: { references: {
@@ -1,14 +1,14 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up (queryInterface) { async up(queryInterface) {
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`DELETE FROM group_users WHERE "deletedAt" IS NOT NULL` `DELETE FROM group_users WHERE "deletedAt" IS NOT NULL`
); );
}, },
async down () { async down() {
// No reverting possible // No reverting possible
} },
}; };
@@ -1,9 +1,9 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up (queryInterface) { async up(queryInterface) {
await queryInterface.removeColumn('group_users', 'deletedAt'); await queryInterface.removeColumn("group_users", "deletedAt");
// Cleanup any rows with duplicate groupId + userId // Cleanup any rows with duplicate groupId + userId
await queryInterface.sequelize.query(` await queryInterface.sequelize.query(`
@@ -16,21 +16,24 @@ module.exports = {
`); `);
// Add groupId + userId as primary key // Add groupId + userId as primary key
await queryInterface.addConstraint('group_users', { await queryInterface.addConstraint("group_users", {
fields: ['groupId', 'userId'], fields: ["groupId", "userId"],
type: 'primary key', type: "primary key",
name: 'group_users_pkey' name: "group_users_pkey",
}); });
await queryInterface.removeIndex("group_users", "group_users_group_id_user_id"); await queryInterface.removeIndex(
"group_users",
"group_users_group_id_user_id"
);
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.addIndex("group_users", ["groupId", "userId"]); await queryInterface.addIndex("group_users", ["groupId", "userId"]);
await queryInterface.removeConstraint('group_users', 'group_users_pkey'); await queryInterface.removeConstraint("group_users", "group_users_pkey");
await queryInterface.addColumn('group_users', 'deletedAt', { await queryInterface.addColumn("group_users", "deletedAt", {
type: Sequelize.DATE, type: Sequelize.DATE,
allowNull: true allowNull: true,
}); });
} },
}; };
@@ -1,12 +1,12 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addIndex('notifications', ['teamId', 'userId']); await queryInterface.addIndex("notifications", ["teamId", "userId"]);
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeIndex('notifications', ['teamId', 'userId']); await queryInterface.removeIndex("notifications", ["teamId", "userId"]);
} },
}; };
@@ -1,12 +1,15 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addIndex('user_permissions', ['documentId', 'userId']); await queryInterface.addIndex("user_permissions", ["documentId", "userId"]);
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeIndex('user_permissions', ['documentId', 'userId']); await queryInterface.removeIndex("user_permissions", [
} "documentId",
"userId",
]);
},
}; };
@@ -1,12 +1,12 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.addIndex('user_authentications', ['userId']); await queryInterface.addIndex("user_authentications", ["userId"]);
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.removeIndex('user_authentications', ['userId']); await queryInterface.removeIndex("user_authentications", ["userId"]);
} },
}; };
@@ -1,35 +1,55 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up (queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn("apiKeys", "hash", { await queryInterface.addColumn(
type: Sequelize.STRING, "apiKeys",
allowNull: true, "hash",
unique: true, {
}, { transaction }); type: Sequelize.STRING,
allowNull: true,
unique: true,
},
{ transaction }
);
await queryInterface.addColumn("apiKeys", "last4", { await queryInterface.addColumn(
type: Sequelize.STRING(4), "apiKeys",
allowNull: true, "last4",
}, { transaction }); {
type: Sequelize.STRING(4),
allowNull: true,
},
{ transaction }
);
await queryInterface.changeColumn("apiKeys", "secret", { await queryInterface.changeColumn(
type: Sequelize.STRING, "apiKeys",
allowNull: true, "secret",
}, { transaction }); {
type: Sequelize.STRING,
allowNull: true,
},
{ transaction }
);
}); });
}, },
async down (queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeColumn("apiKeys", "hash", { transaction }); await queryInterface.removeColumn("apiKeys", "hash", { transaction });
await queryInterface.removeColumn("apiKeys", "last4", { transaction }); await queryInterface.removeColumn("apiKeys", "last4", { transaction });
await queryInterface.changeColumn("apiKeys", "secret", { await queryInterface.changeColumn(
type: Sequelize.STRING, "apiKeys",
allowNull: false, "secret",
}, { transaction }); {
type: Sequelize.STRING,
allowNull: false,
},
{ transaction }
);
}); });
} },
}; };
@@ -3,7 +3,7 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.createTable( await queryInterface.createTable(
"reactions", "reactions",
{ {
@@ -64,7 +64,7 @@ module.exports = {
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
queryInterface.sequelize.transaction(async transaction => { queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.dropTable("reactions", { transaction }); await queryInterface.dropTable("reactions", { transaction });
await queryInterface.removeColumn("comments", "reactions", { await queryInterface.removeColumn("comments", "reactions", {
transaction, transaction,
@@ -3,19 +3,32 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn("teams", "approximateTotalAttachmentsSize", { await queryInterface.addColumn(
type: Sequelize.BIGINT, "teams",
defaultValue: 0, "approximateTotalAttachmentsSize",
}, { transaction }); {
await queryInterface.addIndex("attachments", ["createdAt"], { transaction }); type: Sequelize.BIGINT,
defaultValue: 0,
},
{ transaction }
);
await queryInterface.addIndex("attachments", ["createdAt"], {
transaction,
});
}); });
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeIndex("attachments", ["createdAt"], { transaction }); await queryInterface.removeIndex("attachments", ["createdAt"], {
await queryInterface.removeColumn("teams", "approximateTotalAttachmentsSize", { transaction }); transaction,
});
await queryInterface.removeColumn(
"teams",
"approximateTotalAttachmentsSize",
{ transaction }
);
}); });
}, },
}; };
@@ -3,22 +3,39 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn("groups", "externalId", { await queryInterface.addColumn(
type: Sequelize.STRING, "groups",
}, { transaction }); "externalId",
{
type: Sequelize.STRING,
},
{ transaction }
);
await queryInterface.addIndex("groups", ["externalId"], { transaction }); await queryInterface.addIndex("groups", ["externalId"], { transaction });
await queryInterface.addIndex("group_permissions", ["documentId"], { transaction }); await queryInterface.addIndex("group_permissions", ["documentId"], {
await queryInterface.addIndex("group_permissions", ["sourceId"], { transaction }); transaction,
});
await queryInterface.addIndex("group_permissions", ["sourceId"], {
transaction,
});
}); });
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeIndex("group_permissions", ["sourceId"], { transaction }); await queryInterface.removeIndex("group_permissions", ["sourceId"], {
await queryInterface.removeIndex("group_permissions", ["documentId"], { transaction }); transaction,
await queryInterface.removeIndex("groups", ["externalId"], { transaction }); });
await queryInterface.removeColumn("groups", "externalId", { transaction }); await queryInterface.removeIndex("group_permissions", ["documentId"], {
transaction,
});
await queryInterface.removeIndex("groups", ["externalId"], {
transaction,
});
await queryInterface.removeColumn("groups", "externalId", {
transaction,
});
}); });
}, },
}; };
@@ -3,16 +3,21 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn("apiKeys", "scope", { await queryInterface.addColumn(
type: Sequelize.ARRAY(Sequelize.STRING), "apiKeys",
allowNull: true, "scope",
}, { transaction }); {
type: Sequelize.ARRAY(Sequelize.STRING),
allowNull: true,
},
{ transaction }
);
}); });
}, },
async down(queryInterface) { async down(queryInterface) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeColumn("apiKeys", "scope", { transaction }); await queryInterface.removeColumn("apiKeys", "scope", { transaction });
}); });
}, },
@@ -3,7 +3,7 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn( await queryInterface.addColumn(
"subscriptions", "subscriptions",
"collectionId", "collectionId",
@@ -30,7 +30,7 @@ module.exports = {
}, },
async down(queryInterface, Sequelize) { async down(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeIndex( await queryInterface.removeIndex(
"subscriptions", "subscriptions",
["userId", "collectionId", "event"], ["userId", "collectionId", "event"],
@@ -1,19 +1,19 @@
'use strict'; "use strict";
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up (queryInterface) { async up(queryInterface) {
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`CREATE EXTENSION IF NOT EXISTS "pg_trgm";`, `CREATE EXTENSION IF NOT EXISTS "pg_trgm";`
); );
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`CREATE INDEX CONCURRENTLY documents_title_idx ON documents USING GIN (title gin_trgm_ops);`, `CREATE INDEX CONCURRENTLY documents_title_idx ON documents USING GIN (title gin_trgm_ops);`
); );
}, },
async down (queryInterface) { async down(queryInterface) {
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`DROP INDEX CONCURRENTLY documents_title_idx;`, `DROP INDEX CONCURRENTLY documents_title_idx;`
); );
} },
}; };
@@ -3,11 +3,16 @@
/** @type {import('sequelize-cli').Migration} */ /** @type {import('sequelize-cli').Migration} */
module.exports = { module.exports = {
async up(queryInterface, Sequelize) { async up(queryInterface, Sequelize) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.addColumn("teams", "previousSubdomains", { await queryInterface.addColumn(
type: Sequelize.ARRAY(Sequelize.STRING), "teams",
allowNull: true, "previousSubdomains",
}, { transaction }); {
type: Sequelize.ARRAY(Sequelize.STRING),
allowNull: true,
},
{ transaction }
);
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`CREATE INDEX teams_previous_subdomains ON teams USING GIN ("previousSubdomains");`, `CREATE INDEX teams_previous_subdomains ON teams USING GIN ("previousSubdomains");`,
{ transaction } { transaction }
@@ -16,12 +21,14 @@ module.exports = {
}, },
async down(queryInterface) { async down(queryInterface) {
await queryInterface.sequelize.transaction(async transaction => { await queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.sequelize.query( await queryInterface.sequelize.query(
`DROP INDEX teams_previous_subdomains;`, `DROP INDEX teams_previous_subdomains;`,
{ transaction } { transaction }
); );
await queryInterface.removeColumn("teams", "previousSubdomains", { transaction }); await queryInterface.removeColumn("teams", "previousSubdomains", {
transaction,
});
}); });
}, },
}; };
@@ -4,7 +4,7 @@ const tableName = "team_domains";
const constraintNames = [ const constraintNames = [
"team_domains_createdById_fkey", "team_domains_createdById_fkey",
"createdById_foreign_idx" "createdById_foreign_idx",
]; ];
module.exports = { module.exports = {

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