mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-28 04:25:03 +02:00
bun -> rush (#62)
Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
# Don't allow people to merge changes to these generated files, because the result
|
||||
# may be invalid. You need to run "rush update" again.
|
||||
pnpm-lock.yaml merge=text
|
||||
shrinkwrap.yaml merge=binary
|
||||
npm-shrinkwrap.json merge=binary
|
||||
yarn.lock merge=binary
|
||||
|
||||
# Rush's JSON config files use JavaScript-style code comments. The rule below prevents pedantic
|
||||
# syntax highlighters such as GitHub's from highlighting these comments as errors. Your text editor
|
||||
# may also require a special configuration to allow comments in JSON.
|
||||
#
|
||||
# For more information, see this issue: https://github.com/microsoft/rushstack/issues/1088
|
||||
#
|
||||
*.json linguist-language=JSON-with-Comments
|
||||
+15
-21
@@ -34,32 +34,26 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
with:
|
||||
bun-version: 1.2.9
|
||||
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
node-version: 22
|
||||
registry-url: 'https://npm.pkg.github.com'
|
||||
scope: '@hcengineering'
|
||||
|
||||
- name: Prepare deps
|
||||
- name: Prepare .npmrc for GitHub Packages
|
||||
run: |
|
||||
echo "@hcengineering:registry=https://npm.pkg.github.com" > .npmrc
|
||||
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc
|
||||
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
|
||||
- name: Build
|
||||
run: bun run build
|
||||
|
||||
- name: Check format
|
||||
run: bun run format:check
|
||||
|
||||
- name: Lint
|
||||
run: bun run lint
|
||||
echo "//npm.pkg.github.com/:_authToken=${{secrets.GITHUB_TOKEN}}" > ~/.npmrc
|
||||
|
||||
- name: Checking for mis-matching dependencies...
|
||||
run: node common/scripts/install-run-rush.js check
|
||||
- name: Rush Install
|
||||
run: node common/scripts/install-run-rush.js update
|
||||
- name: Rush rebuild
|
||||
run: node common/scripts/install-run-rush.js build
|
||||
- name: Rush validate
|
||||
run: node common/scripts/install-run-rush.js validate
|
||||
- name: Linting
|
||||
run: node common/scripts/install-run-rush.js lint
|
||||
- name: Formatting
|
||||
run: node common/scripts/install-run-rush.js format
|
||||
+125
-14
@@ -1,6 +1,129 @@
|
||||
# build output
|
||||
dist/
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.pnpm-debug.log*
|
||||
rush-logs/
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov/
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage/
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output/
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt/
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components/
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript/
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release/
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm/
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# next.js build output
|
||||
.next/
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus/
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache/
|
||||
.yarn/unplugged/
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# OS X temporary files
|
||||
.DS_Store
|
||||
|
||||
# IntelliJ IDEA project files; if you want to commit IntelliJ settings, this recipe may be helpful:
|
||||
# https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
# Visual Studio Code
|
||||
.vscode/
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
|
||||
# Rush temporary files
|
||||
common/deploy/
|
||||
common/temp/
|
||||
common/autoinstallers/*/.npmrc
|
||||
**/.rush/temp/
|
||||
*.lock
|
||||
|
||||
# Common toolchain intermediate files
|
||||
temp/
|
||||
lib/
|
||||
lib-amd/
|
||||
lib-es6/
|
||||
lib-esnext/
|
||||
lib-commonjs/
|
||||
lib-shim/
|
||||
dist/
|
||||
dist-storybook/
|
||||
|
||||
# Heft temporary files
|
||||
.cache/
|
||||
.heft/
|
||||
.rush/
|
||||
.validate
|
||||
|
||||
# build output
|
||||
.turbo/
|
||||
**/types/
|
||||
|
||||
@@ -9,21 +132,9 @@ lib/
|
||||
# VS Code settings
|
||||
.vscode/settings.json
|
||||
|
||||
# Jetbrains setting folder
|
||||
.idea/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
|
||||
# logs
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# environment variables
|
||||
.env
|
||||
.env.production
|
||||
|
||||
# macOS-specific files
|
||||
.DS_Store
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
## 📡 Platform Communication Package
|
||||
|
||||
A modular communication package for platform-level messaging —
|
||||
built with [Bun](https://bun.sh).
|
||||
built with [Rush](https://rushjs.io/).
|
||||
|
||||
---
|
||||
|
||||
### 📦 Installation
|
||||
|
||||
Install dependencies using Bun:
|
||||
Install rush:
|
||||
|
||||
```bash
|
||||
bun install
|
||||
npm install -g @microsoft/rush
|
||||
```
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```bash
|
||||
rush update
|
||||
```
|
||||
|
||||
### Build packages
|
||||
|
||||
```bash
|
||||
bun run build
|
||||
rush build
|
||||
rush validate
|
||||
```
|
||||
|
||||
### Lint & format
|
||||
|
||||
```bash
|
||||
bun run lint
|
||||
bun run format
|
||||
rush lint
|
||||
rush format
|
||||
```
|
||||
@@ -1,643 +0,0 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "@hcengineering/communication",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.28.0",
|
||||
"@types/bun": "^1.2.15",
|
||||
"bun-types": "^1.2.15",
|
||||
"eslint": "^9.28.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.4.1",
|
||||
"prettier": "^3.5.3",
|
||||
"turbo": "^2.5.4",
|
||||
"typescript-eslint": "^8.33.1",
|
||||
},
|
||||
},
|
||||
"packages/client-query": {
|
||||
"name": "@hcengineering/communication-client-query",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-query": "workspace:*",
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"fast-equals": "^5.0.1",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/cockroach": {
|
||||
"name": "@hcengineering/communication-cockroach",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-shared": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"postgres": "^3.4.4",
|
||||
"uuid": "^11.1.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/query": {
|
||||
"name": "@hcengineering/communication-query",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-shared": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/communication-yaml": "workspace:*",
|
||||
"fast-equals": "^5.0.1",
|
||||
"uuid": "^11.1.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/rest-client": {
|
||||
"name": "@hcengineering/communication-rest-client",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-shared": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/core": "^0.7.88",
|
||||
"snappyjs": "^0.7.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
"@types/snappyjs": "^0.7.1",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/sdk-types": {
|
||||
"name": "@hcengineering/communication-sdk-types",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/core": "^0.7.88",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/server": {
|
||||
"name": "@hcengineering/communication-server",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/account-client": "^0.7.88",
|
||||
"@hcengineering/communication-cockroach": "workspace:*",
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/communication-yaml": "workspace:*",
|
||||
"@hcengineering/core": "^0.7.88",
|
||||
"@hcengineering/platform": "^0.7.88",
|
||||
"@hcengineering/server-token": "^0.7.88",
|
||||
"@hcengineering/text-core": "^0.7.88",
|
||||
"@hcengineering/text-markdown": "^0.7.88",
|
||||
"zod": "^3.24.2",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/ws": "^8.5.13",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/shared": {
|
||||
"name": "@hcengineering/communication-shared",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/types": {
|
||||
"name": "@hcengineering/communication-types",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/card": "^0.7.88",
|
||||
"@hcengineering/core": "^0.7.88",
|
||||
"@hcengineering/tags": "^0.7.88",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
"packages/yaml": {
|
||||
"name": "@hcengineering/communication-yaml",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-shared": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"js-yaml": "^4.1.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||
|
||||
"@babel/runtime": ["@babel/runtime@7.26.9", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg=="],
|
||||
|
||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
|
||||
|
||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
||||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.20.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ=="],
|
||||
|
||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.2.1", "", {}, "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@0.14.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.28.0", "", {}, "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.1", "", { "dependencies": { "@eslint/core": "^0.14.0", "levn": "^0.4.1" } }, "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w=="],
|
||||
|
||||
"@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.3", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.6", "@formatjs/intl-localematcher": "0.6.0", "decimal.js": "10", "tslib": "2" } }, "sha512-pJT1OkhplSmvvr6i3CWTPvC/FGC06MbN5TNBfRO6Ox62AEz90eMq+dVvtX9Bl3jxCEkS0tATzDarRZuOLw7oFg=="],
|
||||
|
||||
"@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.6", "", { "dependencies": { "tslib": "2" } }, "sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw=="],
|
||||
|
||||
"@formatjs/icu-messageformat-parser": ["@formatjs/icu-messageformat-parser@2.11.1", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.3", "@formatjs/icu-skeleton-parser": "1.8.13", "tslib": "2" } }, "sha512-o0AhSNaOfKoic0Sn1GkFCK4MxdRsw7mPJ5/rBpIqdvcC7MIuyUSW8WChUEvrK78HhNpYOgqCQbINxCTumJLzZA=="],
|
||||
|
||||
"@formatjs/icu-skeleton-parser": ["@formatjs/icu-skeleton-parser@1.8.13", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.3", "tslib": "2" } }, "sha512-N/LIdTvVc1TpJmMt2jVg0Fr1F7Q1qJPdZSCs19unMskCmVQ/sa0H9L8PWt13vq+gLdLg1+pPsvBLydL1Apahjg=="],
|
||||
|
||||
"@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.0", "", { "dependencies": { "tslib": "2" } }, "sha512-4rB4g+3hESy1bHSBG3tDFaMY2CH67iT7yne1e+0CLTsGLDcmoEWWpJjjpWVaYgYfYuohIRuo0E+N536gd2ZHZA=="],
|
||||
|
||||
"@hcengineering/account-client": ["@hcengineering/account-client@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/account-client/0.7.88/57caa95e62fecc4ca22a32c76bcdc900b0384f04", { "dependencies": { "@hcengineering/core": "^0.7.88", "@hcengineering/platform": "^0.7.88" } }, "sha512-CZWOJT/JZAUy+FuYuX0QcJQYDnVDNAB0QHU4RxKc7gSlYAYleibL7qJC0vRGL4rNkvDVZfJMKDPUQW4AauGqtA=="],
|
||||
|
||||
"@hcengineering/analytics": ["@hcengineering/analytics@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/analytics/0.7.88/385c2ae512bbcae39189d63e53ea527aa21a662f", { "dependencies": { "@hcengineering/platform": "^0.7.88" } }, "sha512-3jT3h2Y85awrgG0JWZSrpWOXaX1J3dpq8zouo3QMw8OVO1RgHCwPEqrBPOALnB+gc9cZL02p6Aq4J+fnTZ2fww=="],
|
||||
|
||||
"@hcengineering/card": ["@hcengineering/card@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/card/0.7.88/e39b9e182325945494f162f2dd6f16ef9bea0f3e", { "dependencies": { "@hcengineering/core": "^0.7.88", "@hcengineering/platform": "^0.7.88", "@hcengineering/ui": "^0.7.88" } }, "sha512-3JDgocHFSGmQuKsrtQ5CTTm4rpd/PHahIx6oNX8sshDGpS2hnvNtrHNkJf39seIKiq0NNKmJ//Etl4I21h4c6w=="],
|
||||
|
||||
"@hcengineering/communication-client-query": ["@hcengineering/communication-client-query@workspace:packages/client-query"],
|
||||
|
||||
"@hcengineering/communication-cockroach": ["@hcengineering/communication-cockroach@workspace:packages/cockroach"],
|
||||
|
||||
"@hcengineering/communication-query": ["@hcengineering/communication-query@workspace:packages/query"],
|
||||
|
||||
"@hcengineering/communication-rest-client": ["@hcengineering/communication-rest-client@workspace:packages/rest-client"],
|
||||
|
||||
"@hcengineering/communication-sdk-types": ["@hcengineering/communication-sdk-types@workspace:packages/sdk-types"],
|
||||
|
||||
"@hcengineering/communication-server": ["@hcengineering/communication-server@workspace:packages/server"],
|
||||
|
||||
"@hcengineering/communication-shared": ["@hcengineering/communication-shared@workspace:packages/shared"],
|
||||
|
||||
"@hcengineering/communication-types": ["@hcengineering/communication-types@workspace:packages/types"],
|
||||
|
||||
"@hcengineering/communication-yaml": ["@hcengineering/communication-yaml@workspace:packages/yaml"],
|
||||
|
||||
"@hcengineering/core": ["@hcengineering/core@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/core/0.7.88/ca01c3ccd43c85ea44b189d995b0693c5465956c", { "dependencies": { "@hcengineering/analytics": "^0.7.88", "@hcengineering/platform": "^0.7.88", "fast-equals": "^5.2.2" } }, "sha512-c3GRTGAZYARu1kMt4TqkugmnuprYesZ4XZUeakReRtZdYei9tAF+i9xPpDKb4J3hvMC3u82LlEiV8iK26iXpTA=="],
|
||||
|
||||
"@hcengineering/platform": ["@hcengineering/platform@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/platform/0.7.88/b3fbe09d6b849f7eb3641792682bf133103037f0", { "dependencies": { "intl-messageformat": "^10.7.14" } }, "sha512-iFAwYQZjGox1NqEgUh8hiT1mRHdSJqYmYux0lkeIFyt8Nn/BAZOVXe0br0Dx7wXiueFPWhSZSeWVhxvBb78zoA=="],
|
||||
|
||||
"@hcengineering/preference": ["@hcengineering/preference@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/preference/0.7.88/e1181dae3cb2eaf53fed66ddd3d5c4854717ccf0", { "dependencies": { "@hcengineering/core": "^0.7.88", "@hcengineering/platform": "^0.7.88", "@hcengineering/ui": "^0.7.88" } }, "sha512-idzAlphM/HyNJfFMFwbpyKg6KvFTJ6rTaqgduNNJqkO4DsUCEF5/1WLNQMmiAeoFDY9y5+/mHJrx+1Ztq1XIuw=="],
|
||||
|
||||
"@hcengineering/server-token": ["@hcengineering/server-token@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/server-token/0.7.88/11b3a8247869a50037fcbb13572e16545116ff93", { "dependencies": { "@hcengineering/core": "^0.7.88", "@hcengineering/platform": "^0.7.88", "jwt-simple": "^0.5.6" } }, "sha512-UQfW0E+v+PTwR7ICR+kSTQqAokpiV008ukqsxRSQJkCM4vmNYciUgd/7Y/ifDMFhKDvNyODb+wgAQs3QxkSbkA=="],
|
||||
|
||||
"@hcengineering/tags": ["@hcengineering/tags@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/tags/0.7.88/f3f0de35b1be71d1f3f6711b8e4f161e0cf857eb", { "dependencies": { "@hcengineering/core": "^0.7.88", "@hcengineering/platform": "^0.7.88", "@hcengineering/ui": "^0.7.88", "@hcengineering/view": "^0.7.88" } }, "sha512-wpnVX/1Y8E4YPYnUcw+ZyVOpZvXYpboZC9D1btMqFs34CoMGc4tW1XT3YfsS8KxlkH6tsQjsAUvtWOPy2J46dg=="],
|
||||
|
||||
"@hcengineering/text-core": ["@hcengineering/text-core@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/text-core/0.7.88/7e53b0da9622709b2d1071049ead3843e0c45764", { "dependencies": { "@hcengineering/core": "^0.7.88", "fast-equals": "^5.2.2" } }, "sha512-mFri9SMzD99uR3/H0gZ4KEekYf3lEmJ2bqEQrjIVmi9z7+CzDTxmKnXeHKzcFpvQaLt5kmbPIoXM4MyxpK7ZXA=="],
|
||||
|
||||
"@hcengineering/text-html": ["@hcengineering/text-html@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/text-html/0.7.88/e48beced20921d9e1e9c84548c3caf5c9770bac1", { "dependencies": { "@hcengineering/text-core": "^0.7.88", "htmlparser2": "^9.0.0" } }, "sha512-Wj0gYv0JEUIKpuaDFmRn7/60/SXGg0CZVmzbux0XlUzayly+C4Pkfj5U3G/ZEUyDBtAtyeBdWtnkzgQgN6qOuQ=="],
|
||||
|
||||
"@hcengineering/text-markdown": ["@hcengineering/text-markdown@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/text-markdown/0.7.88/86938b13b0bdd81941a22378e3b2e92998f71d80", { "dependencies": { "@hcengineering/text-core": "^0.7.88", "@hcengineering/text-html": "^0.7.88", "fast-equals": "^5.2.2", "markdown-it": "^14.0.0" } }, "sha512-066WeD/6EI5VmFQZ/Cv6eEOFXBd+fA+YPxX5fb0ytlZr5bLpQs6/AifpyqJoZ5gqQzfAf/HmtDVxDl5QU95FGw=="],
|
||||
|
||||
"@hcengineering/theme": ["@hcengineering/theme@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/theme/0.7.88/d939d1e2a9047def2795dc5124653e49ca522cfc", { "dependencies": { "@hcengineering/analytics": "^0.7.88", "@hcengineering/platform": "^0.7.88", "svelte": "^4.2.19" } }, "sha512-PCt9bFuGPYOf1kQgjzxPSZgGXU4G14Z1XZJfgGu71u/zHxG6fu6nls35aSrEjy2Ks6oR+OCqqvpDh6RTf6utrg=="],
|
||||
|
||||
"@hcengineering/ui": ["@hcengineering/ui@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/ui/0.7.88/fce3392a59f706c248ba4b17714163e5725d5f01", { "dependencies": { "@hcengineering/analytics": "^0.7.88", "@hcengineering/core": "^0.7.88", "@hcengineering/platform": "^0.7.88", "@hcengineering/theme": "^0.7.88", "autolinker": "4.0.0", "date-fns": "^2.30.0", "date-fns-tz": "^2.0.0", "dompurify": "^3.1.6", "emojibase": "^16.0.0", "fast-equals": "^5.2.2", "hls.js": "^1.5.20", "plyr": "^3.7.8", "svelte": "^4.2.19" } }, "sha512-mzHXcX3aBC/OXUaV9F2hnB6+irwMfEYM5J1CnfqiHqgv3Hza20BZR6BrYe/nQCLb44DuHkXojbwL94AKK3QW6w=="],
|
||||
|
||||
"@hcengineering/view": ["@hcengineering/view@0.7.88", "https://npm.pkg.github.com/download/@hcengineering/view/0.7.88/8a13ddff0178ac3b705ebed683d0c1cc328c8e1c", { "dependencies": { "@hcengineering/core": "^0.7.88", "@hcengineering/platform": "^0.7.88", "@hcengineering/preference": "^0.7.88", "@hcengineering/ui": "^0.7.88" } }, "sha512-W3/OgCu9W+OGZ8v8hoT0bjoCNflvIcWFwFafk40FtWFxvqzObm41e5ZWNj3yGWFdlVsyN/Nqdjkyz0txWUXQAA=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
||||
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
|
||||
|
||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
||||
|
||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||
|
||||
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
|
||||
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
||||
|
||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||
|
||||
"@pkgr/core": ["@pkgr/core@0.2.7", "", {}, "sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg=="],
|
||||
|
||||
"@types/body-parser": ["@types/body-parser@1.19.5", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.2.15", "", { "dependencies": { "bun-types": "1.2.15" } }, "sha512-U1ljPdBEphF0nw1MIk0hI7kPg7dFdPyM7EenHsp6W5loNHl7zqy6JQf/RKCgnUn2KDzUpkBwHPnEJEjII594bA=="],
|
||||
|
||||
"@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
|
||||
|
||||
"@types/cors": ["@types/cors@2.8.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA=="],
|
||||
|
||||
"@types/crypto-js": ["@types/crypto-js@4.2.2", "", {}, "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
|
||||
|
||||
"@types/express": ["@types/express@5.0.0", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ=="],
|
||||
|
||||
"@types/express-serve-static-core": ["@types/express-serve-static-core@5.0.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA=="],
|
||||
|
||||
"@types/http-errors": ["@types/http-errors@2.0.4", "", {}, "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="],
|
||||
|
||||
"@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="],
|
||||
|
||||
"@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="],
|
||||
|
||||
"@types/qs": ["@types/qs@6.9.18", "", {}, "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA=="],
|
||||
|
||||
"@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="],
|
||||
|
||||
"@types/send": ["@types/send@0.17.4", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA=="],
|
||||
|
||||
"@types/serve-static": ["@types/serve-static@1.15.7", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "*" } }, "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw=="],
|
||||
|
||||
"@types/snappyjs": ["@types/snappyjs@0.7.1", "", {}, "sha512-OxjzJ6cQZstysMh6PEwZWmK9qlKZyezHJKOkcUkZDooSFuog2votUEKkxMaTq51UQF3cJkXKQ+XGlj4FSl8JQQ=="],
|
||||
|
||||
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
||||
|
||||
"@types/ws": ["@types/ws@8.18.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-8svvI3hMyvN0kKCJMvTJP/x6Y/EoQbepff882wL+Sn5QsXb3etnamgrJq4isrBxSJj5L2AuXcI0+bgkoAXGUJw=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.33.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/type-utils": "8.33.1", "@typescript-eslint/utils": "8.33.1", "@typescript-eslint/visitor-keys": "8.33.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.33.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A=="],
|
||||
|
||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.33.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/types": "8.33.1", "@typescript-eslint/typescript-estree": "8.33.1", "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA=="],
|
||||
|
||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.33.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.33.1", "@typescript-eslint/types": "^8.33.1", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw=="],
|
||||
|
||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.33.1", "", { "dependencies": { "@typescript-eslint/types": "8.33.1", "@typescript-eslint/visitor-keys": "8.33.1" } }, "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA=="],
|
||||
|
||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.33.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g=="],
|
||||
|
||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.33.1", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.33.1", "@typescript-eslint/utils": "8.33.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww=="],
|
||||
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.33.1", "", {}, "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.33.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.33.1", "@typescript-eslint/tsconfig-utils": "8.33.1", "@typescript-eslint/types": "8.33.1", "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA=="],
|
||||
|
||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.33.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/types": "8.33.1", "@typescript-eslint/typescript-estree": "8.33.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ=="],
|
||||
|
||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.33.1", "", { "dependencies": { "@typescript-eslint/types": "8.33.1", "eslint-visitor-keys": "^4.2.0" } }, "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ=="],
|
||||
|
||||
"acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="],
|
||||
|
||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||
|
||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
|
||||
|
||||
"autolinker": ["autolinker@4.0.0", "", { "dependencies": { "tslib": "^2.3.0" } }, "sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw=="],
|
||||
|
||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
||||
|
||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.15", "", { "dependencies": { "@types/node": "*" } }, "sha512-NarRIaS+iOaQU1JPfyKhZm4AsUOrwUOqRNHY0XxI8GI8jYxiLXLcdjYMG9UKS+fwWasc1uw1htV9AX24dD+p4w=="],
|
||||
|
||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"code-red": ["code-red@1.0.4", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", "acorn": "^8.10.0", "estree-walker": "^3.0.3", "periscopic": "^3.1.0" } }, "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
|
||||
"core-js": ["core-js@3.41.0", "", {}, "sha512-SJ4/EHwS36QMJd6h/Rg+GyR4A5xE0FSI3eZ+iBVpfqf1x0eTSg1smWLHrA+2jQThZSh97fmSgFSU8B61nxosxA=="],
|
||||
|
||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||
|
||||
"css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="],
|
||||
|
||||
"custom-event-polyfill": ["custom-event-polyfill@1.0.7", "", {}, "sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w=="],
|
||||
|
||||
"date-fns": ["date-fns@2.30.0", "", { "dependencies": { "@babel/runtime": "^7.21.0" } }, "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw=="],
|
||||
|
||||
"date-fns-tz": ["date-fns-tz@2.0.1", "", { "peerDependencies": { "date-fns": "2.x" } }, "sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA=="],
|
||||
|
||||
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||
|
||||
"decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="],
|
||||
|
||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||
|
||||
"dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
|
||||
|
||||
"domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
|
||||
|
||||
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
|
||||
|
||||
"dompurify": ["dompurify@3.2.4", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg=="],
|
||||
|
||||
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
|
||||
|
||||
"emojibase": ["emojibase@16.0.0", "", {}, "sha512-Nw2m7JLIO4Ou2X/yZPRNscHQXVbbr6SErjkJ7EooG7MbR3yDZszCv9KTizsXFc7yZl0n3WF+qUKIC/Lw6H9xaQ=="],
|
||||
|
||||
"entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.28.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.28.0", "@eslint/plugin-kit": "^0.3.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ=="],
|
||||
|
||||
"eslint-config-prettier": ["eslint-config-prettier@9.1.0", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw=="],
|
||||
|
||||
"eslint-plugin-prettier": ["eslint-plugin-prettier@5.4.1", "", { "dependencies": { "prettier-linter-helpers": "^1.0.0", "synckit": "^0.11.7" }, "peerDependencies": { "@types/eslint": ">=8.0.0", "eslint": ">=8.0.0", "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", "prettier": ">=3.0.0" }, "optionalPeers": ["@types/eslint", "eslint-config-prettier"] }, "sha512-9dF+KuU/Ilkq27A8idRP7N2DH8iUR6qXcjF3FR2wETY21PZdBrIjwCau8oboyGj9b7etWmTGEeM8e7oOed6ZWg=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.3.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ=="],
|
||||
|
||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
|
||||
|
||||
"espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
|
||||
|
||||
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
||||
|
||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||
|
||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||
|
||||
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
|
||||
|
||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||
|
||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||
|
||||
"fast-diff": ["fast-diff@1.3.0", "", {}, "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw=="],
|
||||
|
||||
"fast-equals": ["fast-equals@5.2.2", "", {}, "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw=="],
|
||||
|
||||
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
||||
|
||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||
|
||||
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
||||
|
||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
||||
|
||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||
|
||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||
|
||||
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
||||
|
||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||
|
||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
||||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
|
||||
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"hls.js": ["hls.js@1.5.20", "", {}, "sha512-uu0VXUK52JhihhnN/MVVo1lvqNNuhoxkonqgO3IpjvQiGpJBdIXMGkofjQb/j9zvV7a1SW8U9g1FslWx/1HOiQ=="],
|
||||
|
||||
"htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="],
|
||||
|
||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
||||
|
||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||
|
||||
"intl-messageformat": ["intl-messageformat@10.7.15", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.3", "@formatjs/fast-memoize": "2.2.6", "@formatjs/icu-messageformat-parser": "2.11.1", "tslib": "2" } }, "sha512-LRyExsEsefQSBjU2p47oAheoKz+EOJxSLDdjOaEjdriajfHsMXOmV/EhMvYSg9bAgCUHasuAC+mcUBe/95PfIg=="],
|
||||
|
||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||
|
||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||
|
||||
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
||||
|
||||
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
||||
|
||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||
|
||||
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||
|
||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||
|
||||
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
||||
|
||||
"jwt-simple": ["jwt-simple@0.5.6", "", {}, "sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg=="],
|
||||
|
||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
|
||||
"linkify-it": ["linkify-it@5.0.0", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ=="],
|
||||
|
||||
"loadjs": ["loadjs@4.3.0", "", {}, "sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ=="],
|
||||
|
||||
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
||||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||
|
||||
"markdown-it": ["markdown-it@14.1.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", "linkify-it": "^5.0.0", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg=="],
|
||||
|
||||
"mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="],
|
||||
|
||||
"mdurl": ["mdurl@2.0.0", "", {}, "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="],
|
||||
|
||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||
|
||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||
|
||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||
|
||||
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
||||
|
||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||
|
||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||
|
||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||
|
||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"periscopic": ["periscopic@3.1.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", "is-reference": "^3.0.0" } }, "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw=="],
|
||||
|
||||
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"plyr": ["plyr@3.7.8", "", { "dependencies": { "core-js": "^3.26.1", "custom-event-polyfill": "^1.0.7", "loadjs": "^4.2.0", "rangetouch": "^2.0.1", "url-polyfill": "^1.1.12" } }, "sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA=="],
|
||||
|
||||
"postgres": ["postgres@3.4.5", "", {}, "sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg=="],
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
|
||||
|
||||
"prettier-linter-helpers": ["prettier-linter-helpers@1.0.0", "", { "dependencies": { "fast-diff": "^1.1.2" } }, "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w=="],
|
||||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
"punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="],
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
|
||||
"rangetouch": ["rangetouch@2.0.1", "", {}, "sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA=="],
|
||||
|
||||
"regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="],
|
||||
|
||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||
|
||||
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
||||
|
||||
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
||||
|
||||
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
||||
|
||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"snappyjs": ["snappyjs@0.7.0", "", {}, "sha512-u5iEEXkMe2EInQio6Wv9LWHOQYRDbD2O9hzS27GpT/lwfIQhTCnHCTqedqHIHe9ZcvQo+9au6vngQayipz1NYw=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"svelte": ["svelte@4.2.19", "", { "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", "@jridgewell/trace-mapping": "^0.3.18", "@types/estree": "^1.0.1", "acorn": "^8.9.0", "aria-query": "^5.3.0", "axobject-query": "^4.0.0", "code-red": "^1.0.3", "css-tree": "^2.3.1", "estree-walker": "^3.0.3", "is-reference": "^3.0.1", "locate-character": "^3.0.0", "magic-string": "^0.30.4", "periscopic": "^3.1.0" } }, "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw=="],
|
||||
|
||||
"synckit": ["synckit@0.11.8", "", { "dependencies": { "@pkgr/core": "^0.2.4" } }, "sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A=="],
|
||||
|
||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||
|
||||
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
||||
|
||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"turbo": ["turbo@2.5.4", "", { "optionalDependencies": { "turbo-darwin-64": "2.5.4", "turbo-darwin-arm64": "2.5.4", "turbo-linux-64": "2.5.4", "turbo-linux-arm64": "2.5.4", "turbo-windows-64": "2.5.4", "turbo-windows-arm64": "2.5.4" }, "bin": { "turbo": "bin/turbo" } }, "sha512-kc8ZibdRcuWUG1pbYSBFWqmIjynlD8Lp7IB6U3vIzvOv9VG+6Sp8bzyeBWE3Oi8XV5KsQrznyRTBPvrf99E4mA=="],
|
||||
|
||||
"turbo-darwin-64": ["turbo-darwin-64@2.5.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ah6YnH2dErojhFooxEzmvsoZQTMImaruZhFPfMKPBq8sb+hALRdvBNLqfc8NWlZq576FkfRZ/MSi4SHvVFT9PQ=="],
|
||||
|
||||
"turbo-darwin-arm64": ["turbo-darwin-arm64@2.5.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2+Nx6LAyuXw2MdXb7pxqle3MYignLvS7OwtsP9SgtSBaMlnNlxl9BovzqdYAgkUW3AsYiQMJ/wBRb7d+xemM5A=="],
|
||||
|
||||
"turbo-linux-64": ["turbo-linux-64@2.5.4", "", { "os": "linux", "cpu": "x64" }, "sha512-5May2kjWbc8w4XxswGAl74GZ5eM4Gr6IiroqdLhXeXyfvWEdm2mFYCSWOzz0/z5cAgqyGidF1jt1qzUR8hTmOA=="],
|
||||
|
||||
"turbo-linux-arm64": ["turbo-linux-arm64@2.5.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-/2yqFaS3TbfxV3P5yG2JUI79P7OUQKOUvAnx4MV9Bdz6jqHsHwc9WZPpO4QseQm+NvmgY6ICORnoVPODxGUiJg=="],
|
||||
|
||||
"turbo-windows-64": ["turbo-windows-64@2.5.4", "", { "os": "win32", "cpu": "x64" }, "sha512-EQUO4SmaCDhO6zYohxIjJpOKRN3wlfU7jMAj3CgcyTPvQR/UFLEKAYHqJOnJtymbQmiiM/ihX6c6W6Uq0yC7mA=="],
|
||||
|
||||
"turbo-windows-arm64": ["turbo-windows-arm64@2.5.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-oQ8RrK1VS8lrxkLriotFq+PiF7iiGgkZtfLKF4DDKsmdbPo0O9R2mQxm7jHLuXraRCuIQDWMIw6dpcr7Iykf4A=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
|
||||
|
||||
"typescript-eslint": ["typescript-eslint@8.33.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.33.1", "@typescript-eslint/parser": "8.33.1", "@typescript-eslint/utils": "8.33.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A=="],
|
||||
|
||||
"uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="],
|
||||
|
||||
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
|
||||
|
||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||
|
||||
"url-polyfill": ["url-polyfill@1.1.13", "", {}, "sha512-tXzkojrv2SujumYthZ/WjF7jaSfNhSXlYMpE5AYdL2I3D7DCeo+mch8KtW2rUuKjDg+3VXODXHVgipt8yGY/eQ=="],
|
||||
|
||||
"uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="],
|
||||
|
||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||
|
||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
# Rush uses this file to configure the NPM package registry during installation. It is applicable
|
||||
# to PNPM, NPM, and Yarn package managers. It is used by operations such as "rush install",
|
||||
# "rush update", and the "install-run.js" scripts.
|
||||
#
|
||||
# NOTE: The "rush publish" command uses .npmrc-publish instead.
|
||||
#
|
||||
# Before invoking the package manager, Rush will generate an .npmrc in the folder where installation
|
||||
# is performed. This generated file will omit any config lines that reference environment variables
|
||||
# that are undefined in that session; this avoids problems that would otherwise result due to
|
||||
# a missing variable being replaced by an empty string.
|
||||
#
|
||||
# If "subspacesEnabled" is true in subspaces.json, the generated file will merge settings from
|
||||
# "common/config/rush/.npmrc" and "common/config/subspaces/<name>/.npmrc", with the latter taking
|
||||
# precedence.
|
||||
#
|
||||
# * * * SECURITY WARNING * * *
|
||||
#
|
||||
# It is NOT recommended to store authentication tokens in a text file on a lab machine, because
|
||||
# other unrelated processes may be able to read that file. Also, the file may persist indefinitely,
|
||||
# for example if the machine loses power. A safer practice is to pass the token via an
|
||||
# environment variable, which can be referenced from .npmrc using ${} expansion. For example:
|
||||
#
|
||||
# //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}
|
||||
#
|
||||
|
||||
# Explicitly specify the NPM registry that "rush install" and "rush update" will use by default:
|
||||
registry=https://registry.npmjs.org/
|
||||
|
||||
# Optionally provide an authentication token for the above registry URL (if it is a private registry):
|
||||
# //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}
|
||||
|
||||
# Change this to "true" if your registry requires authentication for read-only operations:
|
||||
@hcengineering:registry=https://npm.pkg.github.com
|
||||
always-auth=false
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# This config file is very similar to common/config/rush/.npmrc, except that .npmrc-publish
|
||||
# is used by the "rush publish" command, as publishing often involves different credentials
|
||||
# and registries than other operations.
|
||||
#
|
||||
# Before invoking the package manager, Rush will copy this file to "common/temp/publish-home/.npmrc"
|
||||
# and then temporarily map that folder as the "home directory" for the current user account.
|
||||
# This enables the same settings to apply for each project folder that gets published. The copied file
|
||||
# will omit any config lines that reference environment variables that are undefined in that session;
|
||||
# this avoids problems that would otherwise result due to a missing variable being replaced by
|
||||
# an empty string.
|
||||
#
|
||||
# * * * SECURITY WARNING * * *
|
||||
#
|
||||
# It is NOT recommended to store authentication tokens in a text file on a lab machine, because
|
||||
# other unrelated processes may be able to read the file. Also, the file may persist indefinitely,
|
||||
# for example if the machine loses power. A safer practice is to pass the token via an
|
||||
# environment variable, which can be referenced from .npmrc using ${} expansion. For example:
|
||||
#
|
||||
# //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}
|
||||
#
|
||||
|
||||
# Explicitly specify the NPM registry that "rush publish" will use by default:
|
||||
registry=https://registry.npmjs.org/
|
||||
|
||||
# Provide an authentication token for the above registry URL:
|
||||
# //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}
|
||||
@@ -0,0 +1,38 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* When using the PNPM package manager, you can use pnpmfile.js to workaround
|
||||
* dependencies that have mistakes in their package.json file. (This feature is
|
||||
* functionally similar to Yarn's "resolutions".)
|
||||
*
|
||||
* For details, see the PNPM documentation:
|
||||
* https://pnpm.io/pnpmfile#hooks
|
||||
*
|
||||
* IMPORTANT: SINCE THIS FILE CONTAINS EXECUTABLE CODE, MODIFYING IT IS LIKELY TO INVALIDATE
|
||||
* ANY CACHED DEPENDENCY ANALYSIS. After any modification to pnpmfile.js, it's recommended to run
|
||||
* "rush update --full" so that PNPM will recalculate all version selections.
|
||||
*/
|
||||
module.exports = {
|
||||
hooks: {
|
||||
readPackage
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This hook is invoked during installation before a package's dependencies
|
||||
* are selected.
|
||||
* The `packageJson` parameter is the deserialized package.json
|
||||
* contents for the package that is about to be installed.
|
||||
* The `context` parameter provides a log() function.
|
||||
* The return value is the updated object.
|
||||
*/
|
||||
function readPackage(packageJson, context) {
|
||||
|
||||
// // The karma types have a missing dependency on typings from the log4js package.
|
||||
// if (packageJson.name === '@types/karma') {
|
||||
// context.log('Fixed up dependencies for @types/karma');
|
||||
// packageJson.dependencies['log4js'] = '0.6.38';
|
||||
// }
|
||||
|
||||
return packageJson;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* This configuration file manages Rush integration with JFrog Artifactory services.
|
||||
* More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/artifactory.schema.json",
|
||||
|
||||
"packageRegistry": {
|
||||
/**
|
||||
* (Required) Set this to "true" to enable Rush to manage tokens for an Artifactory NPM registry.
|
||||
* When enabled, "rush install" will automatically detect when the user's ~/.npmrc
|
||||
* authentication token is missing or expired. And "rush setup" will prompt the user to
|
||||
* renew their token.
|
||||
*
|
||||
* The default value is false.
|
||||
*/
|
||||
"enabled": false,
|
||||
|
||||
/**
|
||||
* (Required) Specify the URL of your NPM registry. This is the same URL that appears in
|
||||
* your .npmrc file. It should look something like this example:
|
||||
*
|
||||
* https://your-company.jfrog.io/your-project/api/npm/npm-private/
|
||||
*/
|
||||
"registryUrl": "",
|
||||
|
||||
/**
|
||||
* A list of custom strings that "rush setup" should add to the user's ~/.npmrc file at the time
|
||||
* when the token is updated. This could be used for example to configure the company registry
|
||||
* to be used whenever NPM is invoked as a standalone command (but it's not needed for Rush
|
||||
* operations like "rush add" and "rush install", which get their mappings from the monorepo's
|
||||
* common/config/rush/.npmrc file).
|
||||
*
|
||||
* NOTE: The ~/.npmrc settings are global for the user account on a given machine, so be careful
|
||||
* about adding settings that may interfere with other work outside the monorepo.
|
||||
*/
|
||||
"userNpmrcLinesToAdd": [
|
||||
// "@example:registry=https://your-company.jfrog.io/your-project/api/npm/npm-private/"
|
||||
],
|
||||
|
||||
/**
|
||||
* (Required) Specifies the URL of the Artifactory control panel where the user can generate
|
||||
* an API key. This URL is printed after the "visitWebsite" message.
|
||||
* It should look something like this example: https://your-company.jfrog.io/
|
||||
* Specify an empty string to suppress this line entirely.
|
||||
*/
|
||||
"artifactoryWebsiteUrl": "",
|
||||
|
||||
/**
|
||||
* Uncomment this line to specify the type of credential to save in the user's ~/.npmrc file.
|
||||
* The default is "password", which means the user's API token will be traded in for an
|
||||
* npm password specific to that registry. Optionally you can specify "authToken", which
|
||||
* will save the user's API token as credentials instead.
|
||||
*/
|
||||
// "credentialType": "password",
|
||||
|
||||
/**
|
||||
* These settings allow the "rush setup" interactive prompts to be customized, for
|
||||
* example with messages specific to your team or configuration. Specify an empty string
|
||||
* to suppress that message entirely.
|
||||
*/
|
||||
"messageOverrides": {
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "This monorepo consumes packages from an Artifactory private NPM registry."
|
||||
*/
|
||||
// "introduction": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Please contact the repository maintainers for help with setting up an Artifactory user account."
|
||||
*/
|
||||
// "obtainAnAccount": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Please open this URL in your web browser:"
|
||||
*
|
||||
* The "artifactoryWebsiteUrl" string is printed after this message.
|
||||
*/
|
||||
// "visitWebsite": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Your user name appears in the upper-right corner of the JFrog website."
|
||||
*/
|
||||
// "locateUserName": "",
|
||||
|
||||
/**
|
||||
* Overrides the message that normally says:
|
||||
* "Click 'Edit Profile' on the JFrog website. Click the 'Generate API Key'
|
||||
* button if you haven't already done so previously."
|
||||
*/
|
||||
// "locateApiKey": ""
|
||||
|
||||
/**
|
||||
* Overrides the message that normally prompts:
|
||||
* "What is your Artifactory user name?"
|
||||
*/
|
||||
// "userNamePrompt": ""
|
||||
|
||||
/**
|
||||
* Overrides the message that normally prompts:
|
||||
* "What is your Artifactory API key?"
|
||||
*/
|
||||
// "apiKeyPrompt": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* This configuration file manages Rush's build cache feature.
|
||||
* More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/build-cache.schema.json",
|
||||
|
||||
/**
|
||||
* (Required) EXPERIMENTAL - Set this to true to enable the build cache feature.
|
||||
*
|
||||
* See https://rushjs.io/pages/maintainer/build_cache/ for details about this experimental feature.
|
||||
*/
|
||||
"buildCacheEnabled": false,
|
||||
|
||||
/**
|
||||
* (Required) Choose where project build outputs will be cached.
|
||||
*
|
||||
* Possible values: "local-only", "azure-blob-storage", "amazon-s3"
|
||||
*/
|
||||
"cacheProvider": "local-only",
|
||||
|
||||
/**
|
||||
* Setting this property overrides the cache entry ID. If this property is set, it must contain
|
||||
* a [hash] token.
|
||||
*
|
||||
* Other available tokens:
|
||||
* - [projectName] Example: "@my-scope/my-project"
|
||||
* - [projectName:normalize] Example: "my-scope+my-project"
|
||||
* - [phaseName] Example: "_phase:test/api"
|
||||
* - [phaseName:normalize] Example: "_phase:test+api"
|
||||
* - [phaseName:trimPrefix] Example: "test/api"
|
||||
* - [os] Example: "win32"
|
||||
* - [arch] Example: "x64"
|
||||
*/
|
||||
// "cacheEntryNamePattern": "[projectName:normalize]-[phaseName:normalize]-[hash]"
|
||||
|
||||
/**
|
||||
* (Optional) Salt to inject during calculation of the cache key. This can be used to invalidate the cache for all projects when the salt changes.
|
||||
*/
|
||||
// "cacheHashSalt": "1",
|
||||
|
||||
/**
|
||||
* Use this configuration with "cacheProvider"="azure-blob-storage"
|
||||
*/
|
||||
"azureBlobStorageConfiguration": {
|
||||
/**
|
||||
* (Required) The name of the the Azure storage account to use for build cache.
|
||||
*/
|
||||
// "storageAccountName": "example",
|
||||
|
||||
/**
|
||||
* (Required) The name of the container in the Azure storage account to use for build cache.
|
||||
*/
|
||||
// "storageContainerName": "my-container",
|
||||
|
||||
/**
|
||||
* The Azure environment the storage account exists in. Defaults to AzurePublicCloud.
|
||||
*
|
||||
* Possible values: "AzurePublicCloud", "AzureChina", "AzureGermany", "AzureGovernment"
|
||||
*/
|
||||
// "azureEnvironment": "AzurePublicCloud",
|
||||
|
||||
/**
|
||||
* An optional prefix for cache item blob names.
|
||||
*/
|
||||
// "blobPrefix": "my-prefix",
|
||||
|
||||
/**
|
||||
* If set to true, allow writing to the cache. Defaults to false.
|
||||
*/
|
||||
// "isCacheWriteAllowed": true,
|
||||
|
||||
/**
|
||||
* The Entra ID login flow to use. Defaults to 'AdoCodespacesAuth' on GitHub Codespaces, 'InteractiveBrowser' otherwise.
|
||||
*/
|
||||
// "loginFlow": "InteractiveBrowser",
|
||||
|
||||
/**
|
||||
* If set to true, reading the cache requires authentication. Defaults to false.
|
||||
*/
|
||||
// "readRequiresAuthentication": true
|
||||
},
|
||||
|
||||
/**
|
||||
* Use this configuration with "cacheProvider"="amazon-s3"
|
||||
*/
|
||||
"amazonS3Configuration": {
|
||||
/**
|
||||
* (Required unless s3Endpoint is specified) The name of the bucket to use for build cache.
|
||||
* Example: "my-bucket"
|
||||
*/
|
||||
// "s3Bucket": "my-bucket",
|
||||
|
||||
/**
|
||||
* (Required unless s3Bucket is specified) The Amazon S3 endpoint of the bucket to use for build cache.
|
||||
* This should not include any path; use the s3Prefix to set the path.
|
||||
* Examples: "my-bucket.s3.us-east-2.amazonaws.com" or "http://localhost:9000"
|
||||
*/
|
||||
// "s3Endpoint": "https://my-bucket.s3.us-east-2.amazonaws.com",
|
||||
|
||||
/**
|
||||
* (Required) The Amazon S3 region of the bucket to use for build cache.
|
||||
* Example: "us-east-1"
|
||||
*/
|
||||
// "s3Region": "us-east-1",
|
||||
|
||||
/**
|
||||
* An optional prefix ("folder") for cache items. It should not start with "/".
|
||||
*/
|
||||
// "s3Prefix": "my-prefix",
|
||||
|
||||
/**
|
||||
* If set to true, allow writing to the cache. Defaults to false.
|
||||
*/
|
||||
// "isCacheWriteAllowed": true
|
||||
},
|
||||
|
||||
/**
|
||||
* Use this configuration with "cacheProvider"="http"
|
||||
*/
|
||||
"httpConfiguration": {
|
||||
/**
|
||||
* (Required) The URL of the server that stores the caches.
|
||||
* Example: "https://build-cacches.example.com/"
|
||||
*/
|
||||
// "url": "https://build-cacches.example.com/",
|
||||
|
||||
/**
|
||||
* (Optional) The HTTP method to use when writing to the cache (defaults to PUT).
|
||||
* Should be one of PUT, POST, or PATCH.
|
||||
* Example: "PUT"
|
||||
*/
|
||||
// "uploadMethod": "PUT",
|
||||
|
||||
/**
|
||||
* (Optional) HTTP headers to pass to the cache server.
|
||||
* Example: { "X-HTTP-Company-Id": "109283" }
|
||||
*/
|
||||
// "headers": {},
|
||||
|
||||
/**
|
||||
* (Optional) Shell command that prints the authorization token needed to communicate with the
|
||||
* cache server, and exits with exit code 0. This command will be executed from the root of
|
||||
* the monorepo.
|
||||
* Example: { "exec": "node", "args": ["common/scripts/auth.js"] }
|
||||
*/
|
||||
// "tokenHandler": { "exec": "node", "args": ["common/scripts/auth.js"] },
|
||||
|
||||
/**
|
||||
* (Optional) Prefix for cache keys.
|
||||
* Example: "my-company-"
|
||||
*/
|
||||
// "cacheKeyPrefix": "",
|
||||
|
||||
/**
|
||||
* (Optional) If set to true, allow writing to the cache. Defaults to false.
|
||||
*/
|
||||
// "isCacheWriteAllowed": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* This configuration file manages Rush's cobuild feature.
|
||||
* More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/cobuild.schema.json",
|
||||
|
||||
/**
|
||||
* (Required) EXPERIMENTAL - Set this to true to enable the cobuild feature.
|
||||
* RUSH_COBUILD_CONTEXT_ID should always be specified as an environment variable with an non-empty string,
|
||||
* otherwise the cobuild feature will be disabled.
|
||||
*/
|
||||
"cobuildFeatureEnabled": false,
|
||||
|
||||
/**
|
||||
* (Required) Choose where cobuild lock will be acquired.
|
||||
*
|
||||
* The lock provider is registered by the rush plugins.
|
||||
* For example, @rushstack/rush-redis-cobuild-plugin registers the "redis" lock provider.
|
||||
*/
|
||||
"cobuildLockProvider": "redis"
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* This configuration file defines custom commands for the "rush" command-line.
|
||||
* More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
|
||||
|
||||
"phases": [
|
||||
{
|
||||
"name": "_phase:build",
|
||||
"dependencies": {
|
||||
"upstream": ["_phase:build"]
|
||||
},
|
||||
"ignoreMissingScript": true,
|
||||
"allowWarningsOnSuccess": false
|
||||
},
|
||||
{
|
||||
"name": "_phase:validate",
|
||||
"dependencies": {
|
||||
"self": ["_phase:build"],
|
||||
"upstream": ["_phase:validate", "_phase:build"]
|
||||
},
|
||||
"ignoreMissingScript": true,
|
||||
"allowWarningsOnSuccess": false
|
||||
},
|
||||
{
|
||||
"name": "_phase:bundle",
|
||||
"dependencies": {
|
||||
"self": ["_phase:build"]
|
||||
},
|
||||
"ignoreMissingScript": true,
|
||||
"allowWarningsOnSuccess": false
|
||||
},
|
||||
],
|
||||
"commands": [
|
||||
{
|
||||
"commandKind": "phased",
|
||||
"name": "build",
|
||||
"summary": "build",
|
||||
"phases": ["_phase:build"],
|
||||
"enableParallelism": true,
|
||||
"incremental": true,
|
||||
"watchOptions": {
|
||||
"alwaysWatch": false,
|
||||
"watchPhases": ["_phase:build"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandKind": "phased",
|
||||
"name": "validate",
|
||||
"phases": ["_phase:validate"],
|
||||
"summary": "validate",
|
||||
"enableParallelism": true,
|
||||
"incremental": true
|
||||
},
|
||||
{
|
||||
"commandKind": "bulk",
|
||||
"name": "format",
|
||||
"summary": "Format",
|
||||
"description": "Perform a formatting",
|
||||
"enableParallelism": true,
|
||||
"incremental": false,
|
||||
"ignoreMissingScript": true,
|
||||
"safeForSimultaneousRushProcesses": true,
|
||||
"disableBuildCache": true
|
||||
},
|
||||
{
|
||||
"commandKind": "bulk",
|
||||
"name": "lint",
|
||||
"summary": "Lint",
|
||||
"description": "Linting",
|
||||
"enableParallelism": true,
|
||||
"incremental": false,
|
||||
"ignoreMissingScript": true,
|
||||
"safeForSimultaneousRushProcesses": true,
|
||||
"disableBuildCache": true
|
||||
},
|
||||
{
|
||||
"commandKind": "bulk",
|
||||
"name": "lint:fix",
|
||||
"summary": "Lint & fix",
|
||||
"description": "Linting and fixing",
|
||||
"enableParallelism": true,
|
||||
"incremental": false,
|
||||
"ignoreMissingScript": true,
|
||||
"safeForSimultaneousRushProcesses": true,
|
||||
"disableBuildCache": true
|
||||
}
|
||||
],
|
||||
|
||||
/**
|
||||
* Custom "parameters" introduce new parameters for specified Rush command-line commands.
|
||||
* For example, you might define a "--production" parameter for the "rush build" command.
|
||||
*/
|
||||
"parameters": [
|
||||
{
|
||||
"parameterKind": "flag",
|
||||
"longName": "--lite",
|
||||
"shortName": "-l",
|
||||
"description": "Enable Heft lite building option, will skip some phases.",
|
||||
"associatedCommands": ["build"]
|
||||
},
|
||||
{
|
||||
"parameterKind": "flag",
|
||||
"longName": "--clean",
|
||||
"description": "Enable Heft clean building option",
|
||||
"associatedCommands": ["build"]
|
||||
},
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom parameter.
|
||||
// * A "flag" is a custom command-line parameter whose presence acts as an on/off switch.
|
||||
// */
|
||||
// "parameterKind": "flag",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The long name of the parameter. It must be lower-case and use dash delimiters.
|
||||
// */
|
||||
// "longName": "--my-flag",
|
||||
//
|
||||
// /**
|
||||
// * An optional alternative short name for the parameter. It must be a dash followed by a single
|
||||
// * lower-case or upper-case letter, which is case-sensitive.
|
||||
// *
|
||||
// * NOTE: The Rush developers recommend that automation scripts should always use the long name
|
||||
// * to improve readability. The short name is only intended as a convenience for humans.
|
||||
// * The alphabet letters run out quickly, and are difficult to memorize, so *only* use
|
||||
// * a short name if you expect the parameter to be needed very often in everyday operations.
|
||||
// */
|
||||
// "shortName": "-m",
|
||||
//
|
||||
// /**
|
||||
// * (Required) A long description to be shown in the command-line help.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "A custom flag parameter that is passed to the scripts that are invoked when building projects",
|
||||
//
|
||||
// /**
|
||||
// * (Required) A list of custom commands and/or built-in Rush commands that this parameter may
|
||||
// * be used with. The parameter will be appended to the shell command that Rush invokes.
|
||||
// */
|
||||
// "associatedCommands": ["build", "rebuild"]
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom parameter.
|
||||
// * A "string" is a custom command-line parameter whose value is a simple text string.
|
||||
// */
|
||||
// "parameterKind": "string",
|
||||
// "longName": "--my-string",
|
||||
// "description": "A custom string parameter for the \"my-global-command\" custom command",
|
||||
//
|
||||
// "associatedCommands": ["my-global-command"],
|
||||
//
|
||||
// /**
|
||||
// * The name of the argument, which will be shown in the command-line help.
|
||||
// *
|
||||
// * For example, if the parameter name is '--count" and the argument name is "NUMBER",
|
||||
// * then the command-line help would display "--count NUMBER". The argument name must
|
||||
// * be comprised of upper-case letters, numbers, and underscores. It should be kept short.
|
||||
// */
|
||||
// "argumentName": "SOME_TEXT",
|
||||
//
|
||||
// /**
|
||||
// * If true, this parameter must be included with the command. The default is false.
|
||||
// */
|
||||
// "required": false
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom parameter.
|
||||
// * A "choice" is a custom command-line parameter whose argument must be chosen from a list of
|
||||
// * allowable alternatives.
|
||||
// */
|
||||
// "parameterKind": "choice",
|
||||
// "longName": "--my-choice",
|
||||
// "description": "A custom choice parameter for the \"my-global-command\" custom command",
|
||||
//
|
||||
// "associatedCommands": ["my-global-command"],
|
||||
//
|
||||
// /**
|
||||
// * If true, this parameter must be included with the command. The default is false.
|
||||
// */
|
||||
// "required": false,
|
||||
//
|
||||
// /**
|
||||
// * Normally if a parameter is omitted from the command line, it will not be passed
|
||||
// * to the shell command. this value will be inserted by default. Whereas if a "defaultValue"
|
||||
// * is defined, the parameter will always be passed to the shell command, and will use the
|
||||
// * default value if unspecified. The value must be one of the defined alternatives.
|
||||
// */
|
||||
// "defaultValue": "vanilla",
|
||||
//
|
||||
// /**
|
||||
// * (Required) A list of alternative argument values that can be chosen for this parameter.
|
||||
// */
|
||||
// "alternatives": [
|
||||
// {
|
||||
// /**
|
||||
// * A token that is one of the alternatives that can be used with the choice parameter,
|
||||
// * e.g. "vanilla" in "--flavor vanilla".
|
||||
// */
|
||||
// "name": "vanilla",
|
||||
//
|
||||
// /**
|
||||
// * A detailed description for the alternative that can be shown in the command-line help.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "Use the vanilla flavor (the default)"
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// "name": "chocolate",
|
||||
// "description": "Use the chocolate flavor"
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// "name": "strawberry",
|
||||
// "description": "Use the strawberry flavor"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* This configuration file specifies NPM dependency version selections that affect all projects
|
||||
* in a Rush repo. More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/common-versions.schema.json",
|
||||
|
||||
/**
|
||||
* A table that specifies a "preferred version" for a given NPM package. This feature is typically used
|
||||
* to hold back an indirect dependency to a specific older version, or to reduce duplication of indirect dependencies.
|
||||
*
|
||||
* The "preferredVersions" value can be any SemVer range specifier (e.g. "~1.2.3"). Rush injects these values into
|
||||
* the "dependencies" field of the top-level common/temp/package.json, which influences how the package manager
|
||||
* will calculate versions. The specific effect depends on your package manager. Generally it will have no
|
||||
* effect on an incompatible or already constrained SemVer range. If you are using PNPM, similar effects can be
|
||||
* achieved using the pnpmfile.js hook. See the Rush documentation for more details.
|
||||
*
|
||||
* After modifying this field, it's recommended to run "rush update --full" so that the package manager
|
||||
* will recalculate all version selections.
|
||||
*/
|
||||
"preferredVersions": {
|
||||
/**
|
||||
* When someone asks for "^1.0.0" make sure they get "1.2.3" when working in this repo,
|
||||
* instead of the latest version.
|
||||
*/
|
||||
// "some-library": "1.2.3"
|
||||
},
|
||||
|
||||
/**
|
||||
* When set to true, for all projects in the repo, all dependencies will be automatically added as preferredVersions,
|
||||
* except in cases where different projects specify different version ranges for a given dependency. For older
|
||||
* package managers, this tended to reduce duplication of indirect dependencies. However, it can sometimes cause
|
||||
* trouble for indirect dependencies with incompatible peerDependencies ranges.
|
||||
*
|
||||
* The default value is true. If you're encountering installation errors related to peer dependencies,
|
||||
* it's recommended to set this to false.
|
||||
*
|
||||
* After modifying this field, it's recommended to run "rush update --full" so that the package manager
|
||||
* will recalculate all version selections.
|
||||
*/
|
||||
// "implicitlyPreferredVersions": false,
|
||||
|
||||
/**
|
||||
* If you would like the version specifiers for your dependencies to be consistent, then
|
||||
* uncomment this line. This is effectively similar to running "rush check" before any
|
||||
* of the following commands:
|
||||
*
|
||||
* rush install, rush update, rush link, rush version, rush publish
|
||||
*
|
||||
* In some cases you may want this turned on, but need to allow certain packages to use a different
|
||||
* version. In those cases, you will need to add an entry to the "allowedAlternativeVersions"
|
||||
* section of the common-versions.json.
|
||||
*
|
||||
* In the case that subspaces is enabled, this setting will take effect at a subspace level.
|
||||
*/
|
||||
// "ensureConsistentVersions": true,
|
||||
|
||||
/**
|
||||
* The "rush check" command can be used to enforce that every project in the repo must specify
|
||||
* the same SemVer range for a given dependency. However, sometimes exceptions are needed.
|
||||
* The allowedAlternativeVersions table allows you to list other SemVer ranges that will be
|
||||
* accepted by "rush check" for a given dependency.
|
||||
*
|
||||
* IMPORTANT: THIS TABLE IS FOR *ADDITIONAL* VERSION RANGES THAT ARE ALTERNATIVES TO THE
|
||||
* USUAL VERSION (WHICH IS INFERRED BY LOOKING AT ALL PROJECTS IN THE REPO).
|
||||
* This design avoids unnecessary churn in this file.
|
||||
*/
|
||||
"allowedAlternativeVersions": {
|
||||
/**
|
||||
* For example, allow some projects to use an older TypeScript compiler
|
||||
* (in addition to whatever "usual" version is being used by other projects in the repo):
|
||||
*/
|
||||
// "typescript": [
|
||||
// "~2.4.0"
|
||||
// ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* This configuration file allows repo maintainers to configure extra details to be
|
||||
* printed alongside certain Rush messages. More documentation is available on the
|
||||
* Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/custom-tips.schema.json",
|
||||
|
||||
/**
|
||||
* Custom tips allow you to annotate Rush's console messages with advice tailored for
|
||||
* your specific monorepo.
|
||||
*/
|
||||
"customTips": [
|
||||
// {
|
||||
// /**
|
||||
// * (REQUIRED) An identifier indicating a message that may be printed by Rush.
|
||||
// * If that message is printed, then this custom tip will be shown.
|
||||
// * The list of available tip identifiers can be found on this page:
|
||||
// * https://rushjs.io/pages/maintainer/custom_tips/
|
||||
// */
|
||||
// "tipId": "TIP_RUSH_INCONSISTENT_VERSIONS",
|
||||
//
|
||||
// /**
|
||||
// * (REQUIRED) The message text to be displayed for this tip.
|
||||
// */
|
||||
// "message": "For additional troubleshooting information, refer this wiki article:\n\nhttps://intranet.contoso.com/docs/pnpm-mismatch"
|
||||
// }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* This configuration file allows repo maintainers to enable and disable experimental
|
||||
* Rush features. More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/experiments.schema.json",
|
||||
|
||||
/**
|
||||
* By default, 'rush install' passes --no-prefer-frozen-lockfile to 'pnpm install'.
|
||||
* Set this option to true to pass '--frozen-lockfile' instead for faster installs.
|
||||
*/
|
||||
// "usePnpmFrozenLockfileForRushInstall": true,
|
||||
|
||||
/**
|
||||
* By default, 'rush update' passes --no-prefer-frozen-lockfile to 'pnpm install'.
|
||||
* Set this option to true to pass '--prefer-frozen-lockfile' instead to minimize shrinkwrap changes.
|
||||
*/
|
||||
// "usePnpmPreferFrozenLockfileForRushUpdate": true,
|
||||
|
||||
/**
|
||||
* By default, 'rush update' runs as a single operation.
|
||||
* Set this option to true to instead update the lockfile with `--lockfile-only`, then perform a `--frozen-lockfile` install.
|
||||
* Necessary when using the `afterAllResolved` hook in .pnpmfile.cjs.
|
||||
*/
|
||||
// "usePnpmLockfileOnlyThenFrozenLockfileForRushUpdate": true,
|
||||
|
||||
/**
|
||||
* If using the 'preventManualShrinkwrapChanges' option, restricts the hash to only include the layout of external dependencies.
|
||||
* Used to allow links between workspace projects or the addition/removal of references to existing dependency versions to not
|
||||
* cause hash changes.
|
||||
*/
|
||||
// "omitImportersFromPreventManualShrinkwrapChanges": true,
|
||||
|
||||
/**
|
||||
* If true, the chmod field in temporary project tar headers will not be normalized.
|
||||
* This normalization can help ensure consistent tarball integrity across platforms.
|
||||
*/
|
||||
// "noChmodFieldInTarHeaderNormalization": true,
|
||||
|
||||
/**
|
||||
* If true, build caching will respect the allowWarningsInSuccessfulBuild flag and cache builds with warnings.
|
||||
* This will not replay warnings from the cached build.
|
||||
*/
|
||||
// "buildCacheWithAllowWarningsInSuccessfulBuild": true,
|
||||
|
||||
/**
|
||||
* If true, build skipping will respect the allowWarningsInSuccessfulBuild flag and skip builds with warnings.
|
||||
* This will not replay warnings from the skipped build.
|
||||
*/
|
||||
// "buildSkipWithAllowWarningsInSuccessfulBuild": true,
|
||||
|
||||
/**
|
||||
* If true, perform a clean install after when running `rush install` or `rush update` if the
|
||||
* `.npmrc` file has changed since the last install.
|
||||
*/
|
||||
// "cleanInstallAfterNpmrcChanges": true,
|
||||
|
||||
/**
|
||||
* If true, print the outputs of shell commands defined in event hooks to the console.
|
||||
*/
|
||||
// "printEventHooksOutputToConsole": true,
|
||||
|
||||
/**
|
||||
* If true, Rush will not allow node_modules in the repo folder or in parent folders.
|
||||
*/
|
||||
// "forbidPhantomResolvableNodeModulesFolders": true,
|
||||
|
||||
/**
|
||||
* (UNDER DEVELOPMENT) For certain installation problems involving peer dependencies, PNPM cannot
|
||||
* correctly satisfy versioning requirements without installing duplicate copies of a package inside the
|
||||
* node_modules folder. This poses a problem for "workspace:*" dependencies, as they are normally
|
||||
* installed by making a symlink to the local project source folder. PNPM's "injected dependencies"
|
||||
* feature provides a model for copying the local project folder into node_modules, however copying
|
||||
* must occur AFTER the dependency project is built and BEFORE the consuming project starts to build.
|
||||
* The "pnpm-sync" tool manages this operation; see its documentation for details.
|
||||
* Enable this experiment if you want "rush" and "rushx" commands to resync injected dependencies
|
||||
* by invoking "pnpm-sync" during the build.
|
||||
*/
|
||||
// "usePnpmSyncForInjectedDependencies": true,
|
||||
|
||||
/**
|
||||
* If set to true, Rush will generate a `project-impact-graph.yaml` file in the repository root during `rush update`.
|
||||
*/
|
||||
// "generateProjectImpactGraphDuringRushUpdate": true,
|
||||
|
||||
/**
|
||||
* If true, when running in watch mode, Rush will check for phase scripts named `_phase:<name>:ipc` and run them instead
|
||||
* of `_phase:<name>` if they exist. The created child process will be provided with an IPC channel and expected to persist
|
||||
* across invocations.
|
||||
*/
|
||||
// "useIPCScriptsInWatchMode": true,
|
||||
|
||||
/**
|
||||
* (UNDER DEVELOPMENT) The Rush alerts feature provides a way to send announcements to engineers
|
||||
* working in the monorepo, by printing directly in the user's shell window when they invoke Rush commands.
|
||||
* This ensures that important notices will be seen by anyone doing active development, since people often
|
||||
* ignore normal discussion group messages or don't know to subscribe.
|
||||
*/
|
||||
// "rushAlerts": true,
|
||||
|
||||
|
||||
/**
|
||||
* When using cobuilds, this experiment allows uncacheable operations to benefit from cobuild orchestration without using the build cache.
|
||||
*/
|
||||
// "allowCobuildWithoutCache": true,
|
||||
|
||||
/**
|
||||
* By default, rush perform a full scan of the entire repository. For example, Rush runs `git status` to check for local file changes.
|
||||
* When this toggle is enabled, Rush will only scan specific paths, significantly speeding up Git operations.
|
||||
*/
|
||||
// "enableSubpathScan": true,
|
||||
|
||||
/**
|
||||
* Rush has a policy that normally requires Rush projects to specify `workspace:*` in package.json when depending
|
||||
* on other projects in the workspace, unless they are explicitly declared as `decoupledLocalDependencies`
|
||||
* in rush.json. Enabling this experiment will remove that requirement for dependencies belonging to a different
|
||||
* subspace. This is useful for large product groups who work in separate subspaces and generally prefer to consume
|
||||
* each other's packages via the NPM registry.
|
||||
*/
|
||||
// "exemptDecoupledDependenciesBetweenSubspaces": false
|
||||
}
|
||||
@@ -0,0 +1,331 @@
|
||||
/**
|
||||
* This configuration file provides settings specific to the PNPM package manager.
|
||||
* More documentation is available on the Rush website: https://rushjs.io
|
||||
*
|
||||
* Rush normally looks for this file in `common/config/rush/pnpm-config.json`. However,
|
||||
* if `subspacesEnabled` is true in subspaces.json, then Rush will instead first look
|
||||
* for `common/config/subspaces/<name>/pnpm-config.json`. (If the file exists in both places,
|
||||
* then the file under `common/config/rush` is ignored.)
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/pnpm-config.schema.json",
|
||||
|
||||
/**
|
||||
* If true, then `rush install` and `rush update` will use the PNPM workspaces feature
|
||||
* to perform the install, instead of the old model where Rush generated the symlinks
|
||||
* for each projects's node_modules folder.
|
||||
*
|
||||
* When using workspaces, Rush will generate a `common/temp/pnpm-workspace.yaml` file referencing
|
||||
* all local projects to install. Rush will also generate a `.pnpmfile.cjs` shim which implements
|
||||
* Rush-specific features such as preferred versions. The user's `common/config/rush/.pnpmfile.cjs`
|
||||
* is invoked by the shim.
|
||||
*
|
||||
* This option is strongly recommended. The default value is false.
|
||||
*/
|
||||
"useWorkspaces": true,
|
||||
|
||||
/**
|
||||
* This setting determines how PNPM chooses version numbers during `rush update`.
|
||||
* For example, suppose `lib-x@3.0.0` depends on `"lib-y": "^1.2.3"` whose latest major
|
||||
* releases are `1.8.9` and `2.3.4`. The resolution mode `lowest-direct` might choose
|
||||
* `lib-y@1.2.3`, wheres `highest` will choose 1.8.9, and `time-based` will pick the
|
||||
* highest compatible version at the time when `lib-x@3.0.0` itself was published (ensuring
|
||||
* that the version could have been tested by the maintainer of "lib-x"). For local workspace
|
||||
* projects, `time-based` instead works like `lowest-direct`, avoiding upgrades unless
|
||||
* they are explicitly requested. Although `time-based` is the most robust option, it may be
|
||||
* slightly slower with registries such as npmjs.com that have not implemented an optimization.
|
||||
*
|
||||
* IMPORTANT: Be aware that PNPM 8.0.0 initially defaulted to `lowest-direct` instead of
|
||||
* `highest`, but PNPM reverted this decision in 8.6.12 because it caused confusion for users.
|
||||
* Rush version 5.106.0 and newer avoids this confusion by consistently defaulting to
|
||||
* `highest` when `resolutionMode` is not explicitly set in pnpm-config.json or .npmrc,
|
||||
* regardless of your PNPM version.
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/npmrc#resolution-mode
|
||||
*
|
||||
* Possible values are: `highest`, `time-based`, and `lowest-direct`.
|
||||
* The default is `highest`.
|
||||
*/
|
||||
// "resolutionMode": "time-based",
|
||||
|
||||
/**
|
||||
* This setting determines whether PNPM will automatically install (non-optional)
|
||||
* missing peer dependencies instead of reporting an error. Doing so conveniently
|
||||
* avoids the need to specify peer versions in package.json, but in a large monorepo
|
||||
* this often creates worse problems. The reason is that peer dependency behavior
|
||||
* is inherently complicated, and it is easier to troubleshoot consequences of an explicit
|
||||
* version than an invisible heuristic. The original NPM RFC discussion pointed out
|
||||
* some other problems with this feature: https://github.com/npm/rfcs/pull/43
|
||||
|
||||
* IMPORTANT: Without Rush, the setting defaults to true for PNPM 8 and newer; however,
|
||||
* as of Rush version 5.109.0 the default is always false unless `autoInstallPeers`
|
||||
* is specified in pnpm-config.json or .npmrc, regardless of your PNPM version.
|
||||
|
||||
* PNPM documentation: https://pnpm.io/npmrc#auto-install-peers
|
||||
|
||||
* The default value is false.
|
||||
*/
|
||||
// "autoInstallPeers": false,
|
||||
|
||||
/**
|
||||
* If true, then Rush will add the `--strict-peer-dependencies` command-line parameter when
|
||||
* invoking PNPM. This causes `rush update` to fail if there are unsatisfied peer dependencies,
|
||||
* which is an invalid state that can cause build failures or incompatible dependency versions.
|
||||
* (For historical reasons, JavaScript package managers generally do not treat this invalid
|
||||
* state as an error.)
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/npmrc#strict-peer-dependencies
|
||||
*
|
||||
* The default value is false to avoid legacy compatibility issues.
|
||||
* It is strongly recommended to set `strictPeerDependencies=true`.
|
||||
*/
|
||||
// "strictPeerDependencies": true,
|
||||
|
||||
/**
|
||||
* Environment variables that will be provided to PNPM.
|
||||
*/
|
||||
// "environmentVariables": {
|
||||
// "NODE_OPTIONS": {
|
||||
// "value": "--max-old-space-size=4096",
|
||||
// "override": false
|
||||
// }
|
||||
// },
|
||||
|
||||
/**
|
||||
* Specifies the location of the PNPM store. There are two possible values:
|
||||
*
|
||||
* - `local` - use the `pnpm-store` folder in the current configured temp folder:
|
||||
* `common/temp/pnpm-store` by default.
|
||||
* - `global` - use PNPM's global store, which has the benefit of being shared
|
||||
* across multiple repo folders, but the disadvantage of less isolation for builds
|
||||
* (for example, bugs or incompatibilities when two repos use different releases of PNPM)
|
||||
*
|
||||
* In both cases, the store path can be overridden by the environment variable `RUSH_PNPM_STORE_PATH`.
|
||||
*
|
||||
* The default value is `local`.
|
||||
*/
|
||||
// "pnpmStore": "global",
|
||||
|
||||
/**
|
||||
* If true, then `rush install` will report an error if manual modifications
|
||||
* were made to the PNPM shrinkwrap file without running `rush update` afterwards.
|
||||
*
|
||||
* This feature protects against accidental inconsistencies that may be introduced
|
||||
* if the PNPM shrinkwrap file (`pnpm-lock.yaml`) is manually edited. When this
|
||||
* feature is enabled, `rush update` will append a hash to the file as a YAML comment,
|
||||
* and then `rush update` and `rush install` will validate the hash. Note that this
|
||||
* does not prohibit manual modifications, but merely requires `rush update` be run
|
||||
* afterwards, ensuring that PNPM can report or repair any potential inconsistencies.
|
||||
*
|
||||
* To temporarily disable this validation when invoking `rush install`, use the
|
||||
* `--bypass-policy` command-line parameter.
|
||||
*
|
||||
* The default value is false.
|
||||
*/
|
||||
// "preventManualShrinkwrapChanges": true,
|
||||
|
||||
/**
|
||||
* When a project uses `workspace:` to depend on another Rush project, PNPM normally installs
|
||||
* it by creating a symlink under `node_modules`. This generally works well, but in certain
|
||||
* cases such as differing `peerDependencies` versions, symlinking may cause trouble
|
||||
* such as incorrectly satisfied versions. For such cases, the dependency can be declared
|
||||
* as "injected", causing PNPM to copy its built output into `node_modules` like a real
|
||||
* install from a registry. Details here: https://rushjs.io/pages/advanced/injected_deps/
|
||||
*
|
||||
* When using Rush subspaces, these sorts of versioning problems are much more likely if
|
||||
* `workspace:` refers to a project from a different subspace. This is because the symlink
|
||||
* would point to a separate `node_modules` tree installed by a different PNPM lockfile.
|
||||
* A comprehensive solution is to enable `alwaysInjectDependenciesFromOtherSubspaces`,
|
||||
* which automatically treats all projects from other subspaces as injected dependencies
|
||||
* without having to manually configure them.
|
||||
*
|
||||
* NOTE: Use carefully -- excessive file copying can slow down the `rush install` and
|
||||
* `pnpm-sync` operations if too many dependencies become injected.
|
||||
*
|
||||
* The default value is false.
|
||||
*/
|
||||
// "alwaysInjectDependenciesFromOtherSubspaces": false,
|
||||
|
||||
/**
|
||||
* Defines the policies to be checked for the `pnpm-lock.yaml` file.
|
||||
*/
|
||||
"pnpmLockfilePolicies": {
|
||||
|
||||
/**
|
||||
* This policy will cause "rush update" to report an error if `pnpm-lock.yaml` contains
|
||||
* any SHA1 integrity hashes.
|
||||
*
|
||||
* For each NPM dependency, `pnpm-lock.yaml` normally stores an `integrity` hash. Although
|
||||
* its main purpose is to detect corrupted or truncated network requests, this hash can also
|
||||
* serve as a security fingerprint to protect against attacks that would substitute a
|
||||
* malicious tarball, for example if a misconfigured .npmrc caused a machine to accidentally
|
||||
* download a matching package name+version from npmjs.com instead of the private NPM registry.
|
||||
* NPM originally used a SHA1 hash; this was insecure because an attacker can too easily craft
|
||||
* a tarball with a matching fingerprint. For this reason, NPM later deprecated SHA1 and
|
||||
* instead adopted a cryptographically strong SHA512 hash. Nonetheless, SHA1 hashes can
|
||||
* occasionally reappear during "rush update", for example due to missing metadata fallbacks
|
||||
* (https://github.com/orgs/pnpm/discussions/6194) or an incompletely migrated private registry.
|
||||
* The `disallowInsecureSha1` policy prevents this, avoiding potential security/compliance alerts.
|
||||
*/
|
||||
// "disallowInsecureSha1": {
|
||||
// /**
|
||||
// * Enables the "disallowInsecureSha1" policy. The default value is false.
|
||||
// */
|
||||
// "enabled": true,
|
||||
//
|
||||
// /**
|
||||
// * In rare cases, a private NPM registry may continue to serve SHA1 hashes for very old
|
||||
// * package versions, perhaps due to a caching issue or database migration glitch. To avoid
|
||||
// * having to disable the "disallowInsecureSha1" policy for the entire monorepo, the problematic
|
||||
// * package versions can be individually ignored. The "exemptPackageVersions" key is the
|
||||
// * package name, and the array value lists exact version numbers to be ignored.
|
||||
// */
|
||||
// "exemptPackageVersions": {
|
||||
// "example1": ["1.0.0"],
|
||||
// "example2": ["2.0.0", "2.0.1"]
|
||||
// }
|
||||
// }
|
||||
},
|
||||
|
||||
/**
|
||||
* The "globalOverrides" setting provides a simple mechanism for overriding version selections
|
||||
* for all dependencies of all projects in the monorepo workspace. The settings are copied
|
||||
* into the `pnpm.overrides` field of the `common/temp/package.json` file that is generated
|
||||
* by Rush during installation.
|
||||
*
|
||||
* Order of precedence: `.pnpmfile.cjs` has the highest precedence, followed by
|
||||
* `unsupportedPackageJsonSettings`, `globalPeerDependencyRules`, `globalPackageExtensions`,
|
||||
* and `globalOverrides` has lowest precedence.
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/package_json#pnpmoverrides
|
||||
*/
|
||||
"globalOverrides": {
|
||||
// "example1": "^1.0.0",
|
||||
// "example2": "npm:@company/example2@^1.0.0"
|
||||
},
|
||||
|
||||
/**
|
||||
* The `globalPeerDependencyRules` setting provides various settings for suppressing validation errors
|
||||
* that are reported during installation with `strictPeerDependencies=true`. The settings are copied
|
||||
* into the `pnpm.peerDependencyRules` field of the `common/temp/package.json` file that is generated
|
||||
* by Rush during installation.
|
||||
*
|
||||
* Order of precedence: `.pnpmfile.cjs` has the highest precedence, followed by
|
||||
* `unsupportedPackageJsonSettings`, `globalPeerDependencyRules`, `globalPackageExtensions`,
|
||||
* and `globalOverrides` has lowest precedence.
|
||||
*
|
||||
* https://pnpm.io/package_json#pnpmpeerdependencyrules
|
||||
*/
|
||||
"globalPeerDependencyRules": {
|
||||
// "ignoreMissing": ["@eslint/*"],
|
||||
// "allowedVersions": { "react": "17" },
|
||||
// "allowAny": ["@babel/*"]
|
||||
},
|
||||
|
||||
/**
|
||||
* The `globalPackageExtension` setting provides a way to patch arbitrary package.json fields
|
||||
* for any PNPM dependency of the monorepo. The settings are copied into the `pnpm.packageExtensions`
|
||||
* field of the `common/temp/package.json` file that is generated by Rush during installation.
|
||||
* The `globalPackageExtension` setting has similar capabilities as `.pnpmfile.cjs` but without
|
||||
* the downsides of an executable script (nondeterminism, unreliable caching, performance concerns).
|
||||
*
|
||||
* Order of precedence: `.pnpmfile.cjs` has the highest precedence, followed by
|
||||
* `unsupportedPackageJsonSettings`, `globalPeerDependencyRules`, `globalPackageExtensions`,
|
||||
* and `globalOverrides` has lowest precedence.
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/package_json#pnpmpackageextensions
|
||||
*/
|
||||
"globalPackageExtensions": {
|
||||
// "fork-ts-checker-webpack-plugin": {
|
||||
// "dependencies": {
|
||||
// "@babel/core": "1"
|
||||
// },
|
||||
// "peerDependencies": {
|
||||
// "eslint": ">= 6"
|
||||
// },
|
||||
// "peerDependenciesMeta": {
|
||||
// "eslint": {
|
||||
// "optional": true
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
},
|
||||
|
||||
/**
|
||||
* The `globalNeverBuiltDependencies` setting suppresses the `preinstall`, `install`, and `postinstall`
|
||||
* lifecycle events for the specified NPM dependencies. This is useful for scripts with poor practices
|
||||
* such as downloading large binaries without retries or attempting to invoke OS tools such as
|
||||
* a C++ compiler. (PNPM's terminology refers to these lifecycle events as "building" a package;
|
||||
* it has nothing to do with build system operations such as `rush build` or `rushx build`.)
|
||||
* The settings are copied into the `pnpm.neverBuiltDependencies` field of the `common/temp/package.json`
|
||||
* file that is generated by Rush during installation.
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/package_json#pnpmneverbuiltdependencies
|
||||
*/
|
||||
"globalNeverBuiltDependencies": [
|
||||
// "fsevents"
|
||||
],
|
||||
|
||||
/**
|
||||
* The `globalIgnoredOptionalDependencies` setting suppresses the installation of optional NPM
|
||||
* dependencies specified in the list. This is useful when certain optional dependencies are
|
||||
* not needed in your environment, such as platform-specific packages or dependencies that
|
||||
* fail during installation but are not critical to your project.
|
||||
* These settings are copied into the `pnpm.overrides` field of the `common/temp/package.json`
|
||||
* file that is generated by Rush during installation, instructing PNPM to ignore the specified
|
||||
* optional dependencies.
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/package_json#pnpmignoredoptionaldependencies
|
||||
*/
|
||||
"globalIgnoredOptionalDependencies": [
|
||||
// "fsevents"
|
||||
],
|
||||
|
||||
/**
|
||||
* The `globalAllowedDeprecatedVersions` setting suppresses installation warnings for package
|
||||
* versions that the NPM registry reports as being deprecated. This is useful if the
|
||||
* deprecated package is an indirect dependency of an external package that has not released a fix.
|
||||
* The settings are copied into the `pnpm.allowedDeprecatedVersions` field of the `common/temp/package.json`
|
||||
* file that is generated by Rush during installation.
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/package_json#pnpmalloweddeprecatedversions
|
||||
*
|
||||
* If you are working to eliminate a deprecated version, it's better to specify `allowedDeprecatedVersions`
|
||||
* in the package.json file for individual Rush projects.
|
||||
*/
|
||||
"globalAllowedDeprecatedVersions": {
|
||||
// "request": "*"
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* (THIS FIELD IS MACHINE GENERATED) The "globalPatchedDependencies" field is updated automatically
|
||||
* by the `rush-pnpm patch-commit` command. It is a dictionary, where the key is an NPM package name
|
||||
* and exact version, and the value is a relative path to the associated patch file.
|
||||
*
|
||||
* PNPM documentation: https://pnpm.io/package_json#pnpmpatcheddependencies
|
||||
*/
|
||||
"globalPatchedDependencies": { },
|
||||
|
||||
/**
|
||||
* (USE AT YOUR OWN RISK) This is a free-form property bag that will be copied into
|
||||
* the `common/temp/package.json` file that is generated by Rush during installation.
|
||||
* This provides a way to experiment with new PNPM features. These settings will override
|
||||
* any other Rush configuration associated with a given JSON field except for `.pnpmfile.cjs`.
|
||||
*
|
||||
* USAGE OF THIS SETTING IS NOT SUPPORTED BY THE RUSH MAINTAINERS AND MAY CAUSE RUSH
|
||||
* TO MALFUNCTION. If you encounter a missing PNPM setting that you believe should
|
||||
* be supported, please create a GitHub issue or PR. Note that Rush does not aim to
|
||||
* support every possible PNPM setting, but rather to promote a battle-tested installation
|
||||
* strategy that is known to provide a good experience for large teams with lots of projects.
|
||||
*/
|
||||
"unsupportedPackageJsonSettings": {
|
||||
// "dependencies": {
|
||||
// "not-a-good-practice": "*"
|
||||
// },
|
||||
// "scripts": {
|
||||
// "do-something": "echo Also not a good practice"
|
||||
// },
|
||||
// "pnpm": { "futurePnpmFeature": true }
|
||||
}
|
||||
}
|
||||
Generated
+5866
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
// DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush.
|
||||
{
|
||||
"preferredVersionsHash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* This configuration file manages Rush's plugin feature.
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugins.schema.json",
|
||||
"plugins": [
|
||||
/**
|
||||
* Each item configures a plugin to be loaded by Rush.
|
||||
*/
|
||||
// {
|
||||
// /**
|
||||
// * The name of the NPM package that provides the plugin.
|
||||
// */
|
||||
// "packageName": "@scope/my-rush-plugin",
|
||||
// /**
|
||||
// * The name of the plugin. This can be found in the "pluginName"
|
||||
// * field of the "rush-plugin-manifest.json" file in the NPM package folder.
|
||||
// */
|
||||
// "pluginName": "my-plugin-name",
|
||||
// /**
|
||||
// * The name of a Rush autoinstaller that will be used for installation, which
|
||||
// * can be created using "rush init-autoinstaller". Add the plugin's NPM package
|
||||
// * to the package.json "dependencies" of your autoinstaller, then run
|
||||
// * "rush update-autoinstaller".
|
||||
// */
|
||||
// "autoinstallerName": "rush-plugins"
|
||||
// }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* This configuration file manages the experimental "subspaces" feature for Rush,
|
||||
* which allows multiple PNPM lockfiles to be used in a single Rush workspace.
|
||||
* For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/subspaces.schema.json",
|
||||
|
||||
/**
|
||||
* Set this flag to "true" to enable usage of subspaces.
|
||||
*/
|
||||
"subspacesEnabled": false,
|
||||
|
||||
/**
|
||||
* (DEPRECATED) This is a temporary workaround for migrating from an earlier prototype
|
||||
* of this feature: https://github.com/microsoft/rushstack/pull/3481
|
||||
* It allows subspaces with only one project to store their config files in the project folder.
|
||||
*/
|
||||
"splitWorkspaceCompatibility": false,
|
||||
|
||||
/**
|
||||
* When a command such as "rush update" is invoked without the "--subspace" or "--to"
|
||||
* parameters, Rush will install all subspaces. In a huge monorepo with numerous subspaces,
|
||||
* this would be extremely slow. Set "preventSelectingAllSubspaces" to true to avoid this
|
||||
* mistake by always requiring selection parameters for commands such as "rush update".
|
||||
*/
|
||||
"preventSelectingAllSubspaces": false,
|
||||
|
||||
/**
|
||||
* The list of subspace names, which should be lowercase alphanumeric words separated by
|
||||
* hyphens, for example "my-subspace". The corresponding config files will have paths
|
||||
* such as "common/config/subspaces/my-subspace/package-lock.yaml".
|
||||
*/
|
||||
"subspaceNames": []
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* This is configuration file is used for advanced publishing configurations with Rush.
|
||||
* More documentation is available on the Rush website: https://rushjs.io
|
||||
*/
|
||||
|
||||
/**
|
||||
* A list of version policy definitions. A "version policy" is a custom package versioning
|
||||
* strategy that affects "rush change", "rush version", and "rush publish". The strategy applies
|
||||
* to a set of projects that are specified using the "versionPolicyName" field in rush.json.
|
||||
*/
|
||||
[
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Indicates the kind of version policy being defined ("lockStepVersion" or "individualVersion").
|
||||
// *
|
||||
// * The "lockStepVersion" mode specifies that the projects will use "lock-step versioning". This
|
||||
// * strategy is appropriate for a set of packages that act as selectable components of a
|
||||
// * unified product. The entire set of packages are always published together, and always share
|
||||
// * the same NPM version number. When the packages depend on other packages in the set, the
|
||||
// * SemVer range is usually restricted to a single version.
|
||||
// */
|
||||
// "definitionName": "lockStepVersion",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The name that will be used for the "versionPolicyName" field in rush.json.
|
||||
// * This name is also used command-line parameters such as "--version-policy"
|
||||
// * and "--to-version-policy".
|
||||
// */
|
||||
// "policyName": "MyBigFramework",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The current version. All packages belonging to the set should have this version
|
||||
// * in the current branch. When bumping versions, Rush uses this to determine the next version.
|
||||
// * (The "version" field in package.json is NOT considered.)
|
||||
// */
|
||||
// "version": "1.0.0",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The type of bump that will be performed when publishing the next release.
|
||||
// * When creating a release branch in Git, this field should be updated according to the
|
||||
// * type of release.
|
||||
// *
|
||||
// * Valid values are: "prerelease", "preminor", "minor", "patch", "major"
|
||||
// */
|
||||
// "nextBump": "prerelease",
|
||||
//
|
||||
// /**
|
||||
// * (Optional) If specified, all packages in the set share a common CHANGELOG.md file.
|
||||
// * This file is stored with the specified "main" project, which must be a member of the set.
|
||||
// *
|
||||
// * If this field is omitted, then a separate CHANGELOG.md file will be maintained for each
|
||||
// * package in the set.
|
||||
// */
|
||||
// "mainProject": "my-app",
|
||||
//
|
||||
// /**
|
||||
// * (Optional) If enabled, the "rush change" command will prompt the user for their email address
|
||||
// * and include it in the JSON change files. If an organization maintains multiple repos, tracking
|
||||
// * this contact information may be useful for a service that automatically upgrades packages and
|
||||
// * needs to notify engineers whose change may be responsible for a downstream build break. It might
|
||||
// * also be useful for crediting contributors. Rush itself does not do anything with the collected
|
||||
// * email addresses. The default value is "false".
|
||||
// */
|
||||
// // "includeEmailInChangeFile": true
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Indicates the kind of version policy being defined ("lockStepVersion" or "individualVersion").
|
||||
// *
|
||||
// * The "individualVersion" mode specifies that the projects will use "individual versioning".
|
||||
// * This is the typical NPM model where each package has an independent version number
|
||||
// * and CHANGELOG.md file. Although a single CI definition is responsible for publishing the
|
||||
// * packages, they otherwise don't have any special relationship. The version bumping will
|
||||
// * depend on how developers answer the "rush change" questions for each package that
|
||||
// * is changed.
|
||||
// */
|
||||
// "definitionName": "individualVersion",
|
||||
//
|
||||
// "policyName": "MyRandomLibraries",
|
||||
//
|
||||
// /**
|
||||
// * (Optional) This can be used to enforce that all packages in the set must share a common
|
||||
// * major version number, e.g. because they are from the same major release branch.
|
||||
// * It can also be used to discourage people from accidentally making "MAJOR" SemVer changes
|
||||
// * inappropriately. The minor/patch version parts will be bumped independently according
|
||||
// * to the types of changes made to each project, according to the "rush change" command.
|
||||
// */
|
||||
// "lockedMajor": 3,
|
||||
//
|
||||
// /**
|
||||
// * (Optional) When publishing is managed by Rush, by default the "rush change" command will
|
||||
// * request changes for any projects that are modified by a pull request. These change entries
|
||||
// * will produce a CHANGELOG.md file. If you author your CHANGELOG.md manually or announce updates
|
||||
// * in some other way, set "exemptFromRushChange" to true to tell "rush change" to ignore the projects
|
||||
// * belonging to this version policy.
|
||||
// */
|
||||
// "exemptFromRushChange": false,
|
||||
//
|
||||
// // "includeEmailInChangeFile": true
|
||||
// }
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This is an example Git hook for use with Rush. To enable this hook, rename this file
|
||||
# to "commit-msg" and then run "rush install", which will copy it from common/git-hooks
|
||||
# to the .git/hooks folder.
|
||||
#
|
||||
# TO LEARN MORE ABOUT GIT HOOKS
|
||||
#
|
||||
# The Git documentation is here: https://git-scm.com/docs/githooks
|
||||
# Some helpful resources: https://githooks.com
|
||||
#
|
||||
# ABOUT THIS EXAMPLE
|
||||
#
|
||||
# The commit-msg hook is called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero status after issuing
|
||||
# an appropriate message if it wants to stop the commit. The hook is allowed to edit
|
||||
# the commit message file.
|
||||
|
||||
# This example enforces that commit message should contain a minimum amount of
|
||||
# description text.
|
||||
if [ `cat $1 | wc -w` -lt 3 ]; then
|
||||
echo ""
|
||||
echo "Invalid commit message: The message must contain at least 3 words."
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,31 @@
|
||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
||||
//
|
||||
// This script is intended for usage in an automated build environment where the Rush command may not have
|
||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
|
||||
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to the
|
||||
// rush-pnpm command.
|
||||
//
|
||||
// An example usage would be:
|
||||
//
|
||||
// node common/scripts/install-run-rush-pnpm.js pnpm-command
|
||||
//
|
||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See the @microsoft/rush package's LICENSE file for details.
|
||||
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
var __webpack_exports__ = {};
|
||||
/*!*****************************************************!*\
|
||||
!*** ./lib-esnext/scripts/install-run-rush-pnpm.js ***!
|
||||
\*****************************************************/
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
require('./install-run-rush');
|
||||
//# sourceMappingURL=install-run-rush-pnpm.js.map
|
||||
module.exports = __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
||||
//# sourceMappingURL=install-run-rush-pnpm.js.map
|
||||
@@ -0,0 +1,218 @@
|
||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
||||
//
|
||||
// This script is intended for usage in an automated build environment where the Rush command may not have
|
||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
|
||||
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to it.
|
||||
// An example usage would be:
|
||||
//
|
||||
// node common/scripts/install-run-rush.js install
|
||||
//
|
||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See the @microsoft/rush package's LICENSE file for details.
|
||||
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ 16928:
|
||||
/*!***********************!*\
|
||||
!*** external "path" ***!
|
||||
\***********************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("path");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 179896:
|
||||
/*!*********************!*\
|
||||
!*** external "fs" ***!
|
||||
\*********************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("fs");
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/compat get default export */
|
||||
/******/ (() => {
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = (module) => {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ () => (module['default']) :
|
||||
/******/ () => (module);
|
||||
/******/ __webpack_require__.d(getter, { a: getter });
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/define property getters */
|
||||
/******/ (() => {
|
||||
/******/ // define getter functions for harmony exports
|
||||
/******/ __webpack_require__.d = (exports, definition) => {
|
||||
/******/ for(var key in definition) {
|
||||
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
var __webpack_exports__ = {};
|
||||
// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
|
||||
(() => {
|
||||
/*!************************************************!*\
|
||||
!*** ./lib-esnext/scripts/install-run-rush.js ***!
|
||||
\************************************************/
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! path */ 16928);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 179896);
|
||||
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__);
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
/* eslint-disable no-console */
|
||||
|
||||
|
||||
const { installAndRun, findRushJsonFolder, RUSH_JSON_FILENAME, runWithErrorAndStatusCode } = require('./install-run');
|
||||
const PACKAGE_NAME = '@microsoft/rush';
|
||||
const RUSH_PREVIEW_VERSION = 'RUSH_PREVIEW_VERSION';
|
||||
const INSTALL_RUN_RUSH_LOCKFILE_PATH_VARIABLE = 'INSTALL_RUN_RUSH_LOCKFILE_PATH';
|
||||
function _getRushVersion(logger) {
|
||||
const rushPreviewVersion = process.env[RUSH_PREVIEW_VERSION];
|
||||
if (rushPreviewVersion !== undefined) {
|
||||
logger.info(`Using Rush version from environment variable ${RUSH_PREVIEW_VERSION}=${rushPreviewVersion}`);
|
||||
return rushPreviewVersion;
|
||||
}
|
||||
const rushJsonFolder = findRushJsonFolder();
|
||||
const rushJsonPath = path__WEBPACK_IMPORTED_MODULE_0__.join(rushJsonFolder, RUSH_JSON_FILENAME);
|
||||
try {
|
||||
const rushJsonContents = fs__WEBPACK_IMPORTED_MODULE_1__.readFileSync(rushJsonPath, 'utf-8');
|
||||
// Use a regular expression to parse out the rushVersion value because rush.json supports comments,
|
||||
// but JSON.parse does not and we don't want to pull in more dependencies than we need to in this script.
|
||||
const rushJsonMatches = rushJsonContents.match(/\"rushVersion\"\s*\:\s*\"([0-9a-zA-Z.+\-]+)\"/);
|
||||
return rushJsonMatches[1];
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to determine the required version of Rush from ${RUSH_JSON_FILENAME} (${rushJsonFolder}). ` +
|
||||
`The 'rushVersion' field is either not assigned in ${RUSH_JSON_FILENAME} or was specified ` +
|
||||
'using an unexpected syntax.');
|
||||
}
|
||||
}
|
||||
function _getBin(scriptName) {
|
||||
switch (scriptName.toLowerCase()) {
|
||||
case 'install-run-rush-pnpm.js':
|
||||
return 'rush-pnpm';
|
||||
case 'install-run-rushx.js':
|
||||
return 'rushx';
|
||||
default:
|
||||
return 'rush';
|
||||
}
|
||||
}
|
||||
function _run() {
|
||||
const [nodePath /* Ex: /bin/node */, scriptPath /* /repo/common/scripts/install-run-rush.js */, ...packageBinArgs /* [build, --to, myproject] */] = process.argv;
|
||||
// Detect if this script was directly invoked, or if the install-run-rushx script was invokved to select the
|
||||
// appropriate binary inside the rush package to run
|
||||
const scriptName = path__WEBPACK_IMPORTED_MODULE_0__.basename(scriptPath);
|
||||
const bin = _getBin(scriptName);
|
||||
if (!nodePath || !scriptPath) {
|
||||
throw new Error('Unexpected exception: could not detect node path or script path');
|
||||
}
|
||||
let commandFound = false;
|
||||
let logger = { info: console.log, error: console.error };
|
||||
for (const arg of packageBinArgs) {
|
||||
if (arg === '-q' || arg === '--quiet') {
|
||||
// The -q/--quiet flag is supported by both `rush` and `rushx`, and will suppress
|
||||
// any normal informational/diagnostic information printed during startup.
|
||||
//
|
||||
// To maintain the same user experience, the install-run* scripts pass along this
|
||||
// flag but also use it to suppress any diagnostic information normally printed
|
||||
// to stdout.
|
||||
logger = {
|
||||
info: () => { },
|
||||
error: console.error
|
||||
};
|
||||
}
|
||||
else if (!arg.startsWith('-') || arg === '-h' || arg === '--help') {
|
||||
// We either found something that looks like a command (i.e. - doesn't start with a "-"),
|
||||
// or we found the -h/--help flag, which can be run without a command
|
||||
commandFound = true;
|
||||
}
|
||||
}
|
||||
if (!commandFound) {
|
||||
console.log(`Usage: ${scriptName} <command> [args...]`);
|
||||
if (scriptName === 'install-run-rush-pnpm.js') {
|
||||
console.log(`Example: ${scriptName} pnpm-command`);
|
||||
}
|
||||
else if (scriptName === 'install-run-rush.js') {
|
||||
console.log(`Example: ${scriptName} build --to myproject`);
|
||||
}
|
||||
else {
|
||||
console.log(`Example: ${scriptName} custom-command`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
runWithErrorAndStatusCode(logger, () => {
|
||||
const version = _getRushVersion(logger);
|
||||
logger.info(`The ${RUSH_JSON_FILENAME} configuration requests Rush version ${version}`);
|
||||
const lockFilePath = process.env[INSTALL_RUN_RUSH_LOCKFILE_PATH_VARIABLE];
|
||||
if (lockFilePath) {
|
||||
logger.info(`Found ${INSTALL_RUN_RUSH_LOCKFILE_PATH_VARIABLE}="${lockFilePath}", installing with lockfile.`);
|
||||
}
|
||||
return installAndRun(logger, PACKAGE_NAME, version, bin, packageBinArgs, lockFilePath);
|
||||
});
|
||||
}
|
||||
_run();
|
||||
//# sourceMappingURL=install-run-rush.js.map
|
||||
})();
|
||||
|
||||
module.exports = __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
||||
//# sourceMappingURL=install-run-rush.js.map
|
||||
@@ -0,0 +1,31 @@
|
||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
||||
//
|
||||
// This script is intended for usage in an automated build environment where the Rush command may not have
|
||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
|
||||
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to the
|
||||
// rushx command.
|
||||
//
|
||||
// An example usage would be:
|
||||
//
|
||||
// node common/scripts/install-run-rushx.js custom-command
|
||||
//
|
||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See the @microsoft/rush package's LICENSE file for details.
|
||||
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
var __webpack_exports__ = {};
|
||||
/*!*************************************************!*\
|
||||
!*** ./lib-esnext/scripts/install-run-rushx.js ***!
|
||||
\*************************************************/
|
||||
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
require('./install-run-rush');
|
||||
//# sourceMappingURL=install-run-rushx.js.map
|
||||
module.exports = __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
||||
//# sourceMappingURL=install-run-rushx.js.map
|
||||
@@ -0,0 +1,778 @@
|
||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
||||
//
|
||||
// This script is intended for usage in an automated build environment where a Node tool may not have
|
||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the specified
|
||||
// version of the specified tool (if not already installed), and then pass a command-line to it.
|
||||
// An example usage would be:
|
||||
//
|
||||
// node common/scripts/install-run.js qrcode@1.2.2 qrcode https://rushjs.io
|
||||
//
|
||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See the @microsoft/rush package's LICENSE file for details.
|
||||
|
||||
/******/ (() => { // webpackBootstrap
|
||||
/******/ "use strict";
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ 16928:
|
||||
/*!***********************!*\
|
||||
!*** external "path" ***!
|
||||
\***********************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("path");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 179896:
|
||||
/*!*********************!*\
|
||||
!*** external "fs" ***!
|
||||
\*********************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("fs");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 370857:
|
||||
/*!*********************!*\
|
||||
!*** external "os" ***!
|
||||
\*********************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("os");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 535317:
|
||||
/*!********************************!*\
|
||||
!*** external "child_process" ***!
|
||||
\********************************/
|
||||
/***/ ((module) => {
|
||||
|
||||
module.exports = require("child_process");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 832286:
|
||||
/*!************************************************!*\
|
||||
!*** ./lib-esnext/utilities/npmrcUtilities.js ***!
|
||||
\************************************************/
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ isVariableSetInNpmrcFile: () => (/* binding */ isVariableSetInNpmrcFile),
|
||||
/* harmony export */ syncNpmrc: () => (/* binding */ syncNpmrc),
|
||||
/* harmony export */ trimNpmrcFileLines: () => (/* binding */ trimNpmrcFileLines)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! fs */ 179896);
|
||||
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! path */ 16928);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_1__);
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
// IMPORTANT - do not use any non-built-in libraries in this file
|
||||
|
||||
|
||||
/**
|
||||
* This function reads the content for given .npmrc file path, and also trims
|
||||
* unusable lines from the .npmrc file.
|
||||
*
|
||||
* @returns
|
||||
* The text of the the .npmrc.
|
||||
*/
|
||||
// create a global _combinedNpmrc for cache purpose
|
||||
const _combinedNpmrcMap = new Map();
|
||||
function _trimNpmrcFile(options) {
|
||||
const { sourceNpmrcPath, linesToPrepend, linesToAppend, supportEnvVarFallbackSyntax } = options;
|
||||
const combinedNpmrcFromCache = _combinedNpmrcMap.get(sourceNpmrcPath);
|
||||
if (combinedNpmrcFromCache !== undefined) {
|
||||
return combinedNpmrcFromCache;
|
||||
}
|
||||
let npmrcFileLines = [];
|
||||
if (linesToPrepend) {
|
||||
npmrcFileLines.push(...linesToPrepend);
|
||||
}
|
||||
if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) {
|
||||
npmrcFileLines.push(...fs__WEBPACK_IMPORTED_MODULE_0__.readFileSync(sourceNpmrcPath).toString().split('\n'));
|
||||
}
|
||||
if (linesToAppend) {
|
||||
npmrcFileLines.push(...linesToAppend);
|
||||
}
|
||||
npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim());
|
||||
const resultLines = trimNpmrcFileLines(npmrcFileLines, process.env, supportEnvVarFallbackSyntax);
|
||||
const combinedNpmrc = resultLines.join('\n');
|
||||
//save the cache
|
||||
_combinedNpmrcMap.set(sourceNpmrcPath, combinedNpmrc);
|
||||
return combinedNpmrc;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param npmrcFileLines The npmrc file's lines
|
||||
* @param env The environment variables object
|
||||
* @param supportEnvVarFallbackSyntax Whether to support fallback values in the form of `${VAR_NAME:-fallback}`
|
||||
* @returns
|
||||
*/
|
||||
function trimNpmrcFileLines(npmrcFileLines, env, supportEnvVarFallbackSyntax) {
|
||||
var _a;
|
||||
const resultLines = [];
|
||||
// This finds environment variable tokens that look like "${VAR_NAME}"
|
||||
const expansionRegExp = /\$\{([^\}]+)\}/g;
|
||||
// Comment lines start with "#" or ";"
|
||||
const commentRegExp = /^\s*[#;]/;
|
||||
// Trim out lines that reference environment variables that aren't defined
|
||||
for (let line of npmrcFileLines) {
|
||||
let lineShouldBeTrimmed = false;
|
||||
//remove spaces before or after key and value
|
||||
line = line
|
||||
.split('=')
|
||||
.map((lineToTrim) => lineToTrim.trim())
|
||||
.join('=');
|
||||
// Ignore comment lines
|
||||
if (!commentRegExp.test(line)) {
|
||||
const environmentVariables = line.match(expansionRegExp);
|
||||
if (environmentVariables) {
|
||||
for (const token of environmentVariables) {
|
||||
/**
|
||||
* Remove the leading "${" and the trailing "}" from the token
|
||||
*
|
||||
* ${nameString} -> nameString
|
||||
* ${nameString-fallbackString} -> name-fallbackString
|
||||
* ${nameString:-fallbackString} -> name:-fallbackString
|
||||
*/
|
||||
const nameWithFallback = token.substring(2, token.length - 1);
|
||||
let environmentVariableName;
|
||||
let fallback;
|
||||
if (supportEnvVarFallbackSyntax) {
|
||||
/**
|
||||
* Get the environment variable name and fallback value.
|
||||
*
|
||||
* name fallback
|
||||
* nameString -> nameString undefined
|
||||
* nameString-fallbackString -> nameString fallbackString
|
||||
* nameString:-fallbackString -> nameString fallbackString
|
||||
*/
|
||||
const matched = nameWithFallback.match(/^([^:-]+)(?:\:?-(.+))?$/);
|
||||
// matched: [originStr, variableName, fallback]
|
||||
environmentVariableName = (_a = matched === null || matched === void 0 ? void 0 : matched[1]) !== null && _a !== void 0 ? _a : nameWithFallback;
|
||||
fallback = matched === null || matched === void 0 ? void 0 : matched[2];
|
||||
}
|
||||
else {
|
||||
environmentVariableName = nameWithFallback;
|
||||
}
|
||||
// Is the environment variable and fallback value defined.
|
||||
if (!env[environmentVariableName] && !fallback) {
|
||||
// No, so trim this line
|
||||
lineShouldBeTrimmed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lineShouldBeTrimmed) {
|
||||
// Example output:
|
||||
// "; MISSING ENVIRONMENT VARIABLE: //my-registry.com/npm/:_authToken=${MY_AUTH_TOKEN}"
|
||||
resultLines.push('; MISSING ENVIRONMENT VARIABLE: ' + line);
|
||||
}
|
||||
else {
|
||||
resultLines.push(line);
|
||||
}
|
||||
}
|
||||
return resultLines;
|
||||
}
|
||||
function _copyAndTrimNpmrcFile(options) {
|
||||
const { logger, sourceNpmrcPath, targetNpmrcPath } = options;
|
||||
logger.info(`Transforming ${sourceNpmrcPath}`); // Verbose
|
||||
logger.info(` --> "${targetNpmrcPath}"`);
|
||||
const combinedNpmrc = _trimNpmrcFile(options);
|
||||
fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync(targetNpmrcPath, combinedNpmrc);
|
||||
return combinedNpmrc;
|
||||
}
|
||||
function syncNpmrc(options) {
|
||||
const { sourceNpmrcFolder, targetNpmrcFolder, useNpmrcPublish, logger = {
|
||||
// eslint-disable-next-line no-console
|
||||
info: console.log,
|
||||
// eslint-disable-next-line no-console
|
||||
error: console.error
|
||||
}, createIfMissing = false } = options;
|
||||
const sourceNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(sourceNpmrcFolder, !useNpmrcPublish ? '.npmrc' : '.npmrc-publish');
|
||||
const targetNpmrcPath = path__WEBPACK_IMPORTED_MODULE_1__.join(targetNpmrcFolder, '.npmrc');
|
||||
try {
|
||||
if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath) || createIfMissing) {
|
||||
// Ensure the target folder exists
|
||||
if (!fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcFolder)) {
|
||||
fs__WEBPACK_IMPORTED_MODULE_0__.mkdirSync(targetNpmrcFolder, { recursive: true });
|
||||
}
|
||||
return _copyAndTrimNpmrcFile({
|
||||
sourceNpmrcPath,
|
||||
targetNpmrcPath,
|
||||
logger,
|
||||
...options
|
||||
});
|
||||
}
|
||||
else if (fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(targetNpmrcPath)) {
|
||||
// If the source .npmrc doesn't exist and there is one in the target, delete the one in the target
|
||||
logger.info(`Deleting ${targetNpmrcPath}`); // Verbose
|
||||
fs__WEBPACK_IMPORTED_MODULE_0__.unlinkSync(targetNpmrcPath);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error syncing .npmrc file: ${e}`);
|
||||
}
|
||||
}
|
||||
function isVariableSetInNpmrcFile(sourceNpmrcFolder, variableKey, supportEnvVarFallbackSyntax) {
|
||||
const sourceNpmrcPath = `${sourceNpmrcFolder}/.npmrc`;
|
||||
//if .npmrc file does not exist, return false directly
|
||||
if (!fs__WEBPACK_IMPORTED_MODULE_0__.existsSync(sourceNpmrcPath)) {
|
||||
return false;
|
||||
}
|
||||
const trimmedNpmrcFile = _trimNpmrcFile({ sourceNpmrcPath, supportEnvVarFallbackSyntax });
|
||||
const variableKeyRegExp = new RegExp(`^${variableKey}=`, 'm');
|
||||
return trimmedNpmrcFile.match(variableKeyRegExp) !== null;
|
||||
}
|
||||
//# sourceMappingURL=npmrcUtilities.js.map
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/compat get default export */
|
||||
/******/ (() => {
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = (module) => {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ () => (module['default']) :
|
||||
/******/ () => (module);
|
||||
/******/ __webpack_require__.d(getter, { a: getter });
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/define property getters */
|
||||
/******/ (() => {
|
||||
/******/ // define getter functions for harmony exports
|
||||
/******/ __webpack_require__.d = (exports, definition) => {
|
||||
/******/ for(var key in definition) {
|
||||
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
var __webpack_exports__ = {};
|
||||
// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
|
||||
(() => {
|
||||
/*!*******************************************!*\
|
||||
!*** ./lib-esnext/scripts/install-run.js ***!
|
||||
\*******************************************/
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ RUSH_JSON_FILENAME: () => (/* binding */ RUSH_JSON_FILENAME),
|
||||
/* harmony export */ findRushJsonFolder: () => (/* binding */ findRushJsonFolder),
|
||||
/* harmony export */ getNpmPath: () => (/* binding */ getNpmPath),
|
||||
/* harmony export */ installAndRun: () => (/* binding */ installAndRun),
|
||||
/* harmony export */ runWithErrorAndStatusCode: () => (/* binding */ runWithErrorAndStatusCode)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! child_process */ 535317);
|
||||
/* harmony import */ var child_process__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(child_process__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! fs */ 179896);
|
||||
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! os */ 370857);
|
||||
/* harmony import */ var os__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(os__WEBPACK_IMPORTED_MODULE_2__);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! path */ 16928);
|
||||
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_3__);
|
||||
/* harmony import */ var _utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utilities/npmrcUtilities */ 832286);
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See LICENSE in the project root for license information.
|
||||
/* eslint-disable no-console */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const RUSH_JSON_FILENAME = 'rush.json';
|
||||
const RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME = 'RUSH_TEMP_FOLDER';
|
||||
const INSTALL_RUN_LOCKFILE_PATH_VARIABLE = 'INSTALL_RUN_LOCKFILE_PATH';
|
||||
const INSTALLED_FLAG_FILENAME = 'installed.flag';
|
||||
const NODE_MODULES_FOLDER_NAME = 'node_modules';
|
||||
const PACKAGE_JSON_FILENAME = 'package.json';
|
||||
/**
|
||||
* Parse a package specifier (in the form of name\@version) into name and version parts.
|
||||
*/
|
||||
function _parsePackageSpecifier(rawPackageSpecifier) {
|
||||
rawPackageSpecifier = (rawPackageSpecifier || '').trim();
|
||||
const separatorIndex = rawPackageSpecifier.lastIndexOf('@');
|
||||
let name;
|
||||
let version = undefined;
|
||||
if (separatorIndex === 0) {
|
||||
// The specifier starts with a scope and doesn't have a version specified
|
||||
name = rawPackageSpecifier;
|
||||
}
|
||||
else if (separatorIndex === -1) {
|
||||
// The specifier doesn't have a version
|
||||
name = rawPackageSpecifier;
|
||||
}
|
||||
else {
|
||||
name = rawPackageSpecifier.substring(0, separatorIndex);
|
||||
version = rawPackageSpecifier.substring(separatorIndex + 1);
|
||||
}
|
||||
if (!name) {
|
||||
throw new Error(`Invalid package specifier: ${rawPackageSpecifier}`);
|
||||
}
|
||||
return { name, version };
|
||||
}
|
||||
let _npmPath = undefined;
|
||||
/**
|
||||
* Get the absolute path to the npm executable
|
||||
*/
|
||||
function getNpmPath() {
|
||||
if (!_npmPath) {
|
||||
try {
|
||||
if (_isWindows()) {
|
||||
// We're on Windows
|
||||
const whereOutput = child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('where npm', { stdio: [] }).toString();
|
||||
const lines = whereOutput.split(os__WEBPACK_IMPORTED_MODULE_2__.EOL).filter((line) => !!line);
|
||||
// take the last result, we are looking for a .cmd command
|
||||
// see https://github.com/microsoft/rushstack/issues/759
|
||||
_npmPath = lines[lines.length - 1];
|
||||
}
|
||||
else {
|
||||
// We aren't on Windows - assume we're on *NIX or Darwin
|
||||
_npmPath = child_process__WEBPACK_IMPORTED_MODULE_0__.execSync('command -v npm', { stdio: [] }).toString();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to determine the path to the NPM tool: ${e}`);
|
||||
}
|
||||
_npmPath = _npmPath.trim();
|
||||
if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(_npmPath)) {
|
||||
throw new Error('The NPM executable does not exist');
|
||||
}
|
||||
}
|
||||
return _npmPath;
|
||||
}
|
||||
function _ensureFolder(folderPath) {
|
||||
if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(folderPath)) {
|
||||
const parentDir = path__WEBPACK_IMPORTED_MODULE_3__.dirname(folderPath);
|
||||
_ensureFolder(parentDir);
|
||||
fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(folderPath);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Create missing directories under the specified base directory, and return the resolved directory.
|
||||
*
|
||||
* Does not support "." or ".." path segments.
|
||||
* Assumes the baseFolder exists.
|
||||
*/
|
||||
function _ensureAndJoinPath(baseFolder, ...pathSegments) {
|
||||
let joinedPath = baseFolder;
|
||||
try {
|
||||
for (let pathSegment of pathSegments) {
|
||||
pathSegment = pathSegment.replace(/[\\\/]/g, '+');
|
||||
joinedPath = path__WEBPACK_IMPORTED_MODULE_3__.join(joinedPath, pathSegment);
|
||||
if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(joinedPath)) {
|
||||
fs__WEBPACK_IMPORTED_MODULE_1__.mkdirSync(joinedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error building local installation folder (${path__WEBPACK_IMPORTED_MODULE_3__.join(baseFolder, ...pathSegments)}): ${e}`);
|
||||
}
|
||||
return joinedPath;
|
||||
}
|
||||
function _getRushTempFolder(rushCommonFolder) {
|
||||
const rushTempFolder = process.env[RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME];
|
||||
if (rushTempFolder !== undefined) {
|
||||
_ensureFolder(rushTempFolder);
|
||||
return rushTempFolder;
|
||||
}
|
||||
else {
|
||||
return _ensureAndJoinPath(rushCommonFolder, 'temp');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compare version strings according to semantic versioning.
|
||||
* Returns a positive integer if "a" is a later version than "b",
|
||||
* a negative integer if "b" is later than "a",
|
||||
* and 0 otherwise.
|
||||
*/
|
||||
function _compareVersionStrings(a, b) {
|
||||
const aParts = a.split(/[.-]/);
|
||||
const bParts = b.split(/[.-]/);
|
||||
const numberOfParts = Math.max(aParts.length, bParts.length);
|
||||
for (let i = 0; i < numberOfParts; i++) {
|
||||
if (aParts[i] !== bParts[i]) {
|
||||
return (Number(aParts[i]) || 0) - (Number(bParts[i]) || 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Resolve a package specifier to a static version
|
||||
*/
|
||||
function _resolvePackageVersion(logger, rushCommonFolder, { name, version }) {
|
||||
if (!version) {
|
||||
version = '*'; // If no version is specified, use the latest version
|
||||
}
|
||||
if (version.match(/^[a-zA-Z0-9\-\+\.]+$/)) {
|
||||
// If the version contains only characters that we recognize to be used in static version specifiers,
|
||||
// pass the version through
|
||||
return version;
|
||||
}
|
||||
else {
|
||||
// version resolves to
|
||||
try {
|
||||
const rushTempFolder = _getRushTempFolder(rushCommonFolder);
|
||||
const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush');
|
||||
(0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)({
|
||||
sourceNpmrcFolder,
|
||||
targetNpmrcFolder: rushTempFolder,
|
||||
logger,
|
||||
supportEnvVarFallbackSyntax: false
|
||||
});
|
||||
const npmPath = getNpmPath();
|
||||
// This returns something that looks like:
|
||||
// ```
|
||||
// [
|
||||
// "3.0.0",
|
||||
// "3.0.1",
|
||||
// ...
|
||||
// "3.0.20"
|
||||
// ]
|
||||
// ```
|
||||
//
|
||||
// if multiple versions match the selector, or
|
||||
//
|
||||
// ```
|
||||
// "3.0.0"
|
||||
// ```
|
||||
//
|
||||
// if only a single version matches.
|
||||
const spawnSyncOptions = {
|
||||
cwd: rushTempFolder,
|
||||
stdio: [],
|
||||
shell: _isWindows()
|
||||
};
|
||||
const platformNpmPath = _getPlatformPath(npmPath);
|
||||
const npmVersionSpawnResult = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(platformNpmPath, ['view', `${name}@${version}`, 'version', '--no-update-notifier', '--json'], spawnSyncOptions);
|
||||
if (npmVersionSpawnResult.status !== 0) {
|
||||
throw new Error(`"npm view" returned error code ${npmVersionSpawnResult.status}`);
|
||||
}
|
||||
const npmViewVersionOutput = npmVersionSpawnResult.stdout.toString();
|
||||
const parsedVersionOutput = JSON.parse(npmViewVersionOutput);
|
||||
const versions = Array.isArray(parsedVersionOutput)
|
||||
? parsedVersionOutput
|
||||
: [parsedVersionOutput];
|
||||
let latestVersion = versions[0];
|
||||
for (let i = 1; i < versions.length; i++) {
|
||||
const latestVersionCandidate = versions[i];
|
||||
if (_compareVersionStrings(latestVersionCandidate, latestVersion) > 0) {
|
||||
latestVersion = latestVersionCandidate;
|
||||
}
|
||||
}
|
||||
if (!latestVersion) {
|
||||
throw new Error('No versions found for the specified version range.');
|
||||
}
|
||||
return latestVersion;
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to resolve version ${version} of package ${name}: ${e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
let _rushJsonFolder;
|
||||
/**
|
||||
* Find the absolute path to the folder containing rush.json
|
||||
*/
|
||||
function findRushJsonFolder() {
|
||||
if (!_rushJsonFolder) {
|
||||
let basePath = __dirname;
|
||||
let tempPath = __dirname;
|
||||
do {
|
||||
const testRushJsonPath = path__WEBPACK_IMPORTED_MODULE_3__.join(basePath, RUSH_JSON_FILENAME);
|
||||
if (fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(testRushJsonPath)) {
|
||||
_rushJsonFolder = basePath;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
basePath = tempPath;
|
||||
}
|
||||
} while (basePath !== (tempPath = path__WEBPACK_IMPORTED_MODULE_3__.dirname(basePath))); // Exit the loop when we hit the disk root
|
||||
if (!_rushJsonFolder) {
|
||||
throw new Error(`Unable to find ${RUSH_JSON_FILENAME}.`);
|
||||
}
|
||||
}
|
||||
return _rushJsonFolder;
|
||||
}
|
||||
/**
|
||||
* Detects if the package in the specified directory is installed
|
||||
*/
|
||||
function _isPackageAlreadyInstalled(packageInstallFolder) {
|
||||
try {
|
||||
const flagFilePath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
||||
if (!fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(flagFilePath)) {
|
||||
return false;
|
||||
}
|
||||
const fileContents = fs__WEBPACK_IMPORTED_MODULE_1__.readFileSync(flagFilePath).toString();
|
||||
return fileContents.trim() === process.version;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Delete a file. Fail silently if it does not exist.
|
||||
*/
|
||||
function _deleteFile(file) {
|
||||
try {
|
||||
fs__WEBPACK_IMPORTED_MODULE_1__.unlinkSync(file);
|
||||
}
|
||||
catch (err) {
|
||||
if (err.code !== 'ENOENT' && err.code !== 'ENOTDIR') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Removes the following files and directories under the specified folder path:
|
||||
* - installed.flag
|
||||
* -
|
||||
* - node_modules
|
||||
*/
|
||||
function _cleanInstallFolder(rushTempFolder, packageInstallFolder, lockFilePath) {
|
||||
try {
|
||||
const flagFile = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
||||
_deleteFile(flagFile);
|
||||
const packageLockFile = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, 'package-lock.json');
|
||||
if (lockFilePath) {
|
||||
fs__WEBPACK_IMPORTED_MODULE_1__.copyFileSync(lockFilePath, packageLockFile);
|
||||
}
|
||||
else {
|
||||
// Not running `npm ci`, so need to cleanup
|
||||
_deleteFile(packageLockFile);
|
||||
const nodeModulesFolder = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME);
|
||||
if (fs__WEBPACK_IMPORTED_MODULE_1__.existsSync(nodeModulesFolder)) {
|
||||
const rushRecyclerFolder = _ensureAndJoinPath(rushTempFolder, 'rush-recycler');
|
||||
fs__WEBPACK_IMPORTED_MODULE_1__.renameSync(nodeModulesFolder, path__WEBPACK_IMPORTED_MODULE_3__.join(rushRecyclerFolder, `install-run-${Date.now().toString()}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error cleaning the package install folder (${packageInstallFolder}): ${e}`);
|
||||
}
|
||||
}
|
||||
function _createPackageJson(packageInstallFolder, name, version) {
|
||||
try {
|
||||
const packageJsonContents = {
|
||||
name: 'ci-rush',
|
||||
version: '0.0.0',
|
||||
dependencies: {
|
||||
[name]: version
|
||||
},
|
||||
description: "DON'T WARN",
|
||||
repository: "DON'T WARN",
|
||||
license: 'MIT'
|
||||
};
|
||||
const packageJsonPath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, PACKAGE_JSON_FILENAME);
|
||||
fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContents, undefined, 2));
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to create package.json: ${e}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Run "npm install" in the package install folder.
|
||||
*/
|
||||
function _installPackage(logger, packageInstallFolder, name, version, command) {
|
||||
try {
|
||||
logger.info(`Installing ${name}...`);
|
||||
const npmPath = getNpmPath();
|
||||
const platformNpmPath = _getPlatformPath(npmPath);
|
||||
const result = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(platformNpmPath, [command], {
|
||||
stdio: 'inherit',
|
||||
cwd: packageInstallFolder,
|
||||
env: process.env,
|
||||
shell: _isWindows()
|
||||
});
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`"npm ${command}" encountered an error`);
|
||||
}
|
||||
logger.info(`Successfully installed ${name}@${version}`);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to install package: ${e}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the ".bin" path for the package.
|
||||
*/
|
||||
function _getBinPath(packageInstallFolder, binName) {
|
||||
const binFolderPath = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
|
||||
const resolvedBinName = _isWindows() ? `${binName}.cmd` : binName;
|
||||
return path__WEBPACK_IMPORTED_MODULE_3__.resolve(binFolderPath, resolvedBinName);
|
||||
}
|
||||
/**
|
||||
* Returns a cross-platform path - windows must enclose any path containing spaces within double quotes.
|
||||
*/
|
||||
function _getPlatformPath(platformPath) {
|
||||
return _isWindows() && platformPath.includes(' ') ? `"${platformPath}"` : platformPath;
|
||||
}
|
||||
function _isWindows() {
|
||||
return os__WEBPACK_IMPORTED_MODULE_2__.platform() === 'win32';
|
||||
}
|
||||
/**
|
||||
* Write a flag file to the package's install directory, signifying that the install was successful.
|
||||
*/
|
||||
function _writeFlagFile(packageInstallFolder) {
|
||||
try {
|
||||
const flagFilePath = path__WEBPACK_IMPORTED_MODULE_3__.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
||||
fs__WEBPACK_IMPORTED_MODULE_1__.writeFileSync(flagFilePath, process.version);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to create installed.flag file in ${packageInstallFolder}`);
|
||||
}
|
||||
}
|
||||
function installAndRun(logger, packageName, packageVersion, packageBinName, packageBinArgs, lockFilePath = process.env[INSTALL_RUN_LOCKFILE_PATH_VARIABLE]) {
|
||||
const rushJsonFolder = findRushJsonFolder();
|
||||
const rushCommonFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushJsonFolder, 'common');
|
||||
const rushTempFolder = _getRushTempFolder(rushCommonFolder);
|
||||
const packageInstallFolder = _ensureAndJoinPath(rushTempFolder, 'install-run', `${packageName}@${packageVersion}`);
|
||||
if (!_isPackageAlreadyInstalled(packageInstallFolder)) {
|
||||
// The package isn't already installed
|
||||
_cleanInstallFolder(rushTempFolder, packageInstallFolder, lockFilePath);
|
||||
const sourceNpmrcFolder = path__WEBPACK_IMPORTED_MODULE_3__.join(rushCommonFolder, 'config', 'rush');
|
||||
(0,_utilities_npmrcUtilities__WEBPACK_IMPORTED_MODULE_4__.syncNpmrc)({
|
||||
sourceNpmrcFolder,
|
||||
targetNpmrcFolder: packageInstallFolder,
|
||||
logger,
|
||||
supportEnvVarFallbackSyntax: false
|
||||
});
|
||||
_createPackageJson(packageInstallFolder, packageName, packageVersion);
|
||||
const command = lockFilePath ? 'ci' : 'install';
|
||||
_installPackage(logger, packageInstallFolder, packageName, packageVersion, command);
|
||||
_writeFlagFile(packageInstallFolder);
|
||||
}
|
||||
const statusMessage = `Invoking "${packageBinName} ${packageBinArgs.join(' ')}"`;
|
||||
const statusMessageLine = new Array(statusMessage.length + 1).join('-');
|
||||
logger.info('\n' + statusMessage + '\n' + statusMessageLine + '\n');
|
||||
const binPath = _getBinPath(packageInstallFolder, packageBinName);
|
||||
const binFolderPath = path__WEBPACK_IMPORTED_MODULE_3__.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
|
||||
// Windows environment variables are case-insensitive. Instead of using SpawnSyncOptions.env, we need to
|
||||
// assign via the process.env proxy to ensure that we append to the right PATH key.
|
||||
const originalEnvPath = process.env.PATH || '';
|
||||
let result;
|
||||
try {
|
||||
// `npm` bin stubs on Windows are `.cmd` files
|
||||
// Node.js will not directly invoke a `.cmd` file unless `shell` is set to `true`
|
||||
const platformBinPath = _getPlatformPath(binPath);
|
||||
process.env.PATH = [binFolderPath, originalEnvPath].join(path__WEBPACK_IMPORTED_MODULE_3__.delimiter);
|
||||
result = child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync(platformBinPath, packageBinArgs, {
|
||||
stdio: 'inherit',
|
||||
windowsVerbatimArguments: false,
|
||||
shell: _isWindows(),
|
||||
cwd: process.cwd(),
|
||||
env: process.env
|
||||
});
|
||||
}
|
||||
finally {
|
||||
process.env.PATH = originalEnvPath;
|
||||
}
|
||||
if (result.status !== null) {
|
||||
return result.status;
|
||||
}
|
||||
else {
|
||||
throw result.error || new Error('An unknown error occurred.');
|
||||
}
|
||||
}
|
||||
function runWithErrorAndStatusCode(logger, fn) {
|
||||
process.exitCode = 1;
|
||||
try {
|
||||
const exitCode = fn();
|
||||
process.exitCode = exitCode;
|
||||
}
|
||||
catch (e) {
|
||||
logger.error('\n\n' + e.toString() + '\n\n');
|
||||
}
|
||||
}
|
||||
function _run() {
|
||||
const [nodePath /* Ex: /bin/node */, scriptPath /* /repo/common/scripts/install-run-rush.js */, rawPackageSpecifier /* qrcode@^1.2.0 */, packageBinName /* qrcode */, ...packageBinArgs /* [-f, myproject/lib] */] = process.argv;
|
||||
if (!nodePath) {
|
||||
throw new Error('Unexpected exception: could not detect node path');
|
||||
}
|
||||
if (path__WEBPACK_IMPORTED_MODULE_3__.basename(scriptPath).toLowerCase() !== 'install-run.js') {
|
||||
// If install-run.js wasn't directly invoked, don't execute the rest of this function. Return control
|
||||
// to the script that (presumably) imported this file
|
||||
return;
|
||||
}
|
||||
if (process.argv.length < 4) {
|
||||
console.log('Usage: install-run.js <package>@<version> <command> [args...]');
|
||||
console.log('Example: install-run.js qrcode@1.2.2 qrcode https://rushjs.io');
|
||||
process.exit(1);
|
||||
}
|
||||
const logger = { info: console.log, error: console.error };
|
||||
runWithErrorAndStatusCode(logger, () => {
|
||||
const rushJsonFolder = findRushJsonFolder();
|
||||
const rushCommonFolder = _ensureAndJoinPath(rushJsonFolder, 'common');
|
||||
const packageSpecifier = _parsePackageSpecifier(rawPackageSpecifier);
|
||||
const name = packageSpecifier.name;
|
||||
const version = _resolvePackageVersion(logger, rushCommonFolder, packageSpecifier);
|
||||
if (packageSpecifier.version !== version) {
|
||||
console.log(`Resolved to ${name}@${version}`);
|
||||
}
|
||||
return installAndRun(logger, name, version, packageBinName, packageBinArgs);
|
||||
});
|
||||
}
|
||||
_run();
|
||||
//# sourceMappingURL=install-run.js.map
|
||||
})();
|
||||
|
||||
module.exports = __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
||||
//# sourceMappingURL=install-run.js.map
|
||||
@@ -1,14 +0,0 @@
|
||||
import pluginJs from "@eslint/js";
|
||||
import tseslint from "typescript-eslint";
|
||||
import prettierRecommended from "eslint-plugin-prettier/recommended";
|
||||
import configPrettier from "eslint-config-prettier";
|
||||
|
||||
/** @type {import('eslint').Linter.Config[]} */
|
||||
export default [
|
||||
pluginJs.configs.recommended,
|
||||
prettierRecommended,
|
||||
configPrettier,
|
||||
...tseslint.configs.recommended,
|
||||
{files: ["**/*.ts"], rules: {"@typescript-eslint/no-explicit-any": "off", '@typescript-eslint/no-empty-object-type': 'off'}},
|
||||
];
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"name": "@hcengineering/communication",
|
||||
"workspaces": ["packages/*"],
|
||||
"scripts": {
|
||||
"publish": "sh scripts/publish.sh",
|
||||
"publish:beta": "sh scripts/publish.sh beta",
|
||||
"build": "turbo run build",
|
||||
"lint": "turbo run lint",
|
||||
"format": "turbo run format",
|
||||
"reformat": "turbo run format && turbo run lint -- --fix",
|
||||
"format:check": "prettier --check \"**/*.ts\"",
|
||||
"clean": "turbo run clean"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.28.0",
|
||||
"@types/bun": "^1.2.15",
|
||||
"bun-types": "^1.2.15",
|
||||
"eslint": "^9.28.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.4.1",
|
||||
"prettier": "^3.5.3",
|
||||
"typescript-eslint": "^8.33.1",
|
||||
"turbo": "^2.5.4"
|
||||
},
|
||||
"packageManager": "bun@1.2.9"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
||||
@@ -1,39 +1,57 @@
|
||||
{
|
||||
"name": "@hcengineering/communication-client-query",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"dist/index.js",
|
||||
"dist/index.cjs",
|
||||
"types/**/*.d.ts"
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "bun run build:types && bun run build:browser",
|
||||
"build:types": "tsc --project ./tsconfig.json --emitDeclarationOnly --declarationDir ./types",
|
||||
"build:browser": "bun build src/index.ts --outdir dist --target browser",
|
||||
"lint": "eslint src/*.ts",
|
||||
"format": "prettier --write src/**/*.ts ",
|
||||
"clean": "rm -rf dist && rm -rf types && rm -rf .turbo"
|
||||
"build": "compile",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:validate": "compile validate",
|
||||
|
||||
"lint": "eslint \"src/**/*.ts\"",
|
||||
"lint:fix": "eslint --fix \"src/**/*.ts\"",
|
||||
"format": "prettier --write src/**/*.ts && eslint --fix \"src/**/*.ts\"",
|
||||
"clean": "rm -rf lib && rm -rf types rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14"
|
||||
"@hcengineering/platform-rig": "^0.6.490",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"esbuild-plugin-copy": "~2.1.1",
|
||||
"eslint": "^8.54.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-query": "workspace:*",
|
||||
"@hcengineering/communication-types": "^0.1.0",
|
||||
"@hcengineering/communication-sdk-types": "^0.1.0",
|
||||
"@hcengineering/communication-query": "^0.1.0",
|
||||
"fast-equals": "^5.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/hcengineering/communication.git"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/index.d.ts",
|
||||
"require": "./lib/index.js",
|
||||
"import": "./lib/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,23 +24,23 @@ export type { MessageQueryParams } from '@hcengineering/communication-query'
|
||||
let lq: LiveQueries
|
||||
let onDestroy: (fn: () => void) => void = () => {}
|
||||
|
||||
export function createMessagesQuery(): MessagesQuery {
|
||||
export function createMessagesQuery (): MessagesQuery {
|
||||
return new MessagesQuery(lq, onDestroy)
|
||||
}
|
||||
|
||||
export function createNotificationsQuery(): NotificationsQuery {
|
||||
export function createNotificationsQuery (): NotificationsQuery {
|
||||
return new NotificationsQuery(lq, onDestroy)
|
||||
}
|
||||
|
||||
export function createNotificationContextsQuery(): NotificationContextsQuery {
|
||||
export function createNotificationContextsQuery (): NotificationContextsQuery {
|
||||
return new NotificationContextsQuery(lq, onDestroy)
|
||||
}
|
||||
|
||||
export function createLabelsQuery(): LabelsQuery {
|
||||
export function createLabelsQuery (): LabelsQuery {
|
||||
return new LabelsQuery(lq, onDestroy)
|
||||
}
|
||||
|
||||
export function initLiveQueries(
|
||||
export function initLiveQueries (
|
||||
client: FindClient,
|
||||
workspace: WorkspaceID,
|
||||
filesUrl: string,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { type LiveQueries } from '@hcengineering/communication-query'
|
||||
import { type LiveQueries, MessageQueryParams } from '@hcengineering/communication-query'
|
||||
import type { PagedQueryCallback, QueryCallback } from '@hcengineering/communication-sdk-types'
|
||||
import {
|
||||
type FindLabelsParams,
|
||||
@@ -25,13 +25,12 @@ import {
|
||||
type Notification
|
||||
} from '@hcengineering/communication-types'
|
||||
import { deepEqual } from 'fast-equals'
|
||||
import type { MessageQueryParams } from '@hcengineering/communication-query'
|
||||
|
||||
class BaseQuery<P extends Record<string, any>, C extends (r: any) => void> {
|
||||
private oldQuery: P | undefined
|
||||
private oldCallback: C | undefined
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
protected readonly lq: LiveQueries,
|
||||
onDestroy: (fn: () => void) => void
|
||||
) {
|
||||
@@ -42,7 +41,7 @@ class BaseQuery<P extends Record<string, any>, C extends (r: any) => void> {
|
||||
|
||||
unsubscribe: () => void = () => {}
|
||||
|
||||
query(params: P, callback: C): boolean {
|
||||
query (params: P, callback: C): boolean {
|
||||
if (!this.needUpdate(params, callback)) {
|
||||
return false
|
||||
}
|
||||
@@ -50,7 +49,7 @@ class BaseQuery<P extends Record<string, any>, C extends (r: any) => void> {
|
||||
return true
|
||||
}
|
||||
|
||||
private doQuery(query: P, callback: C): void {
|
||||
private doQuery (query: P, callback: C): void {
|
||||
this.unsubscribe()
|
||||
this.oldCallback = callback
|
||||
this.oldQuery = query
|
||||
@@ -65,13 +64,13 @@ class BaseQuery<P extends Record<string, any>, C extends (r: any) => void> {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
createQuery(params: P, callback: C): { unsubscribe: () => void } {
|
||||
createQuery (params: P, callback: C): { unsubscribe: () => void } {
|
||||
return {
|
||||
unsubscribe: () => {}
|
||||
}
|
||||
}
|
||||
|
||||
private needUpdate(params: P, callback: C): boolean {
|
||||
private needUpdate (params: P, callback: C): boolean {
|
||||
if (!deepEqual(params, this.oldQuery)) return true
|
||||
if (!deepEqual(callback.toString(), this.oldCallback?.toString())) return true
|
||||
return false
|
||||
@@ -79,43 +78,43 @@ class BaseQuery<P extends Record<string, any>, C extends (r: any) => void> {
|
||||
}
|
||||
|
||||
export class MessagesQuery extends BaseQuery<MessageQueryParams, PagedQueryCallback<Message>> {
|
||||
override createQuery(params: MessageQueryParams, callback: PagedQueryCallback<Message>): { unsubscribe: () => void } {
|
||||
override createQuery (params: MessageQueryParams, callback: PagedQueryCallback<Message>): { unsubscribe: () => void } {
|
||||
return this.lq.queryMessages(params, callback)
|
||||
}
|
||||
}
|
||||
|
||||
export class NotificationsQuery extends BaseQuery<FindNotificationsParams, PagedQueryCallback<Notification>> {
|
||||
override createQuery(
|
||||
override createQuery (
|
||||
params: FindNotificationsParams,
|
||||
callback: PagedQueryCallback<Notification>
|
||||
): {
|
||||
unsubscribe: () => void
|
||||
} {
|
||||
unsubscribe: () => void
|
||||
} {
|
||||
return this.lq.queryNotifications(params, callback)
|
||||
}
|
||||
}
|
||||
|
||||
export class NotificationContextsQuery extends BaseQuery<
|
||||
FindNotificationContextParams,
|
||||
PagedQueryCallback<NotificationContext>
|
||||
FindNotificationContextParams,
|
||||
PagedQueryCallback<NotificationContext>
|
||||
> {
|
||||
override createQuery(
|
||||
override createQuery (
|
||||
params: FindNotificationContextParams,
|
||||
callback: PagedQueryCallback<NotificationContext>
|
||||
): {
|
||||
unsubscribe: () => void
|
||||
} {
|
||||
unsubscribe: () => void
|
||||
} {
|
||||
return this.lq.queryNotificationContexts(params, callback)
|
||||
}
|
||||
}
|
||||
|
||||
export class LabelsQuery extends BaseQuery<FindLabelsParams, QueryCallback<Label>> {
|
||||
override createQuery(
|
||||
override createQuery (
|
||||
params: FindLabelsParams,
|
||||
callback: QueryCallback<Label>
|
||||
): {
|
||||
unsubscribe: () => void
|
||||
} {
|
||||
unsubscribe: () => void
|
||||
} {
|
||||
return this.lq.queryLabels(params, callback)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declarationDir": "./types",
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "lib", "dist", "types", "bundle"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
||||
@@ -1,40 +1,58 @@
|
||||
{
|
||||
"name": "@hcengineering/communication-cockroach",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"dist/index.js",
|
||||
"dist/index.cjs",
|
||||
"types/**/*.d.ts"
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "bun run build:types && bun run build:node",
|
||||
"build:types": "tsc --project ./tsconfig.json --emitDeclarationOnly --declarationDir ./types",
|
||||
"build:node": "bun build src/index.ts --target node --format cjs --outfile dist/index.js",
|
||||
"lint": "eslint src/*.ts",
|
||||
"format": "prettier --write src/**/*.ts",
|
||||
"clean": "rm -rf dist && rm -rf types && rm -rf .turbo"
|
||||
"build": "compile",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:validate": "compile validate",
|
||||
|
||||
"lint": "eslint \"src/**/*.ts\"",
|
||||
"lint:fix": "eslint --fix \"src/**/*.ts\"",
|
||||
"format": "prettier --write src/**/*.ts && eslint --fix \"src/**/*.ts\"",
|
||||
"clean": "rm -rf lib && rm -rf types rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14"
|
||||
"@hcengineering/platform-rig": "^0.6.490",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"esbuild-plugin-copy": "~2.1.1",
|
||||
"eslint": "^8.54.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-shared": "workspace:*",
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/communication-types": "^0.1.0",
|
||||
"@hcengineering/communication-sdk-types": "^0.1.0",
|
||||
"@hcengineering/communication-shared": "^0.1.0",
|
||||
"postgres": "^3.4.4",
|
||||
"uuid": "^11.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/hcengineering/communication.git"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/index.d.ts",
|
||||
"require": "./lib/index.js",
|
||||
"import": "./lib/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export class CockroachAdapter implements DbAdapter {
|
||||
private readonly notification: NotificationsDb
|
||||
private readonly label: LabelsDb
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly sql: SqlClient,
|
||||
private readonly workspace: WorkspaceID,
|
||||
private readonly logger?: Logger,
|
||||
@@ -88,7 +88,7 @@ export class CockroachAdapter implements DbAdapter {
|
||||
this.label = new LabelsDb(this.sql, this.workspace, logger, options)
|
||||
}
|
||||
|
||||
async createMessage(
|
||||
async createMessage (
|
||||
card: CardID,
|
||||
type: MessageType,
|
||||
content: RichText,
|
||||
@@ -97,11 +97,11 @@ export class CockroachAdapter implements DbAdapter {
|
||||
data?: MessageData,
|
||||
externalId?: string,
|
||||
id?: MessageID
|
||||
): Promise<{ id: MessageID; created: Date }> {
|
||||
): Promise<{ id: MessageID, created: Date }> {
|
||||
return await this.message.createMessage(card, type, content, creator, created, data, externalId, id)
|
||||
}
|
||||
|
||||
async createPatch(
|
||||
async createPatch (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -113,19 +113,19 @@ export class CockroachAdapter implements DbAdapter {
|
||||
await this.message.createPatch(card, message, messageCreated, type, data, creator, created)
|
||||
}
|
||||
|
||||
async removePatches(card: CardID): Promise<void> {
|
||||
async removePatches (card: CardID): Promise<void> {
|
||||
await this.message.removePatches(card)
|
||||
}
|
||||
|
||||
async createMessagesGroup(card: CardID, blobId: BlobID, fromDate: Date, toDate: Date, count: number): Promise<void> {
|
||||
async createMessagesGroup (card: CardID, blobId: BlobID, fromDate: Date, toDate: Date, count: number): Promise<void> {
|
||||
await this.message.createMessagesGroup(card, blobId, fromDate, toDate, count)
|
||||
}
|
||||
|
||||
async removeMessagesGroup(card: CardID, blobId: BlobID): Promise<void> {
|
||||
async removeMessagesGroup (card: CardID, blobId: BlobID): Promise<void> {
|
||||
await this.message.removeMessagesGroup(card, blobId)
|
||||
}
|
||||
|
||||
async createReaction(
|
||||
async createReaction (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -136,7 +136,7 @@ export class CockroachAdapter implements DbAdapter {
|
||||
await this.message.createReaction(card, message, messageCreated, reaction, creator, created)
|
||||
}
|
||||
|
||||
async removeReaction(
|
||||
async removeReaction (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -146,7 +146,7 @@ export class CockroachAdapter implements DbAdapter {
|
||||
await this.message.removeReaction(card, message, messageCreated, reaction, creator, new Date())
|
||||
}
|
||||
|
||||
async createFile(
|
||||
async createFile (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -157,11 +157,11 @@ export class CockroachAdapter implements DbAdapter {
|
||||
await this.message.createFile(card, message, messageCreated, data, creator, created)
|
||||
}
|
||||
|
||||
async removeFiles(card: CardID, query: RemoveFileQuery): Promise<void> {
|
||||
async removeFiles (card: CardID, query: RemoveFileQuery): Promise<void> {
|
||||
await this.message.removeFiles(card, query)
|
||||
}
|
||||
|
||||
async createLinkPreview(
|
||||
async createLinkPreview (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -172,11 +172,11 @@ export class CockroachAdapter implements DbAdapter {
|
||||
return await this.message.createLinkPreview(card, message, messageCreated, data, creator, created)
|
||||
}
|
||||
|
||||
async removeLinkPreview(card: CardID, message: MessageID, id: LinkPreviewID): Promise<void> {
|
||||
async removeLinkPreview (card: CardID, message: MessageID, id: LinkPreviewID): Promise<void> {
|
||||
await this.message.removeLinkPreview(card, message, id)
|
||||
}
|
||||
|
||||
async createThread(
|
||||
async createThread (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -187,27 +187,27 @@ export class CockroachAdapter implements DbAdapter {
|
||||
await this.message.createThread(card, message, messageCreated, thread, threadType, created)
|
||||
}
|
||||
|
||||
async removeThreads(query: RemoveThreadQuery): Promise<void> {
|
||||
async removeThreads (query: RemoveThreadQuery): Promise<void> {
|
||||
await this.message.removeThreads(query)
|
||||
}
|
||||
|
||||
async updateThread(thread: CardID, update: ThreadUpdates): Promise<void> {
|
||||
async updateThread (thread: CardID, update: ThreadUpdates): Promise<void> {
|
||||
await this.message.updateThread(thread, update)
|
||||
}
|
||||
|
||||
async findMessages(params: FindMessagesParams): Promise<Message[]> {
|
||||
async findMessages (params: FindMessagesParams): Promise<Message[]> {
|
||||
return await this.message.find(params)
|
||||
}
|
||||
|
||||
async findMessagesGroups(params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
async findMessagesGroups (params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
return await this.message.findMessagesGroups(params)
|
||||
}
|
||||
|
||||
async findThread(thread: CardID): Promise<Thread | undefined> {
|
||||
async findThread (thread: CardID): Promise<Thread | undefined> {
|
||||
return await this.message.findThread(thread)
|
||||
}
|
||||
|
||||
async addCollaborators(
|
||||
async addCollaborators (
|
||||
card: CardID,
|
||||
cardType: CardType,
|
||||
collaborators: AccountID[],
|
||||
@@ -216,15 +216,15 @@ export class CockroachAdapter implements DbAdapter {
|
||||
return await this.notification.addCollaborators(card, cardType, collaborators, date)
|
||||
}
|
||||
|
||||
async removeCollaborators(card: CardID, query: RemoveCollaboratorsQuery): Promise<void> {
|
||||
async removeCollaborators (card: CardID, query: RemoveCollaboratorsQuery): Promise<void> {
|
||||
await this.notification.removeCollaborators(card, query)
|
||||
}
|
||||
|
||||
async updateCollaborators(params: FindCollaboratorsParams, data: Partial<Collaborator>): Promise<void> {
|
||||
async updateCollaborators (params: FindCollaboratorsParams, data: Partial<Collaborator>): Promise<void> {
|
||||
await this.notification.updateCollaborators(params, data)
|
||||
}
|
||||
|
||||
async createNotification(
|
||||
async createNotification (
|
||||
context: ContextID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -236,15 +236,15 @@ export class CockroachAdapter implements DbAdapter {
|
||||
return await this.notification.createNotification(context, message, messageCreated, type, read, content, created)
|
||||
}
|
||||
|
||||
async updateNotification(query: UpdateNotificationQuery, updates: NotificationUpdates): Promise<void> {
|
||||
async updateNotification (query: UpdateNotificationQuery, updates: NotificationUpdates): Promise<void> {
|
||||
await this.notification.updateNotification(query, updates)
|
||||
}
|
||||
|
||||
async removeNotifications(query: RemoveNotificationsQuery): Promise<NotificationID[]> {
|
||||
async removeNotifications (query: RemoveNotificationsQuery): Promise<NotificationID[]> {
|
||||
return await this.notification.removeNotifications(query)
|
||||
}
|
||||
|
||||
async createContext(
|
||||
async createContext (
|
||||
account: AccountID,
|
||||
card: CardID,
|
||||
lastUpdate: Date,
|
||||
@@ -254,51 +254,52 @@ export class CockroachAdapter implements DbAdapter {
|
||||
return await this.notification.createContext(account, card, lastUpdate, lastView, lastNotify)
|
||||
}
|
||||
|
||||
async updateContext(context: ContextID, account: AccountID, updates: NotificationContextUpdates): Promise<void> {
|
||||
async updateContext (context: ContextID, account: AccountID, updates: NotificationContextUpdates): Promise<void> {
|
||||
await this.notification.updateContext(context, account, updates)
|
||||
}
|
||||
|
||||
async removeContexts(query: RemoveNotificationContextQuery): Promise<void> {
|
||||
async removeContexts (query: RemoveNotificationContextQuery): Promise<void> {
|
||||
await this.notification.removeContexts(query)
|
||||
}
|
||||
|
||||
async findNotificationContexts(params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
async findNotificationContexts (params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
return await this.notification.findContexts(params)
|
||||
}
|
||||
|
||||
async findNotifications(params: FindNotificationsParams): Promise<Notification[]> {
|
||||
async findNotifications (params: FindNotificationsParams): Promise<Notification[]> {
|
||||
return await this.notification.findNotifications(params)
|
||||
}
|
||||
|
||||
async findCollaborators(params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
async findCollaborators (params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
return await this.notification.findCollaborators(params)
|
||||
}
|
||||
|
||||
close(): void {
|
||||
close (): void {
|
||||
this.sql.close()
|
||||
}
|
||||
|
||||
getCollaboratorsCursor(card: CardID, date: Date, size?: number): AsyncIterable<Collaborator[]> {
|
||||
getCollaboratorsCursor (card: CardID, date: Date, size?: number): AsyncIterable<Collaborator[]> {
|
||||
return this.notification.getCollaboratorsCursor(card, date, size)
|
||||
}
|
||||
|
||||
createLabel(label: LabelID, card: CardID, cardType: CardType, account: AccountID, created: Date): Promise<void> {
|
||||
createLabel (label: LabelID, card: CardID, cardType: CardType, account: AccountID, created: Date): Promise<void> {
|
||||
return this.label.createLabel(label, card, cardType, account, created)
|
||||
}
|
||||
|
||||
removeLabels(query: RemoveLabelQuery): Promise<void> {
|
||||
removeLabels (query: RemoveLabelQuery): Promise<void> {
|
||||
return this.label.removeLabels(query)
|
||||
}
|
||||
|
||||
findLabels(params: FindLabelsParams): Promise<Label[]> {
|
||||
findLabels (params: FindLabelsParams): Promise<Label[]> {
|
||||
return this.label.findLabels(params)
|
||||
}
|
||||
updateLabels(card: CardID, updates: LabelUpdates): Promise<void> {
|
||||
|
||||
updateLabels (card: CardID, updates: LabelUpdates): Promise<void> {
|
||||
return this.label.updateLabels(card, updates)
|
||||
}
|
||||
|
||||
//TODO: remove it ??
|
||||
async getAccountsByPersonIds(ids: string[]): Promise<AccountID[]> {
|
||||
// TODO: remove it ??
|
||||
async getAccountsByPersonIds (ids: string[]): Promise<AccountID[]> {
|
||||
if (ids.length === 0) return []
|
||||
const sql = `SELECT data ->> 'personUuid' AS "personUuid"
|
||||
FROM public.contact
|
||||
@@ -309,20 +310,20 @@ export class CockroachAdapter implements DbAdapter {
|
||||
return result?.map((it) => it.personUuid as AccountID).filter((it) => it != null) ?? []
|
||||
}
|
||||
|
||||
async getNameByAccount(id: AccountID): Promise<string | undefined> {
|
||||
async getNameByAccount (id: AccountID): Promise<string | undefined> {
|
||||
const sql = `SELECT data ->> 'name' AS name
|
||||
FROM public.contact
|
||||
WHERE "workspaceId" = $1::uuid
|
||||
AND data ->> 'personUuid' = $2
|
||||
LIMIT 1`
|
||||
const result = await this.sql.execute(sql, [this.workspace, id])
|
||||
const name = result[0]?.name
|
||||
const name: string | undefined = result[0]?.name
|
||||
|
||||
return name ? formatName(name) : undefined
|
||||
return name != null ? formatName(name) : undefined
|
||||
}
|
||||
}
|
||||
|
||||
export async function createDbAdapter(
|
||||
export async function createDbAdapter (
|
||||
connectionString: string,
|
||||
workspace: WorkspaceID,
|
||||
logger?: Logger,
|
||||
@@ -338,14 +339,14 @@ export async function createDbAdapter(
|
||||
}
|
||||
|
||||
class CockroachClient implements SqlClient {
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly db: PostgresClientReference,
|
||||
private readonly sql: postgres.Sql
|
||||
) {}
|
||||
|
||||
async execute<T = SqlRow>(query: string, params?: SqlParams): Promise<T[]> {
|
||||
const convertedParams = convertArrayParams(params)
|
||||
return this.sql.unsafe<T[]>(query, convertedParams)
|
||||
return await this.sql.unsafe<T[]>(query, convertedParams)
|
||||
}
|
||||
|
||||
cursor<T = SqlRow>(query: string, params?: SqlParams, size?: number): AsyncIterable<NonNullable<T[][number]>[]> {
|
||||
@@ -353,7 +354,7 @@ class CockroachClient implements SqlClient {
|
||||
return this.sql.unsafe<T[]>(query, convertedParams).cursor(size)
|
||||
}
|
||||
|
||||
close(): void {
|
||||
close (): void {
|
||||
this.db.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class PostgresClientReferenceImpl {
|
||||
count: number
|
||||
client: postgres.Sql | Promise<postgres.Sql>
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
client: postgres.Sql | Promise<postgres.Sql>,
|
||||
readonly onclose: () => void
|
||||
) {
|
||||
@@ -37,14 +37,14 @@ class PostgresClientReferenceImpl {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
async getClient(): Promise<postgres.Sql> {
|
||||
async getClient (): Promise<postgres.Sql> {
|
||||
if (this.client instanceof Promise) {
|
||||
this.client = await this.client
|
||||
}
|
||||
return this.client
|
||||
}
|
||||
|
||||
close(force: boolean = false): void {
|
||||
close (force: boolean = false): void {
|
||||
this.count--
|
||||
if (this.count === 0 || force) {
|
||||
if (force) {
|
||||
@@ -59,7 +59,7 @@ class PostgresClientReferenceImpl {
|
||||
}
|
||||
}
|
||||
|
||||
addRef(): void {
|
||||
addRef (): void {
|
||||
this.count++
|
||||
console.log('Add postgres connection', this.count)
|
||||
}
|
||||
@@ -67,12 +67,12 @@ class PostgresClientReferenceImpl {
|
||||
|
||||
export class ClientRef implements PostgresClientReference {
|
||||
id = uuid()
|
||||
constructor(readonly client: PostgresClientReferenceImpl) {
|
||||
constructor (readonly client: PostgresClientReferenceImpl) {
|
||||
clientRefs.set(this.id, this)
|
||||
}
|
||||
|
||||
closed = false
|
||||
async getClient(): Promise<postgres.Sql> {
|
||||
async getClient (): Promise<postgres.Sql> {
|
||||
if (!this.closed) {
|
||||
return await this.client.getClient()
|
||||
} else {
|
||||
@@ -80,7 +80,7 @@ export class ClientRef implements PostgresClientReference {
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {
|
||||
close (): void {
|
||||
// Do not allow double close of connection client-query
|
||||
if (!this.closed) {
|
||||
clientRefs.delete(this.id)
|
||||
@@ -90,7 +90,7 @@ export class ClientRef implements PostgresClientReference {
|
||||
}
|
||||
}
|
||||
|
||||
export function connect(connectionString: string, database?: string): PostgresClientReference {
|
||||
export function connect (connectionString: string, database?: string): PostgresClientReference {
|
||||
const extraOptions = JSON.parse(process.env.POSTGRES_OPTIONS ?? '{}')
|
||||
const key = `${connectionString}${extraOptions}`
|
||||
let existing = connections.get(key)
|
||||
@@ -103,8 +103,8 @@ export function connect(connectionString: string, database?: string): PostgresCl
|
||||
fetch_types: true,
|
||||
debug: false,
|
||||
notice: false,
|
||||
onnotice() {},
|
||||
onparameter() {},
|
||||
onnotice () {},
|
||||
onparameter () {},
|
||||
...extraOptions,
|
||||
prepare: true,
|
||||
connection: {
|
||||
|
||||
@@ -19,7 +19,7 @@ import type { WorkspaceID } from '@hcengineering/communication-types'
|
||||
import { type Logger, type Options, type SqlClient } from '../types'
|
||||
|
||||
export class BaseDb {
|
||||
constructor(
|
||||
constructor (
|
||||
readonly client: SqlClient,
|
||||
readonly workspace: WorkspaceID,
|
||||
readonly logger?: Logger,
|
||||
|
||||
@@ -29,7 +29,7 @@ import { toLabel } from './mapping'
|
||||
import type { LabelUpdates, RemoveLabelQuery } from '@hcengineering/communication-sdk-types'
|
||||
|
||||
export class LabelsDb extends BaseDb {
|
||||
async createLabel(
|
||||
async createLabel (
|
||||
label: LabelID,
|
||||
card: CardID,
|
||||
cardType: CardType,
|
||||
@@ -54,7 +54,7 @@ export class LabelsDb extends BaseDb {
|
||||
)
|
||||
}
|
||||
|
||||
async removeLabels(query: RemoveLabelQuery): Promise<void> {
|
||||
async removeLabels (query: RemoveLabelQuery): Promise<void> {
|
||||
const db: Partial<LabelDb> = {
|
||||
label_id: query.label,
|
||||
card_id: query.card,
|
||||
@@ -77,7 +77,7 @@ export class LabelsDb extends BaseDb {
|
||||
await this.execute(sql, whereValues, 'remove labels')
|
||||
}
|
||||
|
||||
async updateLabels(card: CardID, updates: LabelUpdates): Promise<void> {
|
||||
async updateLabels (card: CardID, updates: LabelUpdates): Promise<void> {
|
||||
const dbData: Partial<LabelDb> = {
|
||||
card_type: updates.cardType
|
||||
}
|
||||
@@ -95,7 +95,7 @@ export class LabelsDb extends BaseDb {
|
||||
await this.execute(sql, [this.workspace, card, ...setValues], 'update labels')
|
||||
}
|
||||
|
||||
async findLabels(params: FindLabelsParams): Promise<Label[]> {
|
||||
async findLabels (params: FindLabelsParams): Promise<Label[]> {
|
||||
const select = `SELECT *
|
||||
FROM ${TableName.Label} l`
|
||||
|
||||
@@ -111,7 +111,7 @@ export class LabelsDb extends BaseDb {
|
||||
return result.map((it: any) => toLabel(it))
|
||||
}
|
||||
|
||||
buildWhere(params: FindLabelsParams, startIndex: number = 0, prefix = 'l.'): { where: string; values: any[] } {
|
||||
buildWhere (params: FindLabelsParams, startIndex: number = 0, prefix = 'l.'): { where: string, values: any[] } {
|
||||
const where: string[] = []
|
||||
const values: any[] = []
|
||||
let index = startIndex + 1
|
||||
|
||||
@@ -104,7 +104,7 @@ type RawContext = ContextDb & { id: ContextID } & {
|
||||
notifications?: RawNotification[]
|
||||
}
|
||||
|
||||
export function toMessage(raw: RawMessage): Message {
|
||||
export function toMessage (raw: RawMessage): Message {
|
||||
const patches = (raw.patches ?? []).map((it) => toPatch(it))
|
||||
const rawMessage: Message = {
|
||||
id: String(raw.id) as MessageID,
|
||||
@@ -124,7 +124,7 @@ export function toMessage(raw: RawMessage): Message {
|
||||
messageCreated: new Date(raw.created),
|
||||
thread: raw.thread_id,
|
||||
threadType: raw.thread_type,
|
||||
repliesCount: raw.replies_count ? parseInt(raw.replies_count as any) : 0,
|
||||
repliesCount: raw.replies_count != null ? parseInt(raw.replies_count as any) : 0,
|
||||
lastReply: raw.last_reply ?? new Date()
|
||||
}
|
||||
: undefined,
|
||||
@@ -140,7 +140,7 @@ export function toMessage(raw: RawMessage): Message {
|
||||
return applyPatches(rawMessage, patches, [PatchType.update, PatchType.remove])
|
||||
}
|
||||
|
||||
export function toReaction(raw: ReactionDb): Reaction {
|
||||
export function toReaction (raw: ReactionDb): Reaction {
|
||||
return {
|
||||
reaction: raw.reaction,
|
||||
creator: raw.creator,
|
||||
@@ -148,7 +148,7 @@ export function toReaction(raw: ReactionDb): Reaction {
|
||||
}
|
||||
}
|
||||
|
||||
export function toFile(raw: Omit<FileDb, 'workspace_id'>): File {
|
||||
export function toFile (raw: Omit<FileDb, 'workspace_id'>): File {
|
||||
return {
|
||||
blobId: raw.blob_id,
|
||||
type: raw.type,
|
||||
@@ -160,7 +160,7 @@ export function toFile(raw: Omit<FileDb, 'workspace_id'>): File {
|
||||
}
|
||||
}
|
||||
|
||||
export function toLinkPreview(raw: LinkPreviewDb): LinkPreview {
|
||||
export function toLinkPreview (raw: LinkPreviewDb): LinkPreview {
|
||||
return {
|
||||
id: String(raw.id) as LinkPreviewID,
|
||||
url: raw.url,
|
||||
@@ -175,7 +175,7 @@ export function toLinkPreview(raw: LinkPreviewDb): LinkPreview {
|
||||
}
|
||||
}
|
||||
|
||||
export function toMessagesGroup(raw: MessagesGroupDb): MessagesGroup {
|
||||
export function toMessagesGroup (raw: MessagesGroupDb): MessagesGroup {
|
||||
return {
|
||||
card: raw.card_id,
|
||||
blobId: raw.blob_id,
|
||||
@@ -186,7 +186,7 @@ export function toMessagesGroup(raw: MessagesGroupDb): MessagesGroup {
|
||||
}
|
||||
}
|
||||
|
||||
export function toPatch(raw: Omit<PatchDb, 'workspace_id'>): Patch {
|
||||
export function toPatch (raw: Omit<PatchDb, 'workspace_id'>): Patch {
|
||||
return {
|
||||
type: raw.type,
|
||||
messageCreated: new Date(raw.message_created),
|
||||
@@ -197,7 +197,7 @@ export function toPatch(raw: Omit<PatchDb, 'workspace_id'>): Patch {
|
||||
}
|
||||
}
|
||||
|
||||
export function toThread(raw: ThreadDb): Thread {
|
||||
export function toThread (raw: ThreadDb): Thread {
|
||||
return {
|
||||
card: raw.card_id,
|
||||
message: String(raw.message_id) as MessageID,
|
||||
@@ -209,7 +209,7 @@ export function toThread(raw: ThreadDb): Thread {
|
||||
}
|
||||
}
|
||||
|
||||
export function toNotificationContext(raw: RawContext): NotificationContext {
|
||||
export function toNotificationContext (raw: RawContext): NotificationContext {
|
||||
const lastView = new Date(raw.last_view)
|
||||
return {
|
||||
id: String(raw.id) as ContextID,
|
||||
@@ -224,7 +224,7 @@ export function toNotificationContext(raw: RawContext): NotificationContext {
|
||||
}
|
||||
}
|
||||
|
||||
function toNotificationRaw(id: ContextID, card: CardID, raw: RawNotification): Notification {
|
||||
function toNotificationRaw (id: ContextID, card: CardID, raw: RawNotification): Notification {
|
||||
const created = new Date(raw.created)
|
||||
let message: Message | undefined
|
||||
|
||||
@@ -261,17 +261,17 @@ function toNotificationRaw(id: ContextID, card: CardID, raw: RawNotification): N
|
||||
})
|
||||
)
|
||||
|
||||
let thread: Thread | undefined = undefined
|
||||
let thread: Thread | undefined
|
||||
|
||||
if (raw.message_thread_id != null && raw.message_thread_type != null) {
|
||||
thread = {
|
||||
card,
|
||||
message: String(raw.message_id) as MessageID,
|
||||
messageCreated: raw.message_created ? new Date(raw.message_created) : created,
|
||||
messageCreated: raw.message_created != null ? new Date(raw.message_created) : created,
|
||||
thread: raw.message_thread_id,
|
||||
threadType: raw.message_thread_type,
|
||||
repliesCount: Number(raw.message_replies ?? 0),
|
||||
lastReply: raw.message_last_reply ? new Date(raw.message_last_reply) : created
|
||||
lastReply: raw.message_last_reply != null ? new Date(raw.message_last_reply) : created
|
||||
}
|
||||
}
|
||||
message = {
|
||||
@@ -338,11 +338,11 @@ function toNotificationRaw(id: ContextID, card: CardID, raw: RawNotification): N
|
||||
}
|
||||
}
|
||||
|
||||
export function toNotification(raw: RawNotification & { card_id: CardID }): Notification {
|
||||
export function toNotification (raw: RawNotification & { card_id: CardID }): Notification {
|
||||
return toNotificationRaw(raw.context_id, raw.card_id, raw)
|
||||
}
|
||||
|
||||
export function toCollaborator(raw: CollaboratorDb): Collaborator {
|
||||
export function toCollaborator (raw: CollaboratorDb): Collaborator {
|
||||
return {
|
||||
account: raw.account,
|
||||
cardType: raw.card_type,
|
||||
@@ -350,7 +350,7 @@ export function toCollaborator(raw: CollaboratorDb): Collaborator {
|
||||
}
|
||||
}
|
||||
|
||||
export function toLabel(raw: LabelDb): Label {
|
||||
export function toLabel (raw: LabelDb): Label {
|
||||
return {
|
||||
label: raw.label_id,
|
||||
card: raw.card_id,
|
||||
|
||||
@@ -53,7 +53,7 @@ import type { RemoveFileQuery, RemoveThreadQuery, ThreadUpdates } from '@hcengin
|
||||
|
||||
export class MessagesDb extends BaseDb {
|
||||
// Message
|
||||
async createMessage(
|
||||
async createMessage (
|
||||
card: CardID,
|
||||
type: MessageType,
|
||||
content: RichText,
|
||||
@@ -62,7 +62,7 @@ export class MessagesDb extends BaseDb {
|
||||
data?: MessageData,
|
||||
externalId?: string,
|
||||
id?: MessageID
|
||||
): Promise<{ id: MessageID; created: Date }> {
|
||||
): Promise<{ id: MessageID, created: Date }> {
|
||||
const db: Omit<MessageDb, 'id'> & { id?: MessageID } = {
|
||||
type,
|
||||
workspace_id: this.workspace,
|
||||
@@ -104,7 +104,7 @@ export class MessagesDb extends BaseDb {
|
||||
return { id: idR, created: createdR }
|
||||
}
|
||||
|
||||
async createPatch(
|
||||
async createPatch (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -136,7 +136,7 @@ export class MessagesDb extends BaseDb {
|
||||
)
|
||||
}
|
||||
|
||||
async removePatches(card: CardID): Promise<void> {
|
||||
async removePatches (card: CardID): Promise<void> {
|
||||
const sql = `DELETE
|
||||
FROM ${TableName.Patch}
|
||||
WHERE workspace_id = $1::uuid
|
||||
@@ -145,7 +145,7 @@ export class MessagesDb extends BaseDb {
|
||||
}
|
||||
|
||||
// File
|
||||
async createFile(
|
||||
async createFile (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -190,7 +190,7 @@ export class MessagesDb extends BaseDb {
|
||||
)
|
||||
}
|
||||
|
||||
async removeFiles(card: CardID, query: RemoveFileQuery): Promise<void> {
|
||||
async removeFiles (card: CardID, query: RemoveFileQuery): Promise<void> {
|
||||
const db: Partial<FileDb> = {
|
||||
card_id: card,
|
||||
message_id: query.message,
|
||||
@@ -212,7 +212,7 @@ export class MessagesDb extends BaseDb {
|
||||
await this.execute(sql, whereValues, 'remove files')
|
||||
}
|
||||
|
||||
async createLinkPreview(
|
||||
async createLinkPreview (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -261,13 +261,13 @@ export class MessagesDb extends BaseDb {
|
||||
return result[0].id as LinkPreviewID
|
||||
}
|
||||
|
||||
async removeLinkPreview(card: CardID, message: MessageID, id: LinkPreviewID): Promise<void> {
|
||||
async removeLinkPreview (card: CardID, message: MessageID, id: LinkPreviewID): Promise<void> {
|
||||
const sql = `DELETE FROM ${TableName.LinkPreview} WHERE workspace_id = $1::uuid AND card_id = $2::varchar AND message_id = $3::int8 AND id = $4::int8`
|
||||
await this.execute(sql, [this.workspace, card, message, id], 'remove link preview')
|
||||
}
|
||||
|
||||
// Reaction
|
||||
async createReaction(
|
||||
async createReaction (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -305,7 +305,7 @@ export class MessagesDb extends BaseDb {
|
||||
}
|
||||
}
|
||||
|
||||
async removeReaction(
|
||||
async removeReaction (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -336,7 +336,7 @@ export class MessagesDb extends BaseDb {
|
||||
}
|
||||
|
||||
// Thread
|
||||
async createThread(
|
||||
async createThread (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -373,7 +373,7 @@ export class MessagesDb extends BaseDb {
|
||||
)
|
||||
}
|
||||
|
||||
async removeThreads(query: RemoveThreadQuery): Promise<void> {
|
||||
async removeThreads (query: RemoveThreadQuery): Promise<void> {
|
||||
const db: Partial<ThreadDb> = {
|
||||
card_id: query.card,
|
||||
message_id: query.message,
|
||||
@@ -396,7 +396,7 @@ export class MessagesDb extends BaseDb {
|
||||
await this.execute(sql, whereValues, 'remove threads')
|
||||
}
|
||||
|
||||
async updateThread(thread: CardID, update: ThreadUpdates): Promise<void> {
|
||||
async updateThread (thread: CardID, update: ThreadUpdates): Promise<void> {
|
||||
const set: string[] = []
|
||||
const values: any[] = []
|
||||
|
||||
@@ -427,7 +427,7 @@ export class MessagesDb extends BaseDb {
|
||||
}
|
||||
|
||||
// MessagesGroup
|
||||
async createMessagesGroup(card: CardID, blobId: BlobID, fromDate: Date, toDate: Date, count: number): Promise<void> {
|
||||
async createMessagesGroup (card: CardID, blobId: BlobID, fromDate: Date, toDate: Date, count: number): Promise<void> {
|
||||
const db: MessagesGroupDb = {
|
||||
workspace_id: this.workspace,
|
||||
card_id: card,
|
||||
@@ -446,7 +446,7 @@ export class MessagesDb extends BaseDb {
|
||||
)
|
||||
}
|
||||
|
||||
async removeMessagesGroup(card: CardID, blobId: BlobID): Promise<void> {
|
||||
async removeMessagesGroup (card: CardID, blobId: BlobID): Promise<void> {
|
||||
const sql = `DELETE
|
||||
FROM ${TableName.MessagesGroup}
|
||||
WHERE workspace_id = $1::uuid
|
||||
@@ -455,7 +455,7 @@ export class MessagesDb extends BaseDb {
|
||||
await this.execute(sql, [this.workspace, card, blobId], 'remove messages group')
|
||||
}
|
||||
|
||||
async find(params: FindMessagesParams): Promise<Message[]> {
|
||||
async find (params: FindMessagesParams): Promise<Message[]> {
|
||||
const { where, values } = this.buildMessageWhere(params)
|
||||
const orderBy = this.buildOrderBy(params)
|
||||
const limit = this.buildLimit(params)
|
||||
@@ -474,15 +474,15 @@ export class MessagesDb extends BaseDb {
|
||||
return result.map((it: any) => toMessage(it))
|
||||
}
|
||||
|
||||
private buildOrderBy(params: FindMessagesParams): string {
|
||||
private buildOrderBy (params: FindMessagesParams): string {
|
||||
return params.order != null ? `ORDER BY m.created ${params.order === SortingOrder.Ascending ? 'ASC' : 'DESC'}` : ''
|
||||
}
|
||||
|
||||
private buildLimit(params: FindMessagesParams): string {
|
||||
private buildLimit (params: FindMessagesParams): string {
|
||||
return params.limit != null ? `LIMIT ${params.limit}` : ''
|
||||
}
|
||||
|
||||
private buildCteLimitedMessages(where: string, orderBy: string, limit: string): string {
|
||||
private buildCteLimitedMessages (where: string, orderBy: string, limit: string): string {
|
||||
return `
|
||||
limited_messages AS (
|
||||
SELECT *
|
||||
@@ -494,8 +494,8 @@ export class MessagesDb extends BaseDb {
|
||||
`
|
||||
}
|
||||
|
||||
private buildCteAggregatedFiles(params: FindMessagesParams): string {
|
||||
if (!params.files) return ''
|
||||
private buildCteAggregatedFiles (params: FindMessagesParams): string {
|
||||
if (params.files !== true) return ''
|
||||
return `,
|
||||
agg_files AS (
|
||||
SELECT
|
||||
@@ -521,8 +521,8 @@ export class MessagesDb extends BaseDb {
|
||||
`
|
||||
}
|
||||
|
||||
private buildCteAggregatedLinkPreviews(params: FindMessagesParams): string {
|
||||
if (!params.links) return ''
|
||||
private buildCteAggregatedLinkPreviews (params: FindMessagesParams): string {
|
||||
if (params.links !== true) return ''
|
||||
return `,
|
||||
agg_link_previews AS (
|
||||
SELECT
|
||||
@@ -551,8 +551,8 @@ export class MessagesDb extends BaseDb {
|
||||
`
|
||||
}
|
||||
|
||||
private buildCteAggregatedReactions(params: FindMessagesParams): string {
|
||||
if (!params.reactions) return ''
|
||||
private buildCteAggregatedReactions (params: FindMessagesParams): string {
|
||||
if (params.reactions !== true) return ''
|
||||
return `,
|
||||
agg_reactions AS (
|
||||
SELECT
|
||||
@@ -574,7 +574,7 @@ export class MessagesDb extends BaseDb {
|
||||
`
|
||||
}
|
||||
|
||||
private buildCteAggregatedPatches(): string {
|
||||
private buildCteAggregatedPatches (): string {
|
||||
return `,
|
||||
agg_patches AS (
|
||||
SELECT
|
||||
@@ -599,44 +599,48 @@ export class MessagesDb extends BaseDb {
|
||||
`
|
||||
}
|
||||
|
||||
private buildMainSelect(params: FindMessagesParams): string {
|
||||
private buildMainSelect (params: FindMessagesParams): string {
|
||||
const orderBy = this.buildOrderBy(params)
|
||||
const selectReplies = params.replies
|
||||
? `t.thread_id as thread_id, t.thread_type as thread_type, t.replies_count::int as replies_count, t.last_reply as last_reply,`
|
||||
: ''
|
||||
const selectReplies =
|
||||
params.replies === true
|
||||
? 't.thread_id as thread_id, t.thread_type as thread_type, t.replies_count::int as replies_count, t.last_reply as last_reply,'
|
||||
: ''
|
||||
|
||||
const selectFiles = params.files ? `COALESCE(f.files, '[]'::jsonb) AS files,` : `'[]'::jsonb AS files,`
|
||||
const selectLinks = params.links
|
||||
? `COALESCE(l.link_previews, '[]'::jsonb) AS link_previews,`
|
||||
: `'[]'::jsonb AS link_previews,`
|
||||
const selectFiles = params.files === true ? "COALESCE(f.files, '[]'::jsonb) AS files," : "'[]'::jsonb AS files,"
|
||||
const selectLinks =
|
||||
params.links === true
|
||||
? "COALESCE(l.link_previews, '[]'::jsonb) AS link_previews,"
|
||||
: "'[]'::jsonb AS link_previews,"
|
||||
|
||||
const selectReactions = params.reactions
|
||||
? `COALESCE(r.reactions, '[]'::jsonb) AS reactions,`
|
||||
: `'[]'::jsonb AS reactions,`
|
||||
const selectReactions =
|
||||
params.reactions === true ? "COALESCE(r.reactions, '[]'::jsonb) AS reactions," : "'[]'::jsonb AS reactions,"
|
||||
|
||||
const joinFiles = params.files
|
||||
? `
|
||||
const joinFiles =
|
||||
params.files === true
|
||||
? `
|
||||
LEFT JOIN agg_files f
|
||||
ON f.workspace_id = m.workspace_id
|
||||
AND f.card_id = m.card_id
|
||||
AND f.message_id = m.id`
|
||||
: ''
|
||||
: ''
|
||||
|
||||
const joinLinks = params.links
|
||||
? `
|
||||
const joinLinks =
|
||||
params.links === true
|
||||
? `
|
||||
LEFT JOIN agg_link_previews l
|
||||
ON l.workspace_id = m.workspace_id
|
||||
AND l.card_id = m.card_id
|
||||
AND l.message_id = m.id`
|
||||
: ''
|
||||
: ''
|
||||
|
||||
const joinReactions = params.reactions
|
||||
? `
|
||||
const joinReactions =
|
||||
params.reactions === true
|
||||
? `
|
||||
LEFT JOIN agg_reactions r
|
||||
ON r.workspace_id = m.workspace_id
|
||||
AND r.card_id = m.card_id
|
||||
AND r.message_id = m.id`
|
||||
: ''
|
||||
: ''
|
||||
|
||||
return `
|
||||
SELECT m.id::text,
|
||||
@@ -668,7 +672,7 @@ export class MessagesDb extends BaseDb {
|
||||
`
|
||||
}
|
||||
|
||||
buildMessageWhere(params: FindMessagesParams): { where: string; values: any[] } {
|
||||
buildMessageWhere (params: FindMessagesParams): { where: string, values: any[] } {
|
||||
const where: string[] = ['m.workspace_id = $1::uuid']
|
||||
const values: any[] = [this.workspace]
|
||||
|
||||
@@ -701,7 +705,7 @@ export class MessagesDb extends BaseDb {
|
||||
}
|
||||
|
||||
// Find thread
|
||||
async findThread(thread: CardID): Promise<Thread | undefined> {
|
||||
async findThread (thread: CardID): Promise<Thread | undefined> {
|
||||
const sql = `SELECT t.card_id,
|
||||
t.message_id::text,
|
||||
t.message_created,
|
||||
@@ -719,7 +723,7 @@ export class MessagesDb extends BaseDb {
|
||||
}
|
||||
|
||||
// Find messages groups
|
||||
async findMessagesGroups(params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
async findMessagesGroups (params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
const select = `
|
||||
SELECT mg.card_id,
|
||||
mg.blob_id,
|
||||
@@ -756,7 +760,7 @@ export class MessagesDb extends BaseDb {
|
||||
return result.map((it: any) => toMessagesGroup(it))
|
||||
}
|
||||
|
||||
buildMessagesGroupWhere(params: FindMessagesGroupsParams): {
|
||||
buildMessagesGroupWhere (params: FindMessagesGroupsParams): {
|
||||
where: string
|
||||
values: any[]
|
||||
} {
|
||||
|
||||
@@ -45,7 +45,7 @@ import type {
|
||||
} from '@hcengineering/communication-sdk-types'
|
||||
|
||||
export class NotificationsDb extends BaseDb {
|
||||
async addCollaborators(
|
||||
async addCollaborators (
|
||||
card: CardID,
|
||||
cardType: CardType,
|
||||
collaborators: AccountID[],
|
||||
@@ -68,7 +68,7 @@ export class NotificationsDb extends BaseDb {
|
||||
return result.map((it: any) => it.account)
|
||||
}
|
||||
|
||||
async removeCollaborators(card: CardID, query: RemoveCollaboratorsQuery): Promise<void> {
|
||||
async removeCollaborators (card: CardID, query: RemoveCollaboratorsQuery): Promise<void> {
|
||||
const { accounts } = query
|
||||
if (accounts === undefined) {
|
||||
const sql = `DELETE FROM ${TableName.Collaborators} WHERE workspace_id = $1::uuid AND card_id = $2::varchar`
|
||||
@@ -92,7 +92,7 @@ export class NotificationsDb extends BaseDb {
|
||||
}
|
||||
}
|
||||
|
||||
getCollaboratorsCursor(
|
||||
getCollaboratorsCursor (
|
||||
card: CardID,
|
||||
date: Date,
|
||||
size?: number
|
||||
@@ -108,7 +108,7 @@ export class NotificationsDb extends BaseDb {
|
||||
return this.client.cursor<Collaborator>(sql, [this.workspace, card, date], size)
|
||||
}
|
||||
|
||||
async createNotification(
|
||||
async createNotification (
|
||||
context: ContextID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -137,7 +137,7 @@ export class NotificationsDb extends BaseDb {
|
||||
return result[0].id as NotificationID
|
||||
}
|
||||
|
||||
async updateNotification(query: UpdateNotificationQuery, updates: NotificationUpdates): Promise<void> {
|
||||
async updateNotification (query: UpdateNotificationQuery, updates: NotificationUpdates): Promise<void> {
|
||||
const where: string[] = [
|
||||
'nc.workspace_id = $1::uuid',
|
||||
'nc.id = $2::int8',
|
||||
@@ -175,7 +175,7 @@ export class NotificationsDb extends BaseDb {
|
||||
await this.execute(sql, [...values, updates.read], 'update notification')
|
||||
}
|
||||
|
||||
async removeNotifications(query: RemoveNotificationsQuery): Promise<NotificationID[]> {
|
||||
async removeNotifications (query: RemoveNotificationsQuery): Promise<NotificationID[]> {
|
||||
const { context, account, ids } = query
|
||||
if (ids.length === 0) return []
|
||||
const where: string[] = [
|
||||
@@ -205,7 +205,7 @@ export class NotificationsDb extends BaseDb {
|
||||
return result.map((row: any) => row.id)
|
||||
}
|
||||
|
||||
async createContext(
|
||||
async createContext (
|
||||
account: AccountID,
|
||||
card: CardID,
|
||||
lastUpdate: Date,
|
||||
@@ -231,7 +231,7 @@ export class NotificationsDb extends BaseDb {
|
||||
return result[0].id as ContextID
|
||||
}
|
||||
|
||||
async removeContexts(query: RemoveNotificationContextQuery): Promise<void> {
|
||||
async removeContexts (query: RemoveNotificationContextQuery): Promise<void> {
|
||||
const db: Partial<ContextDb> & { id?: ContextID } = {
|
||||
id: query.id,
|
||||
card_id: query.card,
|
||||
@@ -253,7 +253,7 @@ export class NotificationsDb extends BaseDb {
|
||||
await this.execute(sql, whereValues, 'remove notification context')
|
||||
}
|
||||
|
||||
async updateContext(context: ContextID, account: AccountID, updates: NotificationContextUpdates): Promise<void> {
|
||||
async updateContext (context: ContextID, account: AccountID, updates: NotificationContextUpdates): Promise<void> {
|
||||
const dbData: Partial<ContextDb> = {}
|
||||
|
||||
if (updates.lastView != null) {
|
||||
@@ -281,7 +281,7 @@ export class NotificationsDb extends BaseDb {
|
||||
await this.execute(sql, [this.workspace, context, account, ...values], 'update notification context')
|
||||
}
|
||||
|
||||
async findContexts(params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
async findContexts (params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
const withNotifications = params.notifications != null
|
||||
const withMessages = params.notifications?.message === true
|
||||
|
||||
@@ -434,7 +434,7 @@ export class NotificationsDb extends BaseDb {
|
||||
return result.map((it: any) => toNotificationContext(it))
|
||||
}
|
||||
|
||||
async findNotifications(params: FindNotificationsParams): Promise<Notification[]> {
|
||||
async findNotifications (params: FindNotificationsParams): Promise<Notification[]> {
|
||||
const withMessage = params.message === true
|
||||
|
||||
let select =
|
||||
@@ -513,14 +513,14 @@ export class NotificationsDb extends BaseDb {
|
||||
return result.map((it: any) => toNotification(it))
|
||||
}
|
||||
|
||||
async updateCollaborators(params: FindCollaboratorsParams, data: Partial<Collaborator>): Promise<void> {
|
||||
async updateCollaborators (params: FindCollaboratorsParams, data: Partial<Collaborator>): Promise<void> {
|
||||
const dbData: Partial<CollaboratorDb> = {
|
||||
account: data.account,
|
||||
card_id: data.card,
|
||||
card_type: data.cardType
|
||||
}
|
||||
|
||||
const entries = Object.entries(dbData).filter(([_, value]) => value != undefined)
|
||||
const entries = Object.entries(dbData).filter(([_, value]) => value != null)
|
||||
if (entries.length === 0) return
|
||||
|
||||
entries.unshift(['workspace_id', this.workspace])
|
||||
@@ -535,7 +535,8 @@ export class NotificationsDb extends BaseDb {
|
||||
|
||||
await this.execute(sql, [...setValues, ...whereValues], 'update collaborators')
|
||||
}
|
||||
async findCollaborators(params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
|
||||
async findCollaborators (params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
const { where, values } = this.buildCollaboratorsWhere(params)
|
||||
const select = `
|
||||
SELECT *
|
||||
@@ -552,11 +553,11 @@ export class NotificationsDb extends BaseDb {
|
||||
return result.map((it: any) => toCollaborator(it))
|
||||
}
|
||||
|
||||
private buildCollaboratorsWhere(
|
||||
private buildCollaboratorsWhere (
|
||||
params: FindCollaboratorsParams,
|
||||
startIndex: number = 0,
|
||||
prefix: string = 'c.'
|
||||
): { where: string; values: any[] } {
|
||||
): { where: string, values: any[] } {
|
||||
const where: string[] = []
|
||||
const values: any[] = []
|
||||
let index = startIndex + 1
|
||||
@@ -580,7 +581,7 @@ export class NotificationsDb extends BaseDb {
|
||||
return { where: `WHERE ${where.join(' AND ')}`, values }
|
||||
}
|
||||
|
||||
private buildContextWhere(params: FindNotificationContextParams): {
|
||||
private buildContextWhere (params: FindNotificationContextParams): {
|
||||
where: string
|
||||
values: any[]
|
||||
index: number
|
||||
@@ -627,14 +628,14 @@ export class NotificationsDb extends BaseDb {
|
||||
return { where: `WHERE ${where.join(' AND ')}`, values, index }
|
||||
}
|
||||
|
||||
private buildNotificationWhere(
|
||||
private buildNotificationWhere (
|
||||
params: FindNotificationsParams,
|
||||
initialIndex?: number,
|
||||
skipWorkspace?: boolean
|
||||
): {
|
||||
where: string
|
||||
values: any[]
|
||||
} {
|
||||
where: string
|
||||
values: any[]
|
||||
} {
|
||||
const where: string[] = skipWorkspace === true ? [] : ['nc.workspace_id = $1::uuid']
|
||||
const values: any[] = skipWorkspace === true ? [] : [this.workspace]
|
||||
let index = (initialIndex ?? 0) + values.length + 1
|
||||
|
||||
@@ -29,9 +29,10 @@ import {
|
||||
type CardType,
|
||||
type BlobMetadata,
|
||||
type LinkPreviewImage,
|
||||
type LinkPreviewID
|
||||
type LinkPreviewID,
|
||||
NotificationContent,
|
||||
NotificationType
|
||||
} from '@hcengineering/communication-types'
|
||||
import type { NotificationContent, NotificationType } from '@hcengineering/communication-types'
|
||||
|
||||
export enum TableName {
|
||||
File = 'communication.files',
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
export function getCondition(
|
||||
export function getCondition (
|
||||
table: string,
|
||||
dbField: string,
|
||||
startIndex: number,
|
||||
param: any,
|
||||
type: string
|
||||
): { where: string; values: any[]; index: number } | undefined {
|
||||
): { where: string, values: any[], index: number } | undefined {
|
||||
const conditions: string[] = []
|
||||
const values: any[] = []
|
||||
let index = startIndex
|
||||
|
||||
@@ -15,19 +15,21 @@
|
||||
|
||||
import type postgres from 'postgres'
|
||||
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
|
||||
const migrationsTableName = 'communication._migrations'
|
||||
|
||||
let isSchemaInitialized = false
|
||||
let initPromise: Promise<void> | null = null
|
||||
|
||||
export function isInitialized(): boolean {
|
||||
export function isInitialized (): boolean {
|
||||
return isSchemaInitialized
|
||||
}
|
||||
|
||||
export async function initSchema(sql: postgres.Sql): Promise<void> {
|
||||
export async function initSchema (sql: postgres.Sql): Promise<void> {
|
||||
if (isInitialized()) return
|
||||
|
||||
if (!initPromise) {
|
||||
if (initPromise == null) {
|
||||
initPromise = (async () => {
|
||||
const maxAttempts = 3
|
||||
const retryDelay = 3000
|
||||
@@ -57,11 +59,11 @@ export async function initSchema(sql: postgres.Sql): Promise<void> {
|
||||
await initPromise
|
||||
}
|
||||
|
||||
function delay(ms: number): Promise<void> {
|
||||
return new Promise((res) => setTimeout(res, ms))
|
||||
function delay (ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
async function init(sql: postgres.Sql) {
|
||||
async function init (sql: postgres.Sql): Promise<void> {
|
||||
if (isSchemaInitialized) return
|
||||
const start = performance.now()
|
||||
console.log('🗃️ Initializing schema...')
|
||||
@@ -99,7 +101,7 @@ async function init(sql: postgres.Sql) {
|
||||
console.log(`🎉 All migrations complete in ${resTime.toFixed(2)} sec`)
|
||||
}
|
||||
|
||||
function getMigrations(): [string, string][] {
|
||||
function getMigrations (): [string, string][] {
|
||||
return [
|
||||
migrationV1_1(),
|
||||
migrationV1_2(),
|
||||
@@ -115,7 +117,7 @@ function getMigrations(): [string, string][] {
|
||||
]
|
||||
}
|
||||
|
||||
function migrationV1_1(): [string, string] {
|
||||
function migrationV1_1 (): [string, string] {
|
||||
const sql = `
|
||||
DROP SCHEMA IF EXISTS communication CASCADE;
|
||||
CREATE SCHEMA IF NOT EXISTS communication;
|
||||
@@ -130,7 +132,7 @@ function migrationV1_1(): [string, string] {
|
||||
return ['recreate_schema-v1_1', sql]
|
||||
}
|
||||
|
||||
function migrationV1_2(): [string, string] {
|
||||
function migrationV1_2 (): [string, string] {
|
||||
const sql = `
|
||||
CREATE TABLE IF NOT EXISTS communication.messages
|
||||
(
|
||||
@@ -280,7 +282,7 @@ function migrationV1_2(): [string, string] {
|
||||
return ['reinit_tables-v1_2', sql]
|
||||
}
|
||||
|
||||
function migrationV2_1(): [string, string] {
|
||||
function migrationV2_1 (): [string, string] {
|
||||
const sql = `
|
||||
ALTER TABLE communication.notifications
|
||||
ADD COLUMN IF NOT EXISTS type VARCHAR(255) NOT NULL DEFAULT 'message';
|
||||
@@ -288,7 +290,7 @@ function migrationV2_1(): [string, string] {
|
||||
return ['add_type_column_to_notifications-v2_1', sql]
|
||||
}
|
||||
|
||||
function migrationV2_2(): [string, string] {
|
||||
function migrationV2_2 (): [string, string] {
|
||||
const sql = `
|
||||
ALTER TABLE communication.notifications
|
||||
ADD COLUMN IF NOT EXISTS read BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -296,12 +298,12 @@ function migrationV2_2(): [string, string] {
|
||||
return ['add_read_column_to_notifications-v2_2', sql]
|
||||
}
|
||||
|
||||
function migrationV2_3(): [string, string] {
|
||||
const sql = `UPDATE communication.notifications SET read = true; `
|
||||
function migrationV2_3 (): [string, string] {
|
||||
const sql = 'UPDATE communication.notifications SET read = true; '
|
||||
return ['set_read_to_true-v2_3', sql]
|
||||
}
|
||||
|
||||
function migrationV2_4(): [string, string] {
|
||||
function migrationV2_4 (): [string, string] {
|
||||
const sql = `
|
||||
ALTER TABLE communication.notifications
|
||||
ADD COLUMN IF NOT EXISTS message_created TIMESTAMPTZ;
|
||||
@@ -309,7 +311,7 @@ function migrationV2_4(): [string, string] {
|
||||
return ['add_message_created_column_to_notifications-v2_4', sql]
|
||||
}
|
||||
|
||||
function migrationV2_5(): [string, string] {
|
||||
function migrationV2_5 (): [string, string] {
|
||||
const sql = `
|
||||
UPDATE communication.notifications
|
||||
SET message_created = created;
|
||||
@@ -320,7 +322,7 @@ function migrationV2_5(): [string, string] {
|
||||
return ['init_and_set_not_null_message_created_notifications-v2_4', sql]
|
||||
}
|
||||
|
||||
function migrationV2_6(): [string, string] {
|
||||
function migrationV2_6 (): [string, string] {
|
||||
const sql = `
|
||||
ALTER TABLE communication.notification_context
|
||||
ADD COLUMN IF NOT EXISTS last_notify TIMESTAMPTZ;
|
||||
@@ -328,7 +330,7 @@ function migrationV2_6(): [string, string] {
|
||||
return ['add_last_notify_column_to_notification_context-v2_6', sql]
|
||||
}
|
||||
|
||||
function migrationV2_7(): [string, string] {
|
||||
function migrationV2_7 (): [string, string] {
|
||||
const sql = `
|
||||
UPDATE communication.notification_context
|
||||
SET last_notify = last_update;`
|
||||
@@ -336,7 +338,7 @@ function migrationV2_7(): [string, string] {
|
||||
return ['set_last_notify_to_last_update-v2_7', sql]
|
||||
}
|
||||
|
||||
function migrationV3_1(): [string, string] {
|
||||
function migrationV3_1 (): [string, string] {
|
||||
const sql = `
|
||||
CREATE TABLE IF NOT EXISTS communication.link_preview
|
||||
(
|
||||
@@ -363,7 +365,7 @@ function migrationV3_1(): [string, string] {
|
||||
return ['init_link_preview-v3_1', sql]
|
||||
}
|
||||
|
||||
function migrationV4_1(): [string, string] {
|
||||
function migrationV4_1 (): [string, string] {
|
||||
const sql = `
|
||||
CREATE INDEX IF NOT EXISTS notifications_context_id_read_created_desc_idx ON communication.notifications (context_id, read, created DESC);
|
||||
`
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
export function injectVars(sql: string, values: any[]): string {
|
||||
export function injectVars (sql: string, values: any[]): string {
|
||||
return sql.replaceAll(/(\$\d+)/g, (_, idx) => {
|
||||
return escape(values[parseInt(idx.substring(1)) - 1])
|
||||
})
|
||||
}
|
||||
|
||||
function escape(value: any): string {
|
||||
function escape (value: any): string {
|
||||
if (value === null || value === undefined) {
|
||||
return 'NULL'
|
||||
}
|
||||
@@ -53,7 +53,7 @@ function escape(value: any): string {
|
||||
}
|
||||
}
|
||||
|
||||
export function convertArrayParams(params?: unknown[]): any[] | undefined {
|
||||
export function convertArrayParams (params?: unknown[]): any[] | undefined {
|
||||
if (params === undefined) return undefined
|
||||
|
||||
return params.map((param) => {
|
||||
@@ -83,14 +83,14 @@ export function convertArrayParams(params?: unknown[]): any[] | undefined {
|
||||
}
|
||||
|
||||
const SEP = ','
|
||||
function getFirstName(name: string): string {
|
||||
function getFirstName (name: string): string {
|
||||
return name !== undefined ? name.substring(name.indexOf(SEP) + 1) : ''
|
||||
}
|
||||
|
||||
function getLastName(name: string): string {
|
||||
function getLastName (name: string): string {
|
||||
return name !== undefined ? name.substring(0, name.indexOf(SEP)) : ''
|
||||
}
|
||||
|
||||
export function formatName(name: string): string {
|
||||
export function formatName (name: string): string {
|
||||
return getFirstName(name) + ' ' + getLastName(name)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declarationDir": "./types",
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "lib", "dist", "types", "bundle"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
||||
+38
-21
@@ -1,42 +1,59 @@
|
||||
{
|
||||
"name": "@hcengineering/communication-query",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"dist/index.js",
|
||||
"dist/index.cjs",
|
||||
"types/**/*.d.ts"
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "bun run build:types && bun run build:browser",
|
||||
"build:types": "tsc --project ./tsconfig.json --emitDeclarationOnly --declarationDir ./types",
|
||||
"build:browser": "bun build src/index.ts --outdir dist --target browser",
|
||||
"lint": "eslint src/*.ts",
|
||||
"format": "prettier --write src/**/*.ts ",
|
||||
"clean": "rm -rf dist && rm -rf types && rm -rf .turbo"
|
||||
"build": "compile",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:validate": "compile validate",
|
||||
|
||||
"lint": "eslint \"src/**/*.ts\"",
|
||||
"lint:fix": "eslint --fix \"src/**/*.ts\"",
|
||||
"format": "prettier --write src/**/*.ts && eslint --fix \"src/**/*.ts\"",
|
||||
"clean": "rm -rf lib && rm -rf types rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
"@types/crypto-js": "^4.2.2"
|
||||
"@hcengineering/platform-rig": "^0.6.490",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"esbuild-plugin-copy": "~2.1.1",
|
||||
"eslint": "^8.54.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-shared": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/communication-yaml": "workspace:*",
|
||||
"@hcengineering/communication-sdk-types": "^0.1.0",
|
||||
"@hcengineering/communication-shared": "^0.1.0",
|
||||
"@hcengineering/communication-types": "^0.1.0",
|
||||
"@hcengineering/communication-yaml": "^0.1.0",
|
||||
"fast-equals": "^5.0.1",
|
||||
"uuid": "^11.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/hcengineering/communication.git"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/index.d.ts",
|
||||
"require": "./lib/index.js",
|
||||
"import": "./lib/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
import { QueryResult } from '../result'
|
||||
import { type Query, type QueryId } from '../types'
|
||||
|
||||
function getId(label: Label): string {
|
||||
function getId (label: Label): string {
|
||||
return `${label.label}:${label.card}:${label.account}`
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
private result: Promise<QueryResult<Label>> | QueryResult<Label>
|
||||
private isCardRemoved = false
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly client: FindClient,
|
||||
private readonly workspace: WorkspaceID,
|
||||
private readonly filesUrl: string,
|
||||
@@ -56,7 +56,7 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async onEvent(event: ResponseEvent): Promise<void> {
|
||||
async onEvent (event: ResponseEvent): Promise<void> {
|
||||
if (this.isCardRemoved) return
|
||||
switch (event.type) {
|
||||
case LabelResponseEventType.LabelCreated:
|
||||
@@ -75,19 +75,19 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async onLabelCreated(event: LabelCreatedEvent): Promise<void> {
|
||||
async onLabelCreated (event: LabelCreatedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
if (this.params.limit && this.result.length >= this.params.limit) return
|
||||
if (this.params.limit != null && this.result.length >= this.params.limit) return
|
||||
|
||||
const match = this.match(event.label)
|
||||
if (!match) return
|
||||
const existing = this.result.get(getId(event.label))
|
||||
if (existing) return
|
||||
if (existing != null) return
|
||||
this.result.push(event.label)
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
async onLabelRemoved(event: LabelRemovedEvent): Promise<void> {
|
||||
async onLabelRemoved (event: LabelRemovedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
const existing = this.result
|
||||
@@ -97,7 +97,7 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
const prevLength = this.result.length
|
||||
this.result.delete(getId(existing))
|
||||
|
||||
if (this.params.limit && this.result.length < this.params.limit && prevLength >= this.params.limit) {
|
||||
if (this.params.limit != null && this.result.length < this.params.limit && prevLength >= this.params.limit) {
|
||||
const labels = await this.find(this.params)
|
||||
this.result = new QueryResult(labels, getId)
|
||||
}
|
||||
@@ -105,7 +105,7 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
async onCardTypeUpdated(event: CardTypeUpdatedEvent): Promise<void> {
|
||||
async onCardTypeUpdated (event: CardTypeUpdatedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
const result = this.result.getResult()
|
||||
@@ -123,7 +123,7 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
}
|
||||
|
||||
for (const label of result) {
|
||||
if (label.card == event.card) {
|
||||
if (label.card === event.card) {
|
||||
const updatedLabel: Label = { ...label, cardType: event.cardType }
|
||||
const matched = this.match(updatedLabel)
|
||||
if (matched) {
|
||||
@@ -137,7 +137,7 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
|
||||
if (updated) {
|
||||
const newLength = this.result.length
|
||||
if (this.params.limit && newLength < currentLength && newLength >= this.params.limit) {
|
||||
if (this.params.limit != null && newLength < currentLength && newLength >= this.params.limit) {
|
||||
const labels = await this.find(this.params)
|
||||
this.result = new QueryResult(labels, getId)
|
||||
}
|
||||
@@ -146,7 +146,7 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async onCardRemoved(event: CardRemovedEvent): Promise<void> {
|
||||
async onCardRemoved (event: CardRemovedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
if (this.params.card === event.card) {
|
||||
@@ -160,23 +160,24 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
const prevLength = this.result.length
|
||||
let deleted = false
|
||||
for (const label of result) {
|
||||
if (label.card == event.card) {
|
||||
if (label.card === event.card) {
|
||||
this.result.delete(label.label)
|
||||
deleted = true
|
||||
}
|
||||
}
|
||||
|
||||
if (deleted) {
|
||||
if (this.params.limit && this.result.length < this.params.limit && prevLength >= this.params.limit) {
|
||||
if (this.params.limit != null && this.result.length < this.params.limit && prevLength >= this.params.limit) {
|
||||
const labels = await this.find(this.params)
|
||||
this.result = new QueryResult(labels, getId)
|
||||
}
|
||||
void this.notify()
|
||||
}
|
||||
}
|
||||
async onRequest(event: RequestEvent, promise: Promise<EventResult>): Promise<void> {}
|
||||
|
||||
private async initResult(): Promise<QueryResult<Label>> {
|
||||
async onRequest (event: RequestEvent, promise: Promise<EventResult>): Promise<void> {}
|
||||
|
||||
private async initResult (): Promise<QueryResult<Label>> {
|
||||
try {
|
||||
const res = await this.find(this.params)
|
||||
const result = new QueryResult(res, getId)
|
||||
@@ -189,20 +190,20 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async unsubscribe(): Promise<void> {
|
||||
async unsubscribe (): Promise<void> {
|
||||
await this.client.unsubscribeQuery(this.id)
|
||||
}
|
||||
|
||||
removeCallback(): void {
|
||||
removeCallback (): void {
|
||||
this.callback = () => {}
|
||||
}
|
||||
|
||||
setCallback(callback: QueryCallback<Label>): void {
|
||||
setCallback (callback: QueryCallback<Label>): void {
|
||||
this.callback = callback
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
copyResult(): QueryResult<Label> | undefined {
|
||||
copyResult (): QueryResult<Label> | undefined {
|
||||
if (this.result instanceof Promise) {
|
||||
return undefined
|
||||
}
|
||||
@@ -210,19 +211,19 @@ export class LabelsQuery implements Query<Label, FindLabelsParams> {
|
||||
return this.result.copy()
|
||||
}
|
||||
|
||||
private async find(params: FindLabelsParams): Promise<Label[]> {
|
||||
private async find (params: FindLabelsParams): Promise<Label[]> {
|
||||
if (this.isCardRemoved) return []
|
||||
return await this.client.findLabels(params, this.id)
|
||||
}
|
||||
|
||||
private async notify(): Promise<void> {
|
||||
private async notify (): Promise<void> {
|
||||
if (this.callback == null) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
const result = this.result.getResult()
|
||||
this.callback(result)
|
||||
}
|
||||
|
||||
private match(label: Label): boolean {
|
||||
private match (label: Label): boolean {
|
||||
if (this.params.account != null && this.params.account !== label.account) {
|
||||
return false
|
||||
}
|
||||
|
||||
+17
-17
@@ -51,7 +51,7 @@ export class LiveQueries {
|
||||
private readonly unsubscribed = new Set<QueryId>()
|
||||
private counter: number = 0
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly client: FindClient,
|
||||
private readonly workspace: WorkspaceID,
|
||||
private readonly filesUrl: string
|
||||
@@ -64,19 +64,19 @@ export class LiveQueries {
|
||||
}
|
||||
}
|
||||
|
||||
async onEvent(event: ResponseEvent): Promise<void> {
|
||||
async onEvent (event: ResponseEvent): Promise<void> {
|
||||
for (const q of this.queries.values()) {
|
||||
void q.onEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
async onRequest(event: RequestEvent, promise: Promise<EventResult>): Promise<void> {
|
||||
async onRequest (event: RequestEvent, promise: Promise<EventResult>): Promise<void> {
|
||||
for (const q of this.queries.values()) {
|
||||
void q.onRequest(event, promise)
|
||||
}
|
||||
}
|
||||
|
||||
queryMessages(params: MessageQueryParams, callback: PagedQueryCallback<Message>): CreateQueryResult {
|
||||
queryMessages (params: MessageQueryParams, callback: PagedQueryCallback<Message>): CreateQueryResult {
|
||||
return this.createAndStoreQuery<Message, FindMessagesParams, MessagesQuery>(
|
||||
params,
|
||||
callback,
|
||||
@@ -85,7 +85,7 @@ export class LiveQueries {
|
||||
)
|
||||
}
|
||||
|
||||
queryNotifications(params: FindNotificationsParams, callback: PagedQueryCallback<Notification>): CreateQueryResult {
|
||||
queryNotifications (params: FindNotificationsParams, callback: PagedQueryCallback<Notification>): CreateQueryResult {
|
||||
return this.createAndStoreQuery<Notification, FindNotificationsParams, NotificationQuery>(
|
||||
params,
|
||||
callback,
|
||||
@@ -94,7 +94,7 @@ export class LiveQueries {
|
||||
)
|
||||
}
|
||||
|
||||
queryNotificationContexts(params: FindNotificationContextParams, callback: any): CreateQueryResult {
|
||||
queryNotificationContexts (params: FindNotificationContextParams, callback: any): CreateQueryResult {
|
||||
return this.createAndStoreQuery<NotificationContext, FindNotificationContextParams, NotificationContextsQuery>(
|
||||
params,
|
||||
callback,
|
||||
@@ -103,7 +103,7 @@ export class LiveQueries {
|
||||
)
|
||||
}
|
||||
|
||||
queryLabels(params: FindLabelsParams, callback: any): CreateQueryResult {
|
||||
queryLabels (params: FindLabelsParams, callback: any): CreateQueryResult {
|
||||
return this.createAndStoreQuery<Label, FindLabelsParams, LabelsQuery>(params, callback, LabelsQuery, (params) =>
|
||||
this.findLabelsQuery(params)
|
||||
)
|
||||
@@ -151,32 +151,32 @@ export class LiveQueries {
|
||||
private findQuery<T extends AnyQuery>(params: FindParams, QueryClass: new (...args: any[]) => T): T | undefined {
|
||||
for (const query of this.queries.values()) {
|
||||
if (query instanceof QueryClass && this.queryCompare(params, query.params)) {
|
||||
return query as T
|
||||
return query
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private findMessagesQuery(params: FindMessagesParams): MessagesQuery | undefined {
|
||||
private findMessagesQuery (params: FindMessagesParams): MessagesQuery | undefined {
|
||||
return this.findQuery(params, MessagesQuery)
|
||||
}
|
||||
|
||||
private findNotificationQuery(params: FindNotificationsParams): NotificationQuery | undefined {
|
||||
private findNotificationQuery (params: FindNotificationsParams): NotificationQuery | undefined {
|
||||
return this.findQuery(params, NotificationQuery)
|
||||
}
|
||||
|
||||
private findNotificationContextsQuery(params: FindNotificationContextParams): NotificationContextsQuery | undefined {
|
||||
private findNotificationContextsQuery (params: FindNotificationContextParams): NotificationContextsQuery | undefined {
|
||||
return this.findQuery(params, NotificationContextsQuery)
|
||||
}
|
||||
|
||||
private findLabelsQuery(params: FindLabelsParams): LabelsQuery | undefined {
|
||||
private findLabelsQuery (params: FindLabelsParams): LabelsQuery | undefined {
|
||||
return this.findQuery(params, LabelsQuery)
|
||||
}
|
||||
|
||||
private queryCompare(q1: FindParams, q2: FindParams): boolean {
|
||||
private queryCompare (q1: FindParams, q2: FindParams): boolean {
|
||||
return Object.keys(q1).length === Object.keys(q2).length && deepEqual(q1, q2)
|
||||
}
|
||||
|
||||
private removeOldQueries(): void {
|
||||
private removeOldQueries (): void {
|
||||
const unsubscribed = Array.from(this.unsubscribed)
|
||||
for (let i = 0; i < this.unsubscribed.size / 2; i++) {
|
||||
const id = unsubscribed.shift()
|
||||
@@ -185,7 +185,7 @@ export class LiveQueries {
|
||||
}
|
||||
}
|
||||
|
||||
private unsubscribe(id: QueryId): void {
|
||||
private unsubscribe (id: QueryId): void {
|
||||
const query = this.queries.get(id)
|
||||
if (query == null) return
|
||||
void query.unsubscribe()
|
||||
@@ -193,7 +193,7 @@ export class LiveQueries {
|
||||
this.unsubscribed.delete(id)
|
||||
}
|
||||
|
||||
private unsubscribeQuery(query: AnyQuery): void {
|
||||
private unsubscribeQuery (query: AnyQuery): void {
|
||||
this.unsubscribed.add(query.id)
|
||||
query.removeCallback()
|
||||
if (this.unsubscribed.size > maxQueriesCache) {
|
||||
@@ -201,7 +201,7 @@ export class LiveQueries {
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {
|
||||
close (): void {
|
||||
this.queries.clear()
|
||||
this.unsubscribed.clear()
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ import {
|
||||
type QueryId
|
||||
} from '../types'
|
||||
import { WindowImpl } from '../window'
|
||||
import { addFile, addLinkPreview, addReaction, removeFile, removeLinkPreview, removeReaction } from '../utils.ts'
|
||||
import { addFile, addLinkPreview, addReaction, removeFile, removeLinkPreview, removeReaction } from '../utils'
|
||||
|
||||
const GROUPS_LIMIT = 4
|
||||
|
||||
@@ -96,15 +96,15 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
buffer: [] as Message[]
|
||||
}
|
||||
|
||||
private createdFiles: Map<MessageID, File[]> = new Map()
|
||||
private createdReactions: Map<MessageID, Reaction[]> = new Map()
|
||||
private createdLinkPreviews: Map<MessageID, LinkPreview[]> = new Map()
|
||||
private createdPatches: Map<MessageID, Patch[]> = new Map()
|
||||
private readonly createdFiles = new Map<MessageID, File[]>()
|
||||
private readonly createdReactions = new Map<MessageID, Reaction[]>()
|
||||
private readonly createdLinkPreviews = new Map<MessageID, LinkPreview[]>()
|
||||
private readonly createdPatches = new Map<MessageID, Patch[]>()
|
||||
|
||||
private readonly tmpMessages = new Map<string, MessageID>()
|
||||
private isCardRemoved = false
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly client: FindClient,
|
||||
private readonly workspace: WorkspaceID,
|
||||
private readonly filesUrl: string,
|
||||
@@ -152,7 +152,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async onEvent(event: ResponseEvent): Promise<void> {
|
||||
async onEvent (event: ResponseEvent): Promise<void> {
|
||||
if (this.isCardRemoved) return
|
||||
switch (event.type) {
|
||||
case MessageResponseEventType.MessageCreated: {
|
||||
@@ -196,7 +196,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async onCardRemoved(event: CardRemovedEvent): Promise<void> {
|
||||
async onCardRemoved (event: CardRemovedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
if (this.params.card === event.card) {
|
||||
this.isCardRemoved = true
|
||||
@@ -220,7 +220,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async onRequest(event: RequestEvent, promise: Promise<EventResult>): Promise<void> {
|
||||
async onRequest (event: RequestEvent, promise: Promise<EventResult>): Promise<void> {
|
||||
if (this.isCardRemoved) return
|
||||
switch (event.type) {
|
||||
case MessageRequestEventType.CreateMessage: {
|
||||
@@ -230,7 +230,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async onCreateMessageRequest(event: CreateMessageEvent, promise: Promise<CreateMessageResult>): Promise<void> {
|
||||
async onCreateMessageRequest (event: CreateMessageEvent, promise: Promise<CreateMessageResult>): Promise<void> {
|
||||
if (this.params.card !== event.card) return
|
||||
const eventId = event._id
|
||||
if (eventId == null) return
|
||||
@@ -291,7 +291,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
private insertMessage(result: QueryResult<Message>, message: Message): void {
|
||||
private insertMessage (result: QueryResult<Message>, message: Message): void {
|
||||
if (this.params.order === SortingOrder.Ascending) {
|
||||
result.push(message)
|
||||
} else {
|
||||
@@ -299,11 +299,11 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async unsubscribe(): Promise<void> {
|
||||
async unsubscribe (): Promise<void> {
|
||||
await this.client.unsubscribeQuery(this.id)
|
||||
}
|
||||
|
||||
async requestLoadNextPage(): Promise<void> {
|
||||
async requestLoadNextPage (): Promise<void> {
|
||||
if (this.isCardRemoved) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
@@ -318,7 +318,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
async requestLoadPrevPage(): Promise<void> {
|
||||
async requestLoadPrevPage (): Promise<void> {
|
||||
if (this.isCardRemoved) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
if (!this.result.isHead()) {
|
||||
@@ -332,16 +332,16 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
removeCallback(): void {
|
||||
removeCallback (): void {
|
||||
this.callback = () => {}
|
||||
}
|
||||
|
||||
setCallback(callback: PagedQueryCallback<Message>): void {
|
||||
setCallback (callback: PagedQueryCallback<Message>): void {
|
||||
this.callback = callback
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
copyResult(): QueryResult<Message> | undefined {
|
||||
copyResult (): QueryResult<Message> | undefined {
|
||||
if (this.result instanceof Promise) {
|
||||
return undefined
|
||||
}
|
||||
@@ -349,7 +349,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return this.result.copy()
|
||||
}
|
||||
|
||||
private isInitLoadingForward(): boolean {
|
||||
private isInitLoadingForward (): boolean {
|
||||
const { order } = this.params
|
||||
|
||||
if (this.isOneMessageQuery(this.params)) {
|
||||
@@ -359,7 +359,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return order === SortingOrder.Ascending
|
||||
}
|
||||
|
||||
private async loadPage(direction: Direction, result: QueryResult<Message>): Promise<QueryResult<Message>> {
|
||||
private async loadPage (direction: Direction, result: QueryResult<Message>): Promise<QueryResult<Message>> {
|
||||
const { messages, fromDb } =
|
||||
direction === Direction.Forward ? await this.loadNextMessages(result) : await this.loadPrevMessages(result)
|
||||
|
||||
@@ -393,7 +393,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
|
||||
// Load next
|
||||
private async loadNextMessages(result: QueryResult<Message>): Promise<{ messages: Message[]; fromDb: boolean }> {
|
||||
private async loadNextMessages (result: QueryResult<Message>): Promise<{ messages: Message[], fromDb: boolean }> {
|
||||
const messages: Message[] = this.next.buffer.splice(0, this.limit)
|
||||
if (messages.length >= this.limit) return { messages, fromDb: false }
|
||||
|
||||
@@ -411,7 +411,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return { messages, fromDb: dbMessages.length > 0 }
|
||||
}
|
||||
|
||||
private async findNextMessages(limit: number, result: QueryResult<Message>): Promise<Message[]> {
|
||||
private async findNextMessages (limit: number, result: QueryResult<Message>): Promise<Message[]> {
|
||||
if (this.next.hasGroups) {
|
||||
return []
|
||||
}
|
||||
@@ -436,9 +436,9 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
|
||||
// Load prev
|
||||
private async loadPrevMessages(
|
||||
private async loadPrevMessages (
|
||||
result: QueryResult<Message>
|
||||
): Promise<{ messages: Message[]; fromDb: boolean; hasNext?: boolean }> {
|
||||
): Promise<{ messages: Message[], fromDb: boolean, hasNext?: boolean }> {
|
||||
const messages: Message[] = []
|
||||
const prevBuffer = this.prev.buffer
|
||||
const last = prevBuffer[prevBuffer.length - 1]
|
||||
@@ -482,7 +482,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return { messages, fromDb: false }
|
||||
}
|
||||
|
||||
private async findPrevMessages(limit: number, result: QueryResult<Message>): Promise<Message[]> {
|
||||
private async findPrevMessages (limit: number, result: QueryResult<Message>): Promise<Message[]> {
|
||||
if (!this.prev.hasMessages || result.isHead()) return []
|
||||
|
||||
const first = this.params.order === SortingOrder.Ascending ? result.getFirst() : result.getLast()
|
||||
@@ -502,7 +502,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
})
|
||||
}
|
||||
|
||||
getLoadGroupsParams(direction: Direction): Pick<FindMessagesGroupsParams, 'fromDate' | 'toDate'> | undefined {
|
||||
getLoadGroupsParams (direction: Direction): Pick<FindMessagesGroupsParams, 'fromDate' | 'toDate'> | undefined {
|
||||
if (direction === Direction.Forward) {
|
||||
if (this.lastGroup != null) {
|
||||
return {
|
||||
@@ -542,7 +542,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return undefined
|
||||
}
|
||||
|
||||
private async loadGroups(direction: Direction, result: QueryResult<Message>): Promise<void> {
|
||||
private async loadGroups (direction: Direction, result: QueryResult<Message>): Promise<void> {
|
||||
let messagesCount = 0
|
||||
const lastResult = result.getLast()
|
||||
const toLoad: MessagesGroup[] = []
|
||||
@@ -638,12 +638,12 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
private matchFileMessages(
|
||||
private matchFileMessages (
|
||||
file: ParsedFile,
|
||||
direction: Direction,
|
||||
queryResult: QueryResult<Message>,
|
||||
filterDate?: Date
|
||||
): { next: Message[]; prev: Message[] } {
|
||||
): { next: Message[], prev: Message[] } {
|
||||
let result: Message[] = file.messages
|
||||
const params = this.params
|
||||
if (this.isOneMessageQuery(params)) {
|
||||
@@ -687,7 +687,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return { next: nextResult, prev: prevResult }
|
||||
}
|
||||
|
||||
private async loadMessagesFromFiles(group: MessagesGroup): Promise<ParsedFile> {
|
||||
private async loadMessagesFromFiles (group: MessagesGroup): Promise<ParsedFile> {
|
||||
const parsedFile = await loadGroupFile(this.workspace, this.filesUrl, group, { retries: 5 })
|
||||
const patches = group.patches ?? []
|
||||
|
||||
@@ -701,13 +701,13 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
messages:
|
||||
patches.length > 0
|
||||
? parsedFile.messages.map((message) =>
|
||||
applyPatches(message, patchesMap.get(message.id) ?? [], this.allowedPatches())
|
||||
)
|
||||
applyPatches(message, patchesMap.get(message.id) ?? [], this.allowedPatches())
|
||||
)
|
||||
: parsedFile.messages
|
||||
}
|
||||
}
|
||||
|
||||
private async findGroupByDate(params: Date): Promise<MessagesGroup | undefined> {
|
||||
private async findGroupByDate (params: Date): Promise<MessagesGroup | undefined> {
|
||||
const groups = await this.client.findMessagesGroups({
|
||||
card: this.params.card,
|
||||
fromDate: { lessOrEqual: params },
|
||||
@@ -720,7 +720,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return groups[0]
|
||||
}
|
||||
|
||||
private async findGroups(
|
||||
private async findGroups (
|
||||
direction: Direction,
|
||||
date?: Pick<FindMessagesGroupsParams, 'fromDate' | 'toDate'>
|
||||
): Promise<MessagesGroup[]> {
|
||||
@@ -747,16 +747,16 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
})
|
||||
}
|
||||
|
||||
private async find(params: FindMessagesParams): Promise<Message[]> {
|
||||
private async find (params: FindMessagesParams): Promise<Message[]> {
|
||||
delete (params as any).from
|
||||
return await this.client.findMessages(params, this.id)
|
||||
}
|
||||
|
||||
private isOneMessageQuery(params: MessageQueryParams): params is OneMessageQueryParams {
|
||||
private isOneMessageQuery (params: MessageQueryParams): params is OneMessageQueryParams {
|
||||
return 'id' in this.params && this.params.id != null
|
||||
}
|
||||
|
||||
private async notify(): Promise<void> {
|
||||
private async notify (): Promise<void> {
|
||||
this.initialized = true
|
||||
if (this.callback == null) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
@@ -764,7 +764,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
this.callback(new WindowImpl(result, this.result.isTail(), this.result.isHead(), this))
|
||||
}
|
||||
|
||||
private match(message: Message): boolean {
|
||||
private match (message: Message): boolean {
|
||||
if (this.isOneMessageQuery(this.params) && this.params.id !== message.id) {
|
||||
return false
|
||||
}
|
||||
@@ -774,7 +774,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return true
|
||||
}
|
||||
|
||||
private async onThreadCreatedEvent(event: ThreadCreatedEvent): Promise<void> {
|
||||
private async onThreadCreatedEvent (event: ThreadCreatedEvent): Promise<void> {
|
||||
if (this.params.replies !== true) return
|
||||
if (this.params.card !== event.thread.card) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
@@ -810,7 +810,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
})
|
||||
}
|
||||
|
||||
private fillMessage(origin: Message): Message {
|
||||
private fillMessage (origin: Message): Message {
|
||||
let message = origin
|
||||
if (this.params.files === true) {
|
||||
message.files = this.createdFiles.get(message.id) ?? []
|
||||
@@ -826,7 +826,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return message
|
||||
}
|
||||
|
||||
private async onMessageCreatedEvent(event: MessageCreatedEvent): Promise<void> {
|
||||
private async onMessageCreatedEvent (event: MessageCreatedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
if (this.params.card !== event.message.card) return
|
||||
let message = event.message
|
||||
@@ -850,7 +850,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
const lastMessage = this.result.getLast()
|
||||
const firstMessage = this.result.getFirst()
|
||||
|
||||
function shouldResort(order: SortingOrder): boolean {
|
||||
function shouldResort (order: SortingOrder): boolean {
|
||||
if (firstMessage == null || lastMessage == null) return false
|
||||
if (order === SortingOrder.Ascending) {
|
||||
return lastMessage.created > message.created
|
||||
@@ -875,14 +875,14 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
this.cleanCache(message.id)
|
||||
}
|
||||
|
||||
private cleanCache(message: MessageID): void {
|
||||
private cleanCache (message: MessageID): void {
|
||||
this.createdFiles.delete(message)
|
||||
this.createdReactions.delete(message)
|
||||
this.createdLinkPreviews.delete(message)
|
||||
this.createdPatches.delete(message)
|
||||
}
|
||||
|
||||
private async onPatchCreatedEvent(event: PatchCreatedEvent): Promise<void> {
|
||||
private async onPatchCreatedEvent (event: PatchCreatedEvent): Promise<void> {
|
||||
if (this.params.card !== event.card) return
|
||||
if (!this.isAllowedPatch(event.patch.type)) return
|
||||
const current = this.createdPatches.get(event.patch.message) ?? []
|
||||
@@ -908,7 +908,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
private async onReactionCreatedEvent(event: ReactionCreatedEvent): Promise<void> {
|
||||
private async onReactionCreatedEvent (event: ReactionCreatedEvent): Promise<void> {
|
||||
if (this.params.reactions !== true || this.params.card !== event.card) return
|
||||
const current = this.createdReactions.get(event.message) ?? []
|
||||
this.createdReactions.set(event.message, [...current, event.reaction])
|
||||
@@ -935,7 +935,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
private async onReactionRemovedEvent(event: ReactionRemovedEvent): Promise<void> {
|
||||
private async onReactionRemovedEvent (event: ReactionRemovedEvent): Promise<void> {
|
||||
if (this.params.reactions !== true || this.params.card !== event.card) return
|
||||
const current = this.createdReactions.get(event.message) ?? []
|
||||
const reactions = current.filter((it) => it.reaction !== event.reaction || it.creator !== event.creator)
|
||||
@@ -958,7 +958,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
)
|
||||
}
|
||||
|
||||
private updateFilesCache(message: MessageID, files: File[]): void {
|
||||
private updateFilesCache (message: MessageID, files: File[]): void {
|
||||
const filesCache = this.createdFiles.get(message) ?? []
|
||||
this.createdFiles.set(message, filesCache)
|
||||
for (const file of files) {
|
||||
@@ -969,7 +969,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
private async onFileCreatedEvent(event: FileCreatedEvent): Promise<void> {
|
||||
private async onFileCreatedEvent (event: FileCreatedEvent): Promise<void> {
|
||||
if (this.params.files !== true || event.card !== this.params.card) return
|
||||
this.updateFilesCache(event.message, [event.file])
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
@@ -994,7 +994,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
private async onLinkPreviewCreatedEvent(event: LinkPreviewCreatedEvent): Promise<void> {
|
||||
private async onLinkPreviewCreatedEvent (event: LinkPreviewCreatedEvent): Promise<void> {
|
||||
if (this.params.links !== true || this.params.card !== event.card) return
|
||||
const current = this.createdLinkPreviews.get(event.message) ?? []
|
||||
this.createdLinkPreviews.set(event.message, [...current, event.linkPreview])
|
||||
@@ -1019,7 +1019,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
}
|
||||
}
|
||||
|
||||
private async onLinkPreviewRemovedEvent(event: LinkPreviewRemovedEvent): Promise<void> {
|
||||
private async onLinkPreviewRemovedEvent (event: LinkPreviewRemovedEvent): Promise<void> {
|
||||
if (this.params.links !== true || this.params.card !== event.card) return
|
||||
const current = this.createdLinkPreviews.get(event.message) ?? []
|
||||
const linkPreviews = current.filter((it) => it.id !== event.id)
|
||||
@@ -1042,7 +1042,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
this.prev.buffer = this.prev.buffer.map((it) => (it.id === event.message ? removeLinkPreview(it, event.id) : it))
|
||||
}
|
||||
|
||||
private async onFileRemovedEvent(event: FileRemovedEvent): Promise<void> {
|
||||
private async onFileRemovedEvent (event: FileRemovedEvent): Promise<void> {
|
||||
if (this.params.files !== true) return
|
||||
if (this.params.card !== event.card) return
|
||||
const current = this.createdFiles.get(event.message) ?? []
|
||||
@@ -1067,7 +1067,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
this.prev.buffer = this.prev.buffer.map((it) => (it.id === event.message ? removeFile(it, event.blobId) : it))
|
||||
}
|
||||
|
||||
private allowedPatches(): PatchType[] {
|
||||
private allowedPatches (): PatchType[] {
|
||||
const result = [PatchType.update, PatchType.remove]
|
||||
|
||||
if (this.params.reactions === true) {
|
||||
@@ -1082,7 +1082,7 @@ export class MessagesQuery implements PagedQuery<Message, MessageQueryParams> {
|
||||
return result
|
||||
}
|
||||
|
||||
private isAllowedPatch(type: PatchType): boolean {
|
||||
private isAllowedPatch (type: PatchType): boolean {
|
||||
return this.allowedPatches().includes(type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
private forward: Promise<NotificationContext[]> | NotificationContext[] = []
|
||||
private backward: Promise<NotificationContext[]> | NotificationContext[] = []
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly client: FindClient,
|
||||
private readonly workspace: WorkspaceID,
|
||||
private readonly filesUrl: string,
|
||||
@@ -123,7 +123,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
async onEvent(event: ResponseEvent): Promise<void> {
|
||||
async onEvent (event: ResponseEvent): Promise<void> {
|
||||
switch (event.type) {
|
||||
case MessageResponseEventType.PatchCreated: {
|
||||
await this.onCreatePatchEvent(event)
|
||||
@@ -170,13 +170,13 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
async onRequest(event: RequestEvent): Promise<void> {}
|
||||
async onRequest (event: RequestEvent): Promise<void> {}
|
||||
|
||||
async unsubscribe(): Promise<void> {
|
||||
async unsubscribe (): Promise<void> {
|
||||
await this.client.unsubscribeQuery(this.id)
|
||||
}
|
||||
|
||||
async requestLoadNextPage(): Promise<void> {
|
||||
async requestLoadNextPage (): Promise<void> {
|
||||
if (this.result instanceof Promise) {
|
||||
this.result = await this.result
|
||||
}
|
||||
@@ -216,7 +216,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
})
|
||||
}
|
||||
|
||||
async requestLoadPrevPage(): Promise<void> {
|
||||
async requestLoadPrevPage (): Promise<void> {
|
||||
if (this.result instanceof Promise) {
|
||||
this.result = await this.result
|
||||
}
|
||||
@@ -261,16 +261,16 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
})
|
||||
}
|
||||
|
||||
removeCallback(): void {
|
||||
removeCallback (): void {
|
||||
this.callback = () => {}
|
||||
}
|
||||
|
||||
setCallback(callback: PagedQueryCallback<NotificationContext>): void {
|
||||
setCallback (callback: PagedQueryCallback<NotificationContext>): void {
|
||||
this.callback = callback
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
copyResult(): QueryResult<NotificationContext> | undefined {
|
||||
copyResult (): QueryResult<NotificationContext> | undefined {
|
||||
if (this.result instanceof Promise) {
|
||||
return undefined
|
||||
}
|
||||
@@ -278,7 +278,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
return this.result.copy()
|
||||
}
|
||||
|
||||
private async find(params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
private async find (params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
const contexts = await this.client.findNotificationContexts(params, this.id)
|
||||
if (params.notifications?.message !== true) return contexts
|
||||
|
||||
@@ -314,7 +314,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
return contexts
|
||||
}
|
||||
|
||||
private async onCreateNotificationContextEvent(event: NotificationContextCreatedEvent): Promise<void> {
|
||||
private async onCreateNotificationContextEvent (event: NotificationContextCreatedEvent): Promise<void> {
|
||||
if (this.forward instanceof Promise) this.forward = await this.forward
|
||||
if (this.backward instanceof Promise) this.backward = await this.backward
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
@@ -333,7 +333,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
private async onCreatePatchEvent(event: PatchCreatedEvent): Promise<void> {
|
||||
private async onCreatePatchEvent (event: PatchCreatedEvent): Promise<void> {
|
||||
const isUpdated = await this.updateMessage(event.card, event.patch.message, (message) =>
|
||||
applyPatch(message, event.patch, allowedPatchTypes)
|
||||
)
|
||||
@@ -342,14 +342,14 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private async onFileCreated(event: FileCreatedEvent): Promise<void> {
|
||||
private async onFileCreated (event: FileCreatedEvent): Promise<void> {
|
||||
const isUpdated = await this.updateMessage(event.card, event.message, (message) => addFile(message, event.file))
|
||||
if (isUpdated) {
|
||||
void this.notify()
|
||||
}
|
||||
}
|
||||
|
||||
private async onFileRemoved(event: FileRemovedEvent): Promise<void> {
|
||||
private async onFileRemoved (event: FileRemovedEvent): Promise<void> {
|
||||
const isUpdated = await this.updateMessage(event.card, event.message, (message) =>
|
||||
removeFile(message, event.blobId)
|
||||
)
|
||||
@@ -358,7 +358,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private async onThreadCreated(event: ThreadCreatedEvent): Promise<void> {
|
||||
private async onThreadCreated (event: ThreadCreatedEvent): Promise<void> {
|
||||
const isUpdated = await this.updateMessage(event.thread.card, event.thread.message, (message) =>
|
||||
createThread(
|
||||
message,
|
||||
@@ -373,7 +373,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private async onThreadUpdated(event: ThreadUpdatedEvent): Promise<void> {
|
||||
private async onThreadUpdated (event: ThreadUpdatedEvent): Promise<void> {
|
||||
const isUpdated = await this.updateMessage(event.card, event.message, (message) =>
|
||||
updateThread(message, event.thread, event.updates.replies, event.updates.lastReply)
|
||||
)
|
||||
@@ -382,14 +382,14 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private async onRemoveNotificationEvent(event: NotificationsRemovedEvent): Promise<void> {
|
||||
private async onRemoveNotificationEvent (event: NotificationsRemovedEvent): Promise<void> {
|
||||
if (this.params.notifications == null) return
|
||||
if (this.forward instanceof Promise) this.forward = await this.forward
|
||||
if (this.backward instanceof Promise) this.backward = await this.backward
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
const context = this.result.get(event.context)
|
||||
if (context === undefined || context.notifications === undefined) return
|
||||
if (context?.notifications === undefined) return
|
||||
|
||||
const filtered = context.notifications.filter((it) => !event.ids.includes(it.id))
|
||||
if (filtered.length === context.notifications.length) return
|
||||
@@ -413,14 +413,14 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
private async onUpdateNotificationEvent(event: NotificationUpdatedEvent): Promise<void> {
|
||||
private async onUpdateNotificationEvent (event: NotificationUpdatedEvent): Promise<void> {
|
||||
if (this.params.notifications == null) return
|
||||
if (this.forward instanceof Promise) this.forward = await this.forward
|
||||
if (this.backward instanceof Promise) this.backward = await this.backward
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
const context = this.result.get(event.query.context)
|
||||
if (context === undefined || context.notifications === undefined) return
|
||||
if (context?.notifications === undefined) return
|
||||
|
||||
const toUpdate = context.notifications.filter(
|
||||
(it) => matchNotification(it, event.query) && it.read !== event.updates.read
|
||||
@@ -451,7 +451,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
private async onCreateNotificationEvent(event: NotificationCreatedEvent): Promise<void> {
|
||||
private async onCreateNotificationEvent (event: NotificationCreatedEvent): Promise<void> {
|
||||
if (this.params.notifications == null) return
|
||||
if (this.forward instanceof Promise) this.forward = await this.forward
|
||||
if (this.backward instanceof Promise) this.backward = await this.backward
|
||||
@@ -468,16 +468,16 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
const message =
|
||||
this.params.notifications.message === true
|
||||
? await findMessage(
|
||||
this.client,
|
||||
this.workspace,
|
||||
this.filesUrl,
|
||||
context.card,
|
||||
event.notification.messageId,
|
||||
event.notification.messageCreated,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
)
|
||||
this.client,
|
||||
this.workspace,
|
||||
this.filesUrl,
|
||||
context.card,
|
||||
event.notification.messageId,
|
||||
event.notification.messageCreated,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
)
|
||||
: undefined
|
||||
|
||||
const notifications = [
|
||||
@@ -506,7 +506,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private async onRemoveNotificationContextEvent(event: NotificationContextRemovedEvent): Promise<void> {
|
||||
private async onRemoveNotificationContextEvent (event: NotificationContextRemovedEvent): Promise<void> {
|
||||
if (this.forward instanceof Promise) this.forward = await this.forward
|
||||
if (this.backward instanceof Promise) this.backward = await this.backward
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
@@ -515,7 +515,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
const deleted = this.result.delete(event.context.id)
|
||||
|
||||
if (deleted != null) {
|
||||
if (this.params.limit && length >= this.params.limit && this.result.length < this.params.limit) {
|
||||
if (this.params.limit != null && length >= this.params.limit && this.result.length < this.params.limit) {
|
||||
await this.reinit(length)
|
||||
} else {
|
||||
void this.notify()
|
||||
@@ -523,7 +523,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private async reinit(limit: number): Promise<void> {
|
||||
private async reinit (limit: number): Promise<void> {
|
||||
if (this.forward instanceof Promise) this.forward = await this.forward
|
||||
if (this.backward instanceof Promise) this.backward = await this.backward
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
@@ -547,7 +547,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
})
|
||||
}
|
||||
|
||||
private async onUpdateNotificationContextEvent(event: NotificationContextUpdatedEvent): Promise<void> {
|
||||
private async onUpdateNotificationContextEvent (event: NotificationContextUpdatedEvent): Promise<void> {
|
||||
if (this.forward instanceof Promise) this.forward = await this.forward
|
||||
if (this.backward instanceof Promise) this.backward = await this.backward
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
@@ -559,16 +559,16 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
const newNotifications =
|
||||
event.lastView != null
|
||||
? this.filterNotifications(
|
||||
currentNotifications.map((it) => ({
|
||||
...it,
|
||||
read:
|
||||
it.type == NotificationType.Message ? event.lastView != null && event.lastView >= it.created : it.read
|
||||
}))
|
||||
)
|
||||
currentNotifications.map((it) => ({
|
||||
...it,
|
||||
read:
|
||||
it.type === NotificationType.Message ? event.lastView != null && event.lastView >= it.created : it.read
|
||||
}))
|
||||
)
|
||||
: currentNotifications
|
||||
|
||||
if (
|
||||
this.params.notifications &&
|
||||
this.params.notifications != null &&
|
||||
newNotifications.length < currentNotifications.length &&
|
||||
newNotifications.length < this.params.notifications.limit &&
|
||||
this.params.notifications.order !== SortingOrder.Descending
|
||||
@@ -601,12 +601,12 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
async onCardRemoved(event: CardRemovedEvent): Promise<void> {
|
||||
async onCardRemoved (event: CardRemovedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
let updated = false
|
||||
const result = this.result.getResult()
|
||||
for (const context of result) {
|
||||
if (context.card == event.card) {
|
||||
if (context.card === event.card) {
|
||||
this.result.delete(context.id)
|
||||
updated = true
|
||||
}
|
||||
@@ -626,7 +626,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
if (this.params.limit && this.result.length < this.params.limit && result.length >= this.params.limit) {
|
||||
if (this.params.limit != null && this.result.length < this.params.limit && result.length >= this.params.limit) {
|
||||
const contexts = await this.find(this.params)
|
||||
this.result = new QueryResult(contexts, (x) => x.id)
|
||||
}
|
||||
@@ -634,7 +634,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private filterNotifications(notifications: Notification[]): Notification[] {
|
||||
private filterNotifications (notifications: Notification[]): Notification[] {
|
||||
if (this.params.notifications == null) return notifications
|
||||
const read = this.params.notifications.read
|
||||
if (read == null) return notifications
|
||||
@@ -642,7 +642,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
return notifications.filter((it) => it.read === read)
|
||||
}
|
||||
|
||||
private async addContext(context: NotificationContext): Promise<void> {
|
||||
private async addContext (context: NotificationContext): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
if (this.result.get(context.id) !== undefined) return
|
||||
if (this.result.isTail()) {
|
||||
@@ -658,7 +658,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
}
|
||||
}
|
||||
|
||||
private match(context: NotificationContext): boolean {
|
||||
private match (context: NotificationContext): boolean {
|
||||
if (this.params.card !== undefined) {
|
||||
const cards = Array.isArray(this.params.card) ? this.params.card : [this.params.card]
|
||||
if (!cards.includes(context.card)) return false
|
||||
@@ -706,7 +706,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
return true
|
||||
}
|
||||
|
||||
private async notify(): Promise<void> {
|
||||
private async notify (): Promise<void> {
|
||||
if (this.callback === undefined) return
|
||||
if (this.result instanceof Promise) {
|
||||
this.result = await this.result
|
||||
@@ -720,7 +720,7 @@ export class NotificationContextsQuery implements PagedQuery<NotificationContext
|
||||
this.callback(window)
|
||||
}
|
||||
|
||||
private async updateMessage(
|
||||
private async updateMessage (
|
||||
card: CardID,
|
||||
messageId: MessageID,
|
||||
updater: (message: Message) => Message
|
||||
|
||||
@@ -62,7 +62,7 @@ const allowedPatchTypes = [
|
||||
export class NotificationQuery implements PagedQuery<Notification, FindNotificationsParams> {
|
||||
private result: QueryResult<Notification> | Promise<QueryResult<Notification>>
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly client: FindClient,
|
||||
private readonly workspace: WorkspaceID,
|
||||
private readonly filesUrl: string,
|
||||
@@ -86,7 +86,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async initResult(findParams: FindNotificationsParams, limit: number): Promise<QueryResult<Notification>> {
|
||||
private async initResult (findParams: FindNotificationsParams, limit: number): Promise<QueryResult<Notification>> {
|
||||
try {
|
||||
const res = await this.find(findParams)
|
||||
const isComplete = res.length <= limit
|
||||
@@ -104,7 +104,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
async onEvent(event: ResponseEvent): Promise<void> {
|
||||
async onEvent (event: ResponseEvent): Promise<void> {
|
||||
switch (event.type) {
|
||||
case NotificationResponseEventType.NotificationCreated: {
|
||||
await this.onCreateNotificationEvent(event)
|
||||
@@ -146,25 +146,25 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
async onRequest(event: RequestEvent): Promise<void> {}
|
||||
async onRequest (event: RequestEvent): Promise<void> {}
|
||||
|
||||
async unsubscribe(): Promise<void> {
|
||||
async unsubscribe (): Promise<void> {
|
||||
await this.client.unsubscribeQuery(this.id)
|
||||
}
|
||||
|
||||
async requestLoadNextPage(): Promise<void> {
|
||||
async requestLoadNextPage (): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
await this.loadPage(SortingOrder.Ascending, this.result.getLast()?.created)
|
||||
}
|
||||
|
||||
async requestLoadPrevPage(): Promise<void> {
|
||||
async requestLoadPrevPage (): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
await this.loadPage(SortingOrder.Descending, this.result.getFirst()?.created)
|
||||
}
|
||||
|
||||
private async loadPage(order: SortingOrder, created?: Date): Promise<void> {
|
||||
if (!created) return
|
||||
private async loadPage (order: SortingOrder, created?: Date): Promise<void> {
|
||||
if (created == null) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
const limit = this.getLimit()
|
||||
@@ -194,26 +194,26 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
removeCallback(): void {
|
||||
removeCallback (): void {
|
||||
this.callback = () => {}
|
||||
}
|
||||
|
||||
setCallback(callback: PagedQueryCallback<Notification>): void {
|
||||
setCallback (callback: PagedQueryCallback<Notification>): void {
|
||||
this.callback = callback
|
||||
void this.notify()
|
||||
}
|
||||
|
||||
copyResult(): QueryResult<Notification> | undefined {
|
||||
copyResult (): QueryResult<Notification> | undefined {
|
||||
return this.result instanceof Promise ? undefined : this.result.copy()
|
||||
}
|
||||
|
||||
private async find(params: FindNotificationsParams): Promise<Notification[]> {
|
||||
private async find (params: FindNotificationsParams): Promise<Notification[]> {
|
||||
const notifications = await this.client.findNotifications(params, this.id)
|
||||
if (!params.message) return notifications
|
||||
if (params.message !== true) return notifications
|
||||
|
||||
return await Promise.all(
|
||||
notifications.map(async (notification) => {
|
||||
if (notification.message || !notification.messageId) return notification
|
||||
if (notification.message != null) return notification
|
||||
const message = await loadMessageFromGroup(
|
||||
notification.messageId,
|
||||
this.workspace,
|
||||
@@ -221,14 +221,14 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
notification.messageGroup,
|
||||
notification.patches
|
||||
)
|
||||
return message ? { ...notification, message } : notification
|
||||
return message != null ? { ...notification, message } : notification
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
private async onCreateNotificationEvent(event: NotificationCreatedEvent): Promise<void> {
|
||||
private async onCreateNotificationEvent (event: NotificationCreatedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
if (this.result.get(event.notification.id)) return
|
||||
if (this.result.get(event.notification.id) != null) return
|
||||
if (!this.result.isTail()) return
|
||||
|
||||
const match = matchNotification(event.notification, { ...this.params, created: undefined })
|
||||
@@ -243,7 +243,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
await this.notify()
|
||||
}
|
||||
|
||||
private async onUpdateNotificationContextEvent(event: NotificationContextUpdatedEvent): Promise<void> {
|
||||
private async onUpdateNotificationContextEvent (event: NotificationContextUpdatedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
if (this.params.context != null && this.params.context !== event.context) return
|
||||
|
||||
@@ -255,14 +255,14 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
|
||||
const updated: Notification[] = toUpdate.map((it) => ({
|
||||
...it,
|
||||
read: it.type == NotificationType.Message ? lastView >= it.created : it.read
|
||||
read: it.type === NotificationType.Message ? lastView >= it.created : it.read
|
||||
}))
|
||||
|
||||
await this.updateNotificationRead(this.result, updated)
|
||||
}
|
||||
|
||||
private async updateNotificationRead(result: QueryResult<Notification>, updated: Notification[]): Promise<void> {
|
||||
const isAllowed = (n: Notification) => {
|
||||
private async updateNotificationRead (result: QueryResult<Notification>, updated: Notification[]): Promise<void> {
|
||||
const isAllowed = (n: Notification): boolean => {
|
||||
if (this.params.read == null) return true
|
||||
return n.read === this.params.read
|
||||
}
|
||||
@@ -284,11 +284,11 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onUpdateNotificationEvent(event: NotificationUpdatedEvent): Promise<void> {
|
||||
private async onUpdateNotificationEvent (event: NotificationUpdatedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
const toUpdate = (
|
||||
event.query.id
|
||||
event.query.id != null
|
||||
? [this.result.get(event.query.id)].filter((it): it is Notification => it != null)
|
||||
: this.result.getResult().filter((it) => matchNotification(it, event.query))
|
||||
).filter((it) => it.read !== event.updates.read)
|
||||
@@ -297,7 +297,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
await this.updateNotificationRead(this.result, updated)
|
||||
}
|
||||
|
||||
private async onRemoveNotificationsEvent(event: NotificationsRemovedEvent): Promise<void> {
|
||||
private async onRemoveNotificationsEvent (event: NotificationsRemovedEvent): Promise<void> {
|
||||
if (this.params.context !== undefined && this.params.context !== event.context) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
@@ -318,7 +318,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onRemoveNotificationContextEvent(event: NotificationContextRemovedEvent): Promise<void> {
|
||||
private async onRemoveNotificationContextEvent (event: NotificationContextRemovedEvent): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
if (this.params.context != null && this.params.context !== event.context.id) return
|
||||
@@ -346,7 +346,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onCreatePatchEvent(event: PatchCreatedEvent): Promise<void> {
|
||||
private async onCreatePatchEvent (event: PatchCreatedEvent): Promise<void> {
|
||||
if (this.params.message !== true) return
|
||||
const isUpdated = await this.updateMessage(
|
||||
(it) => this.matchNotificationByMessage(it, event.card, event.patch.message),
|
||||
@@ -357,7 +357,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onFileCreated(event: FileCreatedEvent): Promise<void> {
|
||||
private async onFileCreated (event: FileCreatedEvent): Promise<void> {
|
||||
if (this.params.message !== true) return
|
||||
const isUpdated = await this.updateMessage(
|
||||
(it) => this.matchNotificationByMessage(it, event.card, event.message),
|
||||
@@ -368,7 +368,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onFileRemoved(event: FileRemovedEvent): Promise<void> {
|
||||
private async onFileRemoved (event: FileRemovedEvent): Promise<void> {
|
||||
if (this.params.message !== true) return
|
||||
const isUpdated = await this.updateMessage(
|
||||
(it) => this.matchNotificationByMessage(it, event.card, event.message),
|
||||
@@ -379,7 +379,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onThreadCreated(event: ThreadCreatedEvent): Promise<void> {
|
||||
private async onThreadCreated (event: ThreadCreatedEvent): Promise<void> {
|
||||
if (this.params.message !== true) return
|
||||
const isUpdated = await this.updateMessage(
|
||||
(it) => this.matchNotificationByMessage(it, event.thread.card, event.thread.message),
|
||||
@@ -397,7 +397,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onThreadUpdated(event: ThreadUpdatedEvent): Promise<void> {
|
||||
private async onThreadUpdated (event: ThreadUpdatedEvent): Promise<void> {
|
||||
if (this.params.message !== true) return
|
||||
const isUpdated = await this.updateMessage(
|
||||
(it) => this.matchNotificationByMessage(it, event.card, event.message),
|
||||
@@ -408,7 +408,7 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
}
|
||||
}
|
||||
|
||||
private async onCardRemoved(event: CardRemovedEvent): Promise<void> {
|
||||
private async onCardRemoved (event: CardRemovedEvent): Promise<void> {
|
||||
if (this.params.message !== true) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
const isUpdated = await this.updateMessage(
|
||||
@@ -419,19 +419,20 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
void this.notify()
|
||||
}
|
||||
}
|
||||
private async notify(): Promise<void> {
|
||||
if (!this.callback) return
|
||||
|
||||
private async notify (): Promise<void> {
|
||||
if (this.callback == null) return
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
|
||||
const window = new WindowImpl(this.result.getResult(), this.result.isTail(), this.result.isHead(), this)
|
||||
this.callback(window)
|
||||
}
|
||||
|
||||
private getLimit(): number {
|
||||
private getLimit (): number {
|
||||
return this.params.limit ?? defaultQueryParams.limit
|
||||
}
|
||||
|
||||
private async reinit(limit: number): Promise<void> {
|
||||
private async reinit (limit: number): Promise<void> {
|
||||
if (this.result instanceof Promise) this.result = await this.result
|
||||
this.result = this.find({ ...this.params, limit: limit + 1 }).then((res) => {
|
||||
const isTail = res.length <= limit
|
||||
@@ -451,11 +452,11 @@ export class NotificationQuery implements PagedQuery<Notification, FindNotificat
|
||||
})
|
||||
}
|
||||
|
||||
private matchNotificationByMessage(notification: Notification, card: CardID, messageId: MessageID): boolean {
|
||||
private matchNotificationByMessage (notification: Notification, card: CardID, messageId: MessageID): boolean {
|
||||
return notification.messageId === messageId && notification.message != null && notification.message.card === card
|
||||
}
|
||||
|
||||
private async updateMessage(
|
||||
private async updateMessage (
|
||||
matchFn: (notification: Notification) => boolean,
|
||||
updater: (message: Message) => Message
|
||||
): Promise<boolean> {
|
||||
|
||||
@@ -21,60 +21,60 @@ export class QueryResult<T> {
|
||||
private tail: boolean = false
|
||||
private head: boolean = false
|
||||
|
||||
get length(): number {
|
||||
get length (): number {
|
||||
return this.objectById.size
|
||||
}
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
messages: T[],
|
||||
private readonly getId: (it: T) => ID
|
||||
) {
|
||||
this.objectById = new Map(messages.map((it) => [getId(it), it]))
|
||||
}
|
||||
|
||||
isTail(): boolean {
|
||||
isTail (): boolean {
|
||||
return this.tail
|
||||
}
|
||||
|
||||
isHead(): boolean {
|
||||
isHead (): boolean {
|
||||
return this.head
|
||||
}
|
||||
|
||||
setHead(head: boolean): void {
|
||||
setHead (head: boolean): void {
|
||||
this.head = head
|
||||
}
|
||||
|
||||
setTail(tail: boolean): void {
|
||||
setTail (tail: boolean): void {
|
||||
this.tail = tail
|
||||
}
|
||||
|
||||
getResult(): T[] {
|
||||
getResult (): T[] {
|
||||
return Array.from(this.objectById.values())
|
||||
}
|
||||
|
||||
get(id: ID): Readonly<T> | undefined {
|
||||
get (id: ID): Readonly<T> | undefined {
|
||||
return this.objectById.get(id)
|
||||
}
|
||||
|
||||
delete(id: ID): T | undefined {
|
||||
delete (id: ID): T | undefined {
|
||||
const object = this.objectById.get(id)
|
||||
this.objectById.delete(id)
|
||||
return object
|
||||
}
|
||||
|
||||
deleteAll(): void {
|
||||
deleteAll (): void {
|
||||
this.objectById.clear()
|
||||
}
|
||||
|
||||
push(object: T): void {
|
||||
push (object: T): void {
|
||||
this.objectById.set(this.getId(object), object)
|
||||
}
|
||||
|
||||
unshift(object: T): void {
|
||||
unshift (object: T): void {
|
||||
this.objectById = new Map([[this.getId(object), object], ...this.objectById])
|
||||
}
|
||||
|
||||
pop(): T | undefined {
|
||||
pop (): T | undefined {
|
||||
const array = Array.from(this.objectById.values())
|
||||
const last = array[array.length - 1]
|
||||
if (last === undefined) return
|
||||
@@ -82,36 +82,36 @@ export class QueryResult<T> {
|
||||
return last
|
||||
}
|
||||
|
||||
update(object: T): void {
|
||||
update (object: T): void {
|
||||
this.objectById.set(this.getId(object), object)
|
||||
}
|
||||
|
||||
getFirst(): T | undefined {
|
||||
getFirst (): T | undefined {
|
||||
return Array.from(this.objectById.values())[0]
|
||||
}
|
||||
|
||||
getLast(): T | undefined {
|
||||
getLast (): T | undefined {
|
||||
return Array.from(this.objectById.values())[this.objectById.size - 1]
|
||||
}
|
||||
|
||||
prepend(objects: T[]): void {
|
||||
prepend (objects: T[]): void {
|
||||
const current = Array.from(this.objectById.entries())
|
||||
this.objectById = new Map([...objects.map<[ID, T]>((object) => [this.getId(object), object]), ...current])
|
||||
}
|
||||
|
||||
append(objects: T[]): void {
|
||||
append (objects: T[]): void {
|
||||
for (const object of objects) {
|
||||
this.objectById.set(this.getId(object), object)
|
||||
}
|
||||
}
|
||||
|
||||
sort(compare: (a: T, b: T) => number): void {
|
||||
sort (compare: (a: T, b: T) => number): void {
|
||||
const current = Array.from(this.objectById.values())
|
||||
const sorted = current.sort(compare)
|
||||
this.objectById = new Map(sorted.map<[ID, T]>((object) => [this.getId(object), object]))
|
||||
}
|
||||
|
||||
copy(): QueryResult<T> {
|
||||
copy (): QueryResult<T> {
|
||||
const copy = new QueryResult(Array.from(this.objectById.values()), this.getId)
|
||||
|
||||
copy.setHead(this.head)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { type ResponseEvent } from '@hcengineering/communication-sdk-types'
|
||||
import { type ResponseEvent, EventResult, RequestEvent } from '@hcengineering/communication-sdk-types'
|
||||
import {
|
||||
SortingOrder,
|
||||
type Window,
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
type CardID,
|
||||
type MessageID
|
||||
} from '@hcengineering/communication-types'
|
||||
import type { EventResult, RequestEvent } from '@hcengineering/communication-sdk-types'
|
||||
|
||||
import { QueryResult } from './result'
|
||||
|
||||
|
||||
+17
-17
@@ -35,7 +35,7 @@ import {
|
||||
import { loadGroupFile } from '@hcengineering/communication-yaml'
|
||||
import type { FindClient } from '@hcengineering/communication-sdk-types'
|
||||
|
||||
export async function findMessage(
|
||||
export async function findMessage (
|
||||
client: FindClient,
|
||||
workspace: WorkspaceID,
|
||||
filesUrl: string,
|
||||
@@ -53,7 +53,7 @@ export async function findMessage(
|
||||
return await findMessageInFiles(client, workspace, filesUrl, card, id, created)
|
||||
}
|
||||
|
||||
export async function findMessageInFiles(
|
||||
export async function findMessageInFiles (
|
||||
client: FindClient,
|
||||
workspace: WorkspaceID,
|
||||
filesUrl: string,
|
||||
@@ -96,7 +96,7 @@ export async function findMessageInFiles(
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadMessageFromGroup(
|
||||
export async function loadMessageFromGroup (
|
||||
id: MessageID,
|
||||
workspace: WorkspaceID,
|
||||
filesUrl: string,
|
||||
@@ -113,14 +113,14 @@ export async function loadMessageFromGroup(
|
||||
return applyPatches(message, patches)
|
||||
}
|
||||
|
||||
export function addFile(message: Message, file: File): Message {
|
||||
export function addFile (message: Message, file: File): Message {
|
||||
if (!message.files.some((it) => it.blobId === file.blobId)) {
|
||||
message.files.push(file)
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
export function removeFile(message: Message, blobId: BlobID): Message {
|
||||
export function removeFile (message: Message, blobId: BlobID): Message {
|
||||
const files = message.files.filter((it) => it.blobId !== blobId)
|
||||
if (files.length === message.files.length) return message
|
||||
|
||||
@@ -130,7 +130,7 @@ export function removeFile(message: Message, blobId: BlobID): Message {
|
||||
}
|
||||
}
|
||||
|
||||
export function addLinkPreview(message: Message, linkPreview: LinkPreview): Message {
|
||||
export function addLinkPreview (message: Message, linkPreview: LinkPreview): Message {
|
||||
const current = message.links.find((it) => it.id === linkPreview.id)
|
||||
if (current === undefined) {
|
||||
message.links.push(linkPreview)
|
||||
@@ -138,7 +138,7 @@ export function addLinkPreview(message: Message, linkPreview: LinkPreview): Mess
|
||||
return message
|
||||
}
|
||||
|
||||
export function removeLinkPreview(message: Message, id: LinkPreviewID): Message {
|
||||
export function removeLinkPreview (message: Message, id: LinkPreviewID): Message {
|
||||
const links = message.links.filter((it) => it.id !== id)
|
||||
if (links.length === message.links.length) return message
|
||||
return {
|
||||
@@ -147,7 +147,7 @@ export function removeLinkPreview(message: Message, id: LinkPreviewID): Message
|
||||
}
|
||||
}
|
||||
|
||||
export function addReaction(message: Message, reaction: Reaction): Message {
|
||||
export function addReaction (message: Message, reaction: Reaction): Message {
|
||||
const current = message.reactions.find((it) => it.reaction === reaction.reaction && it.creator === reaction.creator)
|
||||
if (current === undefined) {
|
||||
message.reactions.push(reaction)
|
||||
@@ -155,7 +155,7 @@ export function addReaction(message: Message, reaction: Reaction): Message {
|
||||
return message
|
||||
}
|
||||
|
||||
export function removeReaction(message: Message, emoji: string, creator: SocialID): Message {
|
||||
export function removeReaction (message: Message, emoji: string, creator: SocialID): Message {
|
||||
const reactions = message.reactions.filter((it) => it.reaction !== emoji || it.creator !== creator)
|
||||
if (reactions.length === message.reactions.length) return message
|
||||
|
||||
@@ -165,7 +165,7 @@ export function removeReaction(message: Message, emoji: string, creator: SocialI
|
||||
}
|
||||
}
|
||||
|
||||
export function createThread(
|
||||
export function createThread (
|
||||
message: Message,
|
||||
threadId: CardID,
|
||||
threadType: CardType,
|
||||
@@ -188,7 +188,7 @@ export function createThread(
|
||||
return message
|
||||
}
|
||||
|
||||
export function updateThread(
|
||||
export function updateThread (
|
||||
message: Message,
|
||||
thread: CardID,
|
||||
replies: 'increment' | 'decrement',
|
||||
@@ -204,7 +204,7 @@ export function updateThread(
|
||||
return message
|
||||
}
|
||||
|
||||
export function matchNotification(notification: Notification, params: FindNotificationsParams): boolean {
|
||||
export function matchNotification (notification: Notification, params: FindNotificationsParams): boolean {
|
||||
if (params.type !== undefined && params.type !== notification.type) return false
|
||||
if (params.read !== undefined && params.read !== notification.read) return false
|
||||
if (params.id !== undefined && params.id !== notification.id) return false
|
||||
@@ -212,15 +212,15 @@ export function matchNotification(notification: Notification, params: FindNotifi
|
||||
|
||||
const created = notification.created.getTime()
|
||||
|
||||
if (params.created) {
|
||||
if (params.created != null) {
|
||||
if (params.created instanceof Date) {
|
||||
if (created !== params.created.getTime()) return false
|
||||
} else {
|
||||
const { greater, less, greaterOrEqual, lessOrEqual } = params.created
|
||||
if (greater && created <= greater.getTime()) return false
|
||||
if (less && created >= less.getTime()) return false
|
||||
if (greaterOrEqual && created < greaterOrEqual.getTime()) return false
|
||||
if (lessOrEqual && created > lessOrEqual.getTime()) return false
|
||||
if (greater != null && created <= greater.getTime()) return false
|
||||
if (less != null && created >= less.getTime()) return false
|
||||
if (greaterOrEqual != null && created < greaterOrEqual.getTime()) return false
|
||||
if (lessOrEqual != null && created > lessOrEqual.getTime()) return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,32 +18,32 @@ import type { Window } from '@hcengineering/communication-types'
|
||||
import type { PagedQuery } from './types'
|
||||
|
||||
export class WindowImpl<T> implements Window<T> {
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly result: T[],
|
||||
private readonly isTail: boolean,
|
||||
private readonly isHead: boolean,
|
||||
private readonly query: PagedQuery<T>
|
||||
) {}
|
||||
|
||||
getResult(): T[] {
|
||||
getResult (): T[] {
|
||||
return this.result
|
||||
}
|
||||
|
||||
async loadNextPage(): Promise<void> {
|
||||
async loadNextPage (): Promise<void> {
|
||||
if (!this.hasNextPage()) return
|
||||
await this.query.requestLoadNextPage()
|
||||
}
|
||||
|
||||
async loadPrevPage(): Promise<void> {
|
||||
async loadPrevPage (): Promise<void> {
|
||||
if (!this.hasPrevPage()) return
|
||||
await this.query.requestLoadPrevPage()
|
||||
}
|
||||
|
||||
hasNextPage(): boolean {
|
||||
hasNextPage (): boolean {
|
||||
return !this.isTail
|
||||
}
|
||||
|
||||
hasPrevPage(): boolean {
|
||||
hasPrevPage (): boolean {
|
||||
return !this.isHead
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declarationDir": "./types",
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "lib", "dist", "types", "bundle"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
||||
@@ -1,34 +1,44 @@
|
||||
{
|
||||
"name": "@hcengineering/communication-rest-client",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"dist/index.js",
|
||||
"dist/index.cjs",
|
||||
"types/**/*.d.ts"
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "bun run build:types && bun run build:browser && bun run build:node",
|
||||
"build:types": "tsc --project ./tsconfig.json --emitDeclarationOnly --declarationDir ./types",
|
||||
"build:browser": "bun build src/index.ts --outdir dist --target browser",
|
||||
"build:node": "bun build src/index.ts --target node --format cjs --outfile dist/index.cjs",
|
||||
"lint": "eslint src/*.ts",
|
||||
"format": "prettier --write src/**/*.ts ",
|
||||
"clean": "rm -rf dist && rm -rf types && rm -rf .turbo"
|
||||
"build": "compile",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:validate": "compile validate",
|
||||
|
||||
"lint": "eslint \"src/**/*.ts\"",
|
||||
"lint:fix": "eslint --fix \"src/**/*.ts\"",
|
||||
"format": "prettier --write src/**/*.ts && eslint --fix \"src/**/*.ts\"",
|
||||
"clean": "rm -rf lib && rm -rf types rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
"@hcengineering/platform-rig": "^0.6.490",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"esbuild-plugin-copy": "~2.1.1",
|
||||
"eslint": "^8.54.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.8.3",
|
||||
"@types/snappyjs": "^0.7.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/communication-shared": "workspace:*",
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-types": "^0.1.0",
|
||||
"@hcengineering/communication-sdk-types": "^0.1.0",
|
||||
"@hcengineering/communication-shared": "^0.1.0",
|
||||
"@hcengineering/core": "^0.7.88",
|
||||
"snappyjs": "^0.7.0"
|
||||
},
|
||||
@@ -38,5 +48,12 @@
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/index.d.ts",
|
||||
"require": "./lib/index.js",
|
||||
"import": "./lib/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
//
|
||||
|
||||
import { concatLink } from '@hcengineering/core'
|
||||
import { PlatformError, unknownError } from '@hcengineering/platform'
|
||||
import {
|
||||
MessageRequestEventType,
|
||||
type EventResult,
|
||||
@@ -48,14 +47,14 @@ import type { RestClient } from './types'
|
||||
|
||||
const retries = 3
|
||||
|
||||
export function createRestClient(endpoint: string, workspaceId: string, token: string): RestClient {
|
||||
export function createRestClient (endpoint: string, workspaceId: string, token: string): RestClient {
|
||||
return new RestClientImpl(endpoint, workspaceId, token)
|
||||
}
|
||||
|
||||
class RestClientImpl implements RestClient {
|
||||
endpoint: string
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
endpoint: string,
|
||||
readonly workspace: string,
|
||||
readonly token: string
|
||||
@@ -63,7 +62,7 @@ class RestClientImpl implements RestClient {
|
||||
this.endpoint = endpoint.replace('ws', 'http')
|
||||
}
|
||||
|
||||
private jsonHeaders(): Record<string, string> {
|
||||
private jsonHeaders (): Record<string, string> {
|
||||
return {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Bearer ' + this.token,
|
||||
@@ -71,7 +70,7 @@ class RestClientImpl implements RestClient {
|
||||
}
|
||||
}
|
||||
|
||||
private requestInit(): RequestInit {
|
||||
private requestInit (): RequestInit {
|
||||
return {
|
||||
method: 'GET',
|
||||
keepalive: true,
|
||||
@@ -79,7 +78,7 @@ class RestClientImpl implements RestClient {
|
||||
}
|
||||
}
|
||||
|
||||
async event(event: RequestEvent): Promise<EventResult> {
|
||||
async event (event: RequestEvent): Promise<EventResult> {
|
||||
const response = await fetch(concatLink(this.endpoint, `/api/v1/event/${this.workspace}`), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -90,12 +89,12 @@ class RestClientImpl implements RestClient {
|
||||
body: JSON.stringify(event)
|
||||
})
|
||||
if (!response.ok) {
|
||||
throw new PlatformError(unknownError(response.statusText))
|
||||
throw new Error(response.statusText)
|
||||
}
|
||||
return (await response.json()) as EventResult
|
||||
}
|
||||
|
||||
async createMessage(
|
||||
async createMessage (
|
||||
card: CardID,
|
||||
cardType: CardType,
|
||||
content: RichText,
|
||||
@@ -121,7 +120,7 @@ class RestClientImpl implements RestClient {
|
||||
return result as CreateMessageResult
|
||||
}
|
||||
|
||||
async updateMessage(
|
||||
async updateMessage (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -139,7 +138,7 @@ class RestClientImpl implements RestClient {
|
||||
})
|
||||
}
|
||||
|
||||
async removeMessage(card: CardID, message: MessageID, messageCreated: Date, creator: SocialID): Promise<void> {
|
||||
async removeMessage (card: CardID, message: MessageID, messageCreated: Date, creator: SocialID): Promise<void> {
|
||||
await this.event({
|
||||
type: MessageRequestEventType.CreatePatch,
|
||||
patchType: PatchType.remove,
|
||||
@@ -151,7 +150,7 @@ class RestClientImpl implements RestClient {
|
||||
})
|
||||
}
|
||||
|
||||
async createFile(
|
||||
async createFile (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -168,7 +167,7 @@ class RestClientImpl implements RestClient {
|
||||
})
|
||||
}
|
||||
|
||||
async removeFile(
|
||||
async removeFile (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -185,7 +184,7 @@ class RestClientImpl implements RestClient {
|
||||
})
|
||||
}
|
||||
|
||||
async findMessages(params: FindMessagesParams): Promise<Message[]> {
|
||||
async findMessages (params: FindMessagesParams): Promise<Message[]> {
|
||||
const searchParams = new URLSearchParams()
|
||||
if (Object.keys(params).length > 0) {
|
||||
searchParams.append('params', JSON.stringify(params))
|
||||
@@ -196,7 +195,7 @@ class RestClientImpl implements RestClient {
|
||||
async () => {
|
||||
const response = await fetch(requestUrl, this.requestInit())
|
||||
if (!response.ok) {
|
||||
throw new PlatformError(unknownError(response.statusText))
|
||||
throw new Error(response.statusText)
|
||||
}
|
||||
return await extractJson<MessagesGroup[]>(response)
|
||||
},
|
||||
@@ -204,7 +203,7 @@ class RestClientImpl implements RestClient {
|
||||
)
|
||||
}
|
||||
|
||||
async findMessagesGroups(params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
async findMessagesGroups (params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
const searchParams = new URLSearchParams()
|
||||
if (Object.keys(params).length > 0) {
|
||||
searchParams.append('params', JSON.stringify(params))
|
||||
@@ -217,7 +216,7 @@ class RestClientImpl implements RestClient {
|
||||
async () => {
|
||||
const response = await fetch(requestUrl, this.requestInit())
|
||||
if (!response.ok) {
|
||||
throw new PlatformError(unknownError(response.statusText))
|
||||
throw new Error(response.statusText)
|
||||
}
|
||||
return await extractJson<MessagesGroup[]>(response)
|
||||
},
|
||||
@@ -225,7 +224,7 @@ class RestClientImpl implements RestClient {
|
||||
)
|
||||
}
|
||||
|
||||
async findNotificationContexts(params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
async findNotificationContexts (params: FindNotificationContextParams): Promise<NotificationContext[]> {
|
||||
const searchParams = new URLSearchParams()
|
||||
if (Object.keys(params).length > 0) {
|
||||
searchParams.append('params', JSON.stringify(params))
|
||||
@@ -238,7 +237,7 @@ class RestClientImpl implements RestClient {
|
||||
async () => {
|
||||
const response = await fetch(requestUrl, this.requestInit())
|
||||
if (!response.ok) {
|
||||
throw new PlatformError(unknownError(response.statusText))
|
||||
throw new Error(response.statusText)
|
||||
}
|
||||
return await extractJson<NotificationContext[]>(response)
|
||||
},
|
||||
@@ -246,7 +245,7 @@ class RestClientImpl implements RestClient {
|
||||
)
|
||||
}
|
||||
|
||||
async findNotifications(params: FindNotificationsParams): Promise<Notification[]> {
|
||||
async findNotifications (params: FindNotificationsParams): Promise<Notification[]> {
|
||||
const searchParams = new URLSearchParams()
|
||||
if (Object.keys(params).length > 0) {
|
||||
searchParams.append('params', JSON.stringify(params))
|
||||
@@ -259,7 +258,7 @@ class RestClientImpl implements RestClient {
|
||||
async () => {
|
||||
const response = await fetch(requestUrl, this.requestInit())
|
||||
if (!response.ok) {
|
||||
throw new PlatformError(unknownError(response.statusText))
|
||||
throw new Error(response.statusText)
|
||||
}
|
||||
return await extractJson<Notification[]>(response)
|
||||
},
|
||||
|
||||
@@ -15,19 +15,19 @@
|
||||
|
||||
import { uncompress } from 'snappyjs'
|
||||
|
||||
function isDateString(value: any) {
|
||||
function isDateString (value: any): boolean {
|
||||
if (typeof value !== 'string') return false
|
||||
const dateStringRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/
|
||||
|
||||
return dateStringRegex.test(value)
|
||||
}
|
||||
|
||||
function reviver(key: string, value: any) {
|
||||
function reviver (key: string, value: any): Date {
|
||||
if (isDateString(value)) return new Date(value)
|
||||
return value
|
||||
}
|
||||
|
||||
export async function extractJson<T>(response: Response): Promise<any> {
|
||||
export async function extractJson<T> (response: Response): Promise<any> {
|
||||
const encoding = response.headers.get('content-encoding')
|
||||
if (encoding === 'snappy') {
|
||||
const buffer = await response.arrayBuffer()
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declarationDir": "./types",
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "lib", "dist", "types", "bundle"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
||||
@@ -1,32 +1,42 @@
|
||||
{
|
||||
"name": "@hcengineering/communication-sdk-types",
|
||||
"version": "0.1.0",
|
||||
"main": "./dist/index.cjs",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"dist/index.js",
|
||||
"dist/index.cjs",
|
||||
"types/**/*.d.ts"
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "bun run build:types && bun run build:browser && bun run build:node",
|
||||
"build:types": "tsc --project ./tsconfig.json --emitDeclarationOnly --declarationDir ./types",
|
||||
"build:browser": "bun build src/index.ts --outdir dist --target browser",
|
||||
"build:node": "bun build src/index.ts --target node --format cjs --outfile dist/index.cjs",
|
||||
"lint": "eslint src/*.ts",
|
||||
"format": "prettier --write src/**/*.ts",
|
||||
"clean": "rm -rf dist && rm -rf types && rm -rf .turbo"
|
||||
"build": "compile",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:validate": "compile validate",
|
||||
|
||||
"lint": "eslint \"src/**/*.ts\"",
|
||||
"lint:fix": "eslint --fix \"src/**/*.ts\"",
|
||||
"format": "prettier --write src/**/*.ts && eslint --fix \"src/**/*.ts\"",
|
||||
"clean": "rm -rf lib && rm -rf types rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14"
|
||||
"@hcengineering/platform-rig": "^0.6.490",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"esbuild-plugin-copy": "~2.1.1",
|
||||
"eslint": "^8.54.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/core": "^0.7.88"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3"
|
||||
"@hcengineering/core": "^0.7.88",
|
||||
"@hcengineering/communication-types": "^0.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -34,5 +44,12 @@
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/index.d.ts",
|
||||
"require": "./lib/index.js",
|
||||
"import": "./lib/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,19 +29,19 @@ import type {
|
||||
import type { EventResult, RequestEvent, ResponseEvent } from './event'
|
||||
|
||||
export interface FindClient {
|
||||
onEvent(event: ResponseEvent): void
|
||||
onEvent: (event: ResponseEvent) => void
|
||||
|
||||
onRequest(event: RequestEvent, promise: Promise<EventResult>): void
|
||||
findMessages: (params: FindMessagesParams, queryId?: number) => Promise<Message[]>
|
||||
|
||||
findMessages(params: FindMessagesParams, queryId?: number): Promise<Message[]>
|
||||
findMessagesGroups: (params: FindMessagesGroupsParams) => Promise<MessagesGroup[]>
|
||||
|
||||
findMessagesGroups(params: FindMessagesGroupsParams): Promise<MessagesGroup[]>
|
||||
findNotificationContexts: (params: FindNotificationContextParams, queryId?: number) => Promise<NotificationContext[]>
|
||||
|
||||
findNotificationContexts(params: FindNotificationContextParams, queryId?: number): Promise<NotificationContext[]>
|
||||
findNotifications: (params: FindNotificationsParams, queryId?: number) => Promise<Notification[]>
|
||||
|
||||
findNotifications(params: FindNotificationsParams, queryId?: number): Promise<Notification[]>
|
||||
findLabels: (params: FindLabelsParams, queryId?: number) => Promise<Label[]>
|
||||
|
||||
findLabels(params: FindLabelsParams, queryId?: number): Promise<Label[]>
|
||||
onRequest: (event: RequestEvent, promise: Promise<EventResult>) => void
|
||||
|
||||
unsubscribeQuery(id: number): Promise<void>
|
||||
unsubscribeQuery: (id: number) => Promise<void>
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ import type {
|
||||
} from '@hcengineering/communication-types'
|
||||
|
||||
export interface DbAdapter {
|
||||
createMessage(
|
||||
createMessage: (
|
||||
card: CardID,
|
||||
type: MessageType,
|
||||
content: RichText,
|
||||
@@ -59,9 +59,9 @@ export interface DbAdapter {
|
||||
data?: MessageData,
|
||||
externalId?: string,
|
||||
id?: MessageID
|
||||
): Promise<{ id: MessageID; created: Date }>
|
||||
) => Promise<{ id: MessageID, created: Date }>
|
||||
|
||||
createPatch(
|
||||
createPatch: (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -69,73 +69,73 @@ export interface DbAdapter {
|
||||
data: PatchData,
|
||||
creator: SocialID,
|
||||
created: Date
|
||||
): Promise<void>
|
||||
) => Promise<void>
|
||||
|
||||
removePatches(card: CardID): Promise<void>
|
||||
removePatches: (card: CardID) => Promise<void>
|
||||
|
||||
createMessagesGroup(card: CardID, blobId: BlobID, fromDate: Date, toDate: Date, count: number): Promise<void>
|
||||
removeMessagesGroup(card: CardID, blobId: BlobID): Promise<void>
|
||||
createMessagesGroup: (card: CardID, blobId: BlobID, fromDate: Date, toDate: Date, count: number) => Promise<void>
|
||||
removeMessagesGroup: (card: CardID, blobId: BlobID) => Promise<void>
|
||||
|
||||
createReaction(
|
||||
createReaction: (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
reaction: string,
|
||||
creator: SocialID,
|
||||
created: Date
|
||||
): Promise<void>
|
||||
removeReaction(
|
||||
) => Promise<void>
|
||||
removeReaction: (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
reaction: string,
|
||||
creator: SocialID
|
||||
): Promise<void>
|
||||
) => Promise<void>
|
||||
|
||||
createFile(
|
||||
createFile: (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
data: FileData,
|
||||
creator: SocialID,
|
||||
created: Date
|
||||
): Promise<void>
|
||||
removeFiles(card: CardID, query: RemoveFileQuery): Promise<void>
|
||||
) => Promise<void>
|
||||
removeFiles: (card: CardID, query: RemoveFileQuery) => Promise<void>
|
||||
|
||||
createLinkPreview(
|
||||
createLinkPreview: (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
data: LinkPreviewData,
|
||||
creator: SocialID,
|
||||
created: Date
|
||||
): Promise<LinkPreviewID>
|
||||
) => Promise<LinkPreviewID>
|
||||
|
||||
removeLinkPreview(card: CardID, message: MessageID, id: LinkPreviewID): Promise<void>
|
||||
removeLinkPreview: (card: CardID, message: MessageID, id: LinkPreviewID) => Promise<void>
|
||||
|
||||
createThread(
|
||||
createThread: (
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
thread: CardID,
|
||||
threadType: CardType,
|
||||
created: Date
|
||||
): Promise<void>
|
||||
removeThreads(query: RemoveThreadQuery): Promise<void>
|
||||
updateThread(thread: CardID, update: ThreadUpdates): Promise<void>
|
||||
) => Promise<void>
|
||||
removeThreads: (query: RemoveThreadQuery) => Promise<void>
|
||||
updateThread: (thread: CardID, update: ThreadUpdates) => Promise<void>
|
||||
|
||||
findMessages(params: FindMessagesParams): Promise<Message[]>
|
||||
findMessagesGroups(params: FindMessagesGroupsParams): Promise<MessagesGroup[]>
|
||||
findThread(thread: CardID): Promise<Thread | undefined>
|
||||
findMessages: (params: FindMessagesParams) => Promise<Message[]>
|
||||
findMessagesGroups: (params: FindMessagesGroupsParams) => Promise<MessagesGroup[]>
|
||||
findThread: (thread: CardID) => Promise<Thread | undefined>
|
||||
|
||||
addCollaborators(card: CardID, cardType: CardType, collaborators: AccountID[], date?: Date): Promise<AccountID[]>
|
||||
removeCollaborators(card: CardID, query: RemoveCollaboratorsQuery): Promise<void>
|
||||
getCollaboratorsCursor(card: CardID, date: Date, size?: number): AsyncIterable<Collaborator[]>
|
||||
addCollaborators: (card: CardID, cardType: CardType, collaborators: AccountID[], date?: Date) => Promise<AccountID[]>
|
||||
removeCollaborators: (card: CardID, query: RemoveCollaboratorsQuery) => Promise<void>
|
||||
getCollaboratorsCursor: (card: CardID, date: Date, size?: number) => AsyncIterable<Collaborator[]>
|
||||
|
||||
findCollaborators(params: FindCollaboratorsParams): Promise<Collaborator[]>
|
||||
updateCollaborators(query: FindCollaboratorsParams, update: CollaboratorUpdates): Promise<void>
|
||||
findCollaborators: (params: FindCollaboratorsParams) => Promise<Collaborator[]>
|
||||
updateCollaborators: (query: FindCollaboratorsParams, update: CollaboratorUpdates) => Promise<void>
|
||||
|
||||
createNotification(
|
||||
createNotification: (
|
||||
context: ContextID,
|
||||
message: MessageID,
|
||||
messageCreated: Date,
|
||||
@@ -143,44 +143,44 @@ export interface DbAdapter {
|
||||
read: boolean,
|
||||
content: NotificationContent | undefined,
|
||||
created: Date
|
||||
): Promise<NotificationID>
|
||||
updateNotification(query: UpdateNotificationQuery, updates: NotificationUpdates): Promise<void>
|
||||
removeNotifications(query: RemoveNotificationsQuery): Promise<NotificationID[]>
|
||||
) => Promise<NotificationID>
|
||||
updateNotification: (query: UpdateNotificationQuery, updates: NotificationUpdates) => Promise<void>
|
||||
removeNotifications: (query: RemoveNotificationsQuery) => Promise<NotificationID[]>
|
||||
|
||||
createContext(
|
||||
createContext: (
|
||||
account: AccountID,
|
||||
card: CardID,
|
||||
lastUpdate: Date,
|
||||
lastView: Date,
|
||||
lastNotify?: Date
|
||||
): Promise<ContextID>
|
||||
updateContext(context: ContextID, account: AccountID, updates: NotificationContextUpdates): Promise<void>
|
||||
removeContexts(query: RemoveNotificationContextQuery): Promise<void>
|
||||
) => Promise<ContextID>
|
||||
updateContext: (context: ContextID, account: AccountID, updates: NotificationContextUpdates) => Promise<void>
|
||||
removeContexts: (query: RemoveNotificationContextQuery) => Promise<void>
|
||||
|
||||
findNotificationContexts(params: FindNotificationContextParams): Promise<NotificationContext[]>
|
||||
findNotifications(params: FindNotificationsParams): Promise<Notification[]>
|
||||
findNotificationContexts: (params: FindNotificationContextParams) => Promise<NotificationContext[]>
|
||||
findNotifications: (params: FindNotificationsParams) => Promise<Notification[]>
|
||||
|
||||
createLabel(label: LabelID, card: CardID, cardType: CardType, account: AccountID, created: Date): Promise<void>
|
||||
removeLabels(query: RemoveLabelQuery): Promise<void>
|
||||
findLabels(params: FindLabelsParams): Promise<Label[]>
|
||||
updateLabels(card: CardID, update: LabelUpdates): Promise<void>
|
||||
createLabel: (label: LabelID, card: CardID, cardType: CardType, account: AccountID, created: Date) => Promise<void>
|
||||
removeLabels: (query: RemoveLabelQuery) => Promise<void>
|
||||
findLabels: (params: FindLabelsParams) => Promise<Label[]>
|
||||
updateLabels: (card: CardID, update: LabelUpdates) => Promise<void>
|
||||
|
||||
getAccountsByPersonIds(ids: string[]): Promise<AccountID[]>
|
||||
getNameByAccount(id: AccountID): Promise<string | undefined>
|
||||
getAccountsByPersonIds: (ids: string[]) => Promise<AccountID[]>
|
||||
getNameByAccount: (id: AccountID) => Promise<string | undefined>
|
||||
|
||||
close(): void
|
||||
close: () => void
|
||||
}
|
||||
|
||||
export type RemoveFileQuery = {
|
||||
export interface RemoveFileQuery {
|
||||
message: MessageID
|
||||
blobId: BlobID
|
||||
}
|
||||
export type RemoveThreadQuery = Partial<Pick<Thread, 'card' | 'thread' | 'message'>>
|
||||
export type RemoveCollaboratorsQuery = {
|
||||
export interface RemoveCollaboratorsQuery {
|
||||
accounts?: AccountID[]
|
||||
}
|
||||
export type RemoveNotificationContextQuery = Partial<Pick<NotificationContext, 'id' | 'account' | 'card'>>
|
||||
export type RemoveNotificationsQuery = {
|
||||
export interface RemoveNotificationsQuery {
|
||||
context: ContextID
|
||||
account: AccountID
|
||||
ids: NotificationID[]
|
||||
@@ -188,7 +188,7 @@ export type RemoveNotificationsQuery = {
|
||||
export type RemoveLabelQuery = Partial<Pick<Label, 'card' | 'label' | 'account'>>
|
||||
|
||||
export type NotificationUpdates = Partial<Pick<Notification, 'read'>>
|
||||
export type UpdateNotificationQuery = {
|
||||
export interface UpdateNotificationQuery {
|
||||
context: ContextID
|
||||
account: AccountID
|
||||
type?: NotificationType
|
||||
@@ -198,7 +198,7 @@ export type UpdateNotificationQuery = {
|
||||
|
||||
export type NotificationContextUpdates = Partial<Pick<NotificationContext, 'lastView' | 'lastUpdate' | 'lastNotify'>>
|
||||
|
||||
export type ThreadUpdates = {
|
||||
export interface ThreadUpdates {
|
||||
threadType?: CardType
|
||||
lastReply?: Date
|
||||
replies?: 'increment' | 'decrement'
|
||||
|
||||
@@ -20,7 +20,7 @@ import type {
|
||||
NotificationRequestEvent,
|
||||
NotificationRequestEventType
|
||||
} from './requestEvents/notification'
|
||||
import { type LabelResponseEvent, LabelResponseEventType } from './responseEvents/label'
|
||||
import type { LabelResponseEvent, LabelResponseEventType } from './responseEvents/label'
|
||||
import type { MessageResponseEvent, MessageResponseEventType } from './responseEvents/message'
|
||||
import type { NotificationResponseEvent, NotificationResponseEventType } from './responseEvents/notification'
|
||||
import type { CardRequestEvent, CardRequestEventType } from './requestEvents/card'
|
||||
@@ -41,6 +41,7 @@ export type RequestEventType =
|
||||
| LabelRequestEventType
|
||||
| CardRequestEventType
|
||||
export type RequestEvent = MessageRequestEvent | NotificationRequestEvent | LabelRequestEvent | CardRequestEvent
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type EventResult = MessageEventResult | NotificationEventResult | {}
|
||||
|
||||
export type ResponseEventType =
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
export * from './client'
|
||||
export * from './db'
|
||||
export * from './query'
|
||||
export type * from './client'
|
||||
export type * from './db'
|
||||
export type * from './query'
|
||||
export * from './event'
|
||||
export * from './serverApi'
|
||||
export type * from './serverApi'
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
export type BaseRequestEvent = {
|
||||
export interface BaseRequestEvent {
|
||||
_id?: string
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ export interface RemoveCollaboratorsEvent extends BaseRequestEvent {
|
||||
created?: Date
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type NotificationEventResult = CreateNotificationContextResult | {}
|
||||
|
||||
export interface CreateNotificationContextResult {
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
export type BaseResponseEvent = {
|
||||
export interface BaseResponseEvent {
|
||||
_id?: string
|
||||
}
|
||||
|
||||
@@ -37,26 +37,26 @@ export interface SessionData {
|
||||
}
|
||||
|
||||
export interface ServerApi {
|
||||
findMessages(session: SessionData, params: FindMessagesParams, queryId?: number | string): Promise<Message[]>
|
||||
findMessagesGroups(session: SessionData, params: FindMessagesGroupsParams): Promise<MessagesGroup[]>
|
||||
findNotificationContexts(
|
||||
findMessages: (session: SessionData, params: FindMessagesParams, queryId?: number | string) => Promise<Message[]>
|
||||
findMessagesGroups: (session: SessionData, params: FindMessagesGroupsParams) => Promise<MessagesGroup[]>
|
||||
findNotificationContexts: (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: number | string
|
||||
): Promise<NotificationContext[]>
|
||||
findNotifications(
|
||||
) => Promise<NotificationContext[]>
|
||||
findNotifications: (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: number | string
|
||||
): Promise<Notification[]>
|
||||
) => Promise<Notification[]>
|
||||
|
||||
findLabels(session: SessionData, params: FindLabelsParams): Promise<Label[]>
|
||||
findCollaborators(session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]>
|
||||
findLabels: (session: SessionData, params: FindLabelsParams) => Promise<Label[]>
|
||||
findCollaborators: (session: SessionData, params: FindCollaboratorsParams) => Promise<Collaborator[]>
|
||||
|
||||
event(session: SessionData, event: RequestEvent): Promise<EventResult>
|
||||
event: (session: SessionData, event: RequestEvent) => Promise<EventResult>
|
||||
|
||||
unsubscribeQuery(session: SessionData, id: number): Promise<void>
|
||||
unsubscribeQuery: (session: SessionData, id: number) => Promise<void>
|
||||
|
||||
closeSession(sessionId: string): Promise<void>
|
||||
close(): Promise<void>
|
||||
closeSession: (sessionId: string) => Promise<void>
|
||||
close: () => Promise<void>
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"extends": "./node_modules/@hcengineering/platform-rig/profiles/default/tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./lib",
|
||||
"declarationDir": "./types",
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
"tsBuildInfoFile": ".build/build.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "lib", "dist", "types", "bundle"]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
extends: ['./node_modules/@hcengineering/platform-rig/profiles/default/eslint.config.json'],
|
||||
parserOptions: {
|
||||
tsconfigRootDir: __dirname,
|
||||
project: './tsconfig.json'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json",
|
||||
"rigPackageName": "@hcengineering/platform-rig"
|
||||
}
|
||||
@@ -1,49 +1,65 @@
|
||||
{
|
||||
"name": "@hcengineering/communication-server",
|
||||
"version": "0.1.0",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"main": "lib/index.js",
|
||||
"svelte": "src/index.ts",
|
||||
"types": "types/index.d.ts",
|
||||
"files": [
|
||||
"dist/index.js",
|
||||
"dist/index.cjs",
|
||||
"types/**/*.d.ts"
|
||||
"lib/**/*",
|
||||
"types/**/*",
|
||||
"tsconfig.json"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "bun run build:types && bun run build:node",
|
||||
"build:types": "tsc --project ./tsconfig.json --emitDeclarationOnly --declarationDir ./types",
|
||||
"build:node": "bun build src/index.ts --target node --format cjs --outfile dist/index.js",
|
||||
"lint": "eslint src/*.ts",
|
||||
"format": "prettier --write src/**/*.ts",
|
||||
"clean": "rm -rf dist && rm -rf types && rm -rf .turbo"
|
||||
"build": "compile",
|
||||
"_phase:build": "compile transpile src",
|
||||
"_phase:validate": "compile validate",
|
||||
|
||||
"lint": "eslint \"src/**/*.ts\"",
|
||||
"lint:fix": "eslint --fix \"src/**/*.ts\"",
|
||||
"format": "prettier --write src/**/*.ts && eslint --fix \"src/**/*.ts\"",
|
||||
"clean": "rm -rf lib && rm -rf types rm -rf node_modules"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.1.14",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/ws": "^8.5.13"
|
||||
"@hcengineering/platform-rig": "^0.6.490",
|
||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||
"@typescript-eslint/parser": "^6.11.0",
|
||||
"esbuild": "^0.24.2",
|
||||
"esbuild-plugin-copy": "~2.1.1",
|
||||
"eslint": "^8.54.0",
|
||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-n": "^15.4.0",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.1.0",
|
||||
"typescript": "^5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/account-client": "^0.7.88",
|
||||
"@hcengineering/communication-cockroach": "workspace:*",
|
||||
"@hcengineering/communication-sdk-types": "workspace:*",
|
||||
"@hcengineering/communication-types": "workspace:*",
|
||||
"@hcengineering/communication-yaml": "workspace:*",
|
||||
"@hcengineering/communication-cockroach": "^0.1.0",
|
||||
"@hcengineering/communication-sdk-types": "^0.1.0",
|
||||
"@hcengineering/communication-shared": "^0.1.0",
|
||||
"@hcengineering/communication-types": "^0.1.0",
|
||||
"@hcengineering/communication-yaml": "^0.1.0",
|
||||
"@hcengineering/core": "^0.7.88",
|
||||
"@hcengineering/server-token": "^0.7.88",
|
||||
"@hcengineering/platform": "^0.7.88",
|
||||
"@hcengineering/server-token": "^0.7.88",
|
||||
"@hcengineering/text-core": "^0.7.88",
|
||||
"@hcengineering/text-markdown": "^0.7.88",
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.6.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/hcengineering/communication.git"
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./types/index.d.ts",
|
||||
"require": "./lib/index.js",
|
||||
"import": "./lib/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,33 +17,33 @@ export class ApiError extends Error {
|
||||
public code: number
|
||||
public message: string
|
||||
|
||||
private constructor(code: number, message: string) {
|
||||
private constructor (code: number, message: string) {
|
||||
super(message)
|
||||
this.code = code
|
||||
this.message = message
|
||||
Object.setPrototypeOf(this, ApiError.prototype)
|
||||
}
|
||||
|
||||
static badRequest(message: string): ApiError {
|
||||
static badRequest (message: string): ApiError {
|
||||
return new ApiError(400, `Bad Request: ${message}`)
|
||||
}
|
||||
|
||||
static forbidden(message: string): ApiError {
|
||||
static forbidden (message: string): ApiError {
|
||||
return new ApiError(403, `Forbidden: ${message}`)
|
||||
}
|
||||
|
||||
static notFound(message: string): ApiError {
|
||||
static notFound (message: string): ApiError {
|
||||
return new ApiError(404, `Not Found: ${message}`)
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
toJSON (): object {
|
||||
return {
|
||||
code: this.code,
|
||||
message: this.message
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
toString (): string {
|
||||
return JSON.stringify(this.toJSON())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,12 +39,12 @@ import type { BroadcastSessionsFunc, QueryId } from './types'
|
||||
import { buildMiddlewares, Middlewares } from './middlewares'
|
||||
|
||||
export class Api implements ServerApi {
|
||||
private constructor(
|
||||
private constructor (
|
||||
private readonly ctx: MeasureContext,
|
||||
private readonly middlewares: Middlewares
|
||||
) {}
|
||||
|
||||
static async create(
|
||||
static async create (
|
||||
ctx: MeasureContext,
|
||||
workspace: WorkspaceID,
|
||||
dbUrl: string,
|
||||
@@ -63,15 +63,15 @@ export class Api implements ServerApi {
|
||||
return new Api(ctx, middleware)
|
||||
}
|
||||
|
||||
async findMessages(session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
async findMessages (session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
return await this.middlewares.findMessages(session, params, queryId)
|
||||
}
|
||||
|
||||
async findMessagesGroups(session: SessionData, params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
async findMessagesGroups (session: SessionData, params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
return await this.middlewares.findMessagesGroups(session, params)
|
||||
}
|
||||
|
||||
async findNotificationContexts(
|
||||
async findNotificationContexts (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: QueryId
|
||||
@@ -79,7 +79,7 @@ export class Api implements ServerApi {
|
||||
return await this.middlewares.findNotificationContexts(session, params, queryId)
|
||||
}
|
||||
|
||||
async findNotifications(
|
||||
async findNotifications (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: QueryId
|
||||
@@ -87,27 +87,27 @@ export class Api implements ServerApi {
|
||||
return await this.middlewares.findNotifications(session, params, queryId)
|
||||
}
|
||||
|
||||
async findLabels(session: SessionData, params: FindLabelsParams): Promise<Label[]> {
|
||||
async findLabels (session: SessionData, params: FindLabelsParams): Promise<Label[]> {
|
||||
return await this.middlewares.findLabels(session, params)
|
||||
}
|
||||
|
||||
async findCollaborators(session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
async findCollaborators (session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
return await this.middlewares.findCollaborators(session, params)
|
||||
}
|
||||
|
||||
async unsubscribeQuery(session: SessionData, id: number): Promise<void> {
|
||||
async unsubscribeQuery (session: SessionData, id: number): Promise<void> {
|
||||
await this.middlewares.unsubscribeQuery(session, id)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent): Promise<EventResult> {
|
||||
return await this.middlewares.event(session, event)
|
||||
}
|
||||
|
||||
async closeSession(sessionId: string): Promise<void> {
|
||||
async closeSession (sessionId: string): Promise<void> {
|
||||
await this.middlewares.closeSession(sessionId)
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
async close (): Promise<void> {
|
||||
await this.middlewares.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
import type { Metadata } from './types'
|
||||
|
||||
export function getMetadata(): Metadata {
|
||||
export function getMetadata (): Metadata {
|
||||
return {
|
||||
msg2fileUrl: process.env.MSG2FILE_URL ?? '',
|
||||
accountsUrl: process.env.ACCOUNTS_URL ?? '',
|
||||
|
||||
@@ -37,16 +37,16 @@ import type {
|
||||
import type { Middleware, MiddlewareContext, QueryId } from '../types'
|
||||
|
||||
export class BaseMiddleware implements Middleware {
|
||||
constructor(
|
||||
constructor (
|
||||
readonly context: MiddlewareContext,
|
||||
protected readonly next?: Middleware
|
||||
) {}
|
||||
|
||||
async findMessages(session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
async findMessages (session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
return await this.provideFindMessages(session, params, queryId)
|
||||
}
|
||||
|
||||
async findMessagesGroups(
|
||||
async findMessagesGroups (
|
||||
session: SessionData,
|
||||
params: FindMessagesGroupsParams,
|
||||
queryId?: QueryId
|
||||
@@ -54,7 +54,7 @@ export class BaseMiddleware implements Middleware {
|
||||
return await this.provideFindMessagesGroups(session, params, queryId)
|
||||
}
|
||||
|
||||
async findNotificationContexts(
|
||||
async findNotificationContexts (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: QueryId
|
||||
@@ -62,7 +62,7 @@ export class BaseMiddleware implements Middleware {
|
||||
return await this.provideFindNotificationContexts(session, params, queryId)
|
||||
}
|
||||
|
||||
async findNotifications(
|
||||
async findNotifications (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: QueryId
|
||||
@@ -70,106 +70,106 @@ export class BaseMiddleware implements Middleware {
|
||||
return await this.provideFindNotifications(session, params, queryId)
|
||||
}
|
||||
|
||||
async findLabels(session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
async findLabels (session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
return await this.provideFindLabels(session, params, queryId)
|
||||
}
|
||||
|
||||
async findCollaborators(session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
async findCollaborators (session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
return await this.provideFindCollaborators(session, params)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
return await this.provideEvent(session, event, derived)
|
||||
}
|
||||
|
||||
async response(session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
return await this.provideResponse(session, event, derived)
|
||||
async response (session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
await this.provideResponse(session, event, derived)
|
||||
}
|
||||
|
||||
unsubscribeQuery(session: SessionData, queryId: number): void {
|
||||
unsubscribeQuery (session: SessionData, queryId: number): void {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.unsubscribeQuery(session, queryId)
|
||||
this.next.unsubscribeQuery(session, queryId)
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {}
|
||||
closeSession(sessionId: string): void {}
|
||||
close (): void {}
|
||||
closeSession (sessionId: string): void {}
|
||||
|
||||
protected async provideEvent(session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
protected async provideEvent (session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.event(session, event, derived)
|
||||
return await this.next.event(session, event, derived)
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
protected async provideFindMessages(
|
||||
protected async provideFindMessages (
|
||||
session: SessionData,
|
||||
params: FindMessagesParams,
|
||||
queryId?: QueryId
|
||||
): Promise<Message[]> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.findMessages(session, params, queryId)
|
||||
return await this.next.findMessages(session, params, queryId)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
protected async provideFindMessagesGroups(
|
||||
protected async provideFindMessagesGroups (
|
||||
session: SessionData,
|
||||
params: FindMessagesGroupsParams,
|
||||
queryId?: QueryId
|
||||
): Promise<MessagesGroup[]> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.findMessagesGroups(session, params, queryId)
|
||||
return await this.next.findMessagesGroups(session, params, queryId)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
protected async provideFindNotificationContexts(
|
||||
protected async provideFindNotificationContexts (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: QueryId
|
||||
): Promise<NotificationContext[]> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.findNotificationContexts(session, params, queryId)
|
||||
return await this.next.findNotificationContexts(session, params, queryId)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
protected async provideFindNotifications(
|
||||
protected async provideFindNotifications (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: QueryId
|
||||
): Promise<Notification[]> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.findNotifications(session, params, queryId)
|
||||
return await this.next.findNotifications(session, params, queryId)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
protected async provideFindLabels(
|
||||
protected async provideFindLabels (
|
||||
session: SessionData,
|
||||
params: FindLabelsParams,
|
||||
queryId?: QueryId
|
||||
): Promise<Label[]> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.findLabels(session, params, queryId)
|
||||
return await this.next.findLabels(session, params, queryId)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
protected async provideFindCollaborators(
|
||||
protected async provideFindCollaborators (
|
||||
session: SessionData,
|
||||
params: FindCollaboratorsParams
|
||||
): Promise<Collaborator[]> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.findCollaborators(session, params)
|
||||
return await this.next.findCollaborators(session, params)
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
protected async provideResponse(session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
protected async provideResponse (session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
if (this.next !== undefined) {
|
||||
return this.next.response(session, event, derived)
|
||||
await this.next.response(session, event, derived)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,14 +51,15 @@ interface SessionInfo {
|
||||
export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
private readonly dataBySessionId = new Map<string, SessionInfo>()
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly broadcastFn: BroadcastSessionsFunc,
|
||||
readonly context: MiddlewareContext,
|
||||
next?: Middleware
|
||||
) {
|
||||
super(context, next)
|
||||
}
|
||||
async findMessages(session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
|
||||
async findMessages (session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
this.createSession(session)
|
||||
|
||||
const result = await this.provideFindMessages(session, params, queryId)
|
||||
@@ -68,7 +69,7 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
return result
|
||||
}
|
||||
|
||||
async findMessagesGroups(
|
||||
async findMessagesGroups (
|
||||
session: SessionData,
|
||||
params: FindMessagesGroupsParams,
|
||||
queryId?: QueryId
|
||||
@@ -77,7 +78,7 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
return await this.provideFindMessagesGroups(session, params, queryId)
|
||||
}
|
||||
|
||||
async findNotificationContexts(
|
||||
async findNotificationContexts (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: QueryId
|
||||
@@ -91,7 +92,7 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
return result
|
||||
}
|
||||
|
||||
async findNotifications(
|
||||
async findNotifications (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: QueryId
|
||||
@@ -100,17 +101,17 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
return await this.provideFindNotifications(session, params, queryId)
|
||||
}
|
||||
|
||||
async findLabels(session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
async findLabels (session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
this.createSession(session)
|
||||
return await this.provideFindLabels(session, params, queryId)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
this.createSession(session)
|
||||
return await this.provideEvent(session, event, derived)
|
||||
}
|
||||
|
||||
unsubscribeQuery(session: SessionData, queryId: number): void {
|
||||
unsubscribeQuery (session: SessionData, queryId: number): void {
|
||||
if (session.sessionId == null) return
|
||||
const data = this.dataBySessionId.get(session.sessionId)
|
||||
if (data == null) return
|
||||
@@ -119,7 +120,7 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
data.contextQueries.delete(queryId)
|
||||
}
|
||||
|
||||
async response(session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
async response (session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
const sessionIds: string[] = []
|
||||
for (const [sessionId, session] of this.dataBySessionId.entries()) {
|
||||
if (this.match(event, session)) {
|
||||
@@ -137,22 +138,22 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
await this.provideResponse(session, event, derived)
|
||||
}
|
||||
|
||||
closeSession(sessionId: string): void {
|
||||
closeSession (sessionId: string): void {
|
||||
this.dataBySessionId.delete(sessionId)
|
||||
}
|
||||
|
||||
close(): void {
|
||||
close (): void {
|
||||
this.dataBySessionId.clear()
|
||||
}
|
||||
|
||||
private subscribeMessageQuery(session: SessionData, queryId: QueryId, params: Record<string, any>): void {
|
||||
private subscribeMessageQuery (session: SessionData, queryId: QueryId, params: Record<string, any>): void {
|
||||
const data = this.createSession(session)
|
||||
if (data == null) return
|
||||
|
||||
data.messageQueries.set(queryId, params as FindMessagesParams)
|
||||
}
|
||||
|
||||
private subscribeContextQuery(session: SessionData, queryId: QueryId, result: NotificationContext[]): void {
|
||||
private subscribeContextQuery (session: SessionData, queryId: QueryId, result: NotificationContext[]): void {
|
||||
const data = this.createSession(session)
|
||||
if (data == null) return
|
||||
|
||||
@@ -162,7 +163,7 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
data.contextQueries.set(queryId, new Set([...current, ...cards]))
|
||||
}
|
||||
|
||||
private createSession(session: SessionData): SessionInfo | undefined {
|
||||
private createSession (session: SessionData): SessionInfo | undefined {
|
||||
const id = session.sessionId
|
||||
if (id == null) return
|
||||
if (!this.dataBySessionId.has(id)) {
|
||||
@@ -176,7 +177,7 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
return this.dataBySessionId.get(id)
|
||||
}
|
||||
|
||||
private match(event: ResponseEvent, info: SessionInfo): boolean {
|
||||
private match (event: ResponseEvent, info: SessionInfo): boolean {
|
||||
switch (event.type) {
|
||||
case MessageResponseEventType.MessageCreated:
|
||||
return this.matchMessagesQuery(
|
||||
@@ -238,8 +239,8 @@ export class BroadcastMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private matchMessagesQuery(
|
||||
params: { ids: MessageID[]; card: CardID },
|
||||
private matchMessagesQuery (
|
||||
params: { ids: MessageID[], card: CardID },
|
||||
queries: FindMessagesParams[],
|
||||
cards: Set<CardID>
|
||||
): boolean {
|
||||
|
||||
@@ -27,14 +27,14 @@ import type { Middleware, MiddlewareContext } from '../types'
|
||||
import { BaseMiddleware } from './base'
|
||||
|
||||
export class DateMiddleware extends BaseMiddleware implements Middleware {
|
||||
constructor(
|
||||
constructor (
|
||||
readonly context: MiddlewareContext,
|
||||
next?: Middleware
|
||||
) {
|
||||
super(context, next)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
if (derived) return await this.provideEvent(session, event, derived)
|
||||
switch (event.type) {
|
||||
case MessageRequestEventType.CreateFile:
|
||||
@@ -52,10 +52,10 @@ export class DateMiddleware extends BaseMiddleware implements Middleware {
|
||||
break
|
||||
}
|
||||
|
||||
return this.provideEvent(session, event, derived)
|
||||
return await this.provideEvent(session, event, derived)
|
||||
}
|
||||
|
||||
private isSystem(session: SessionData): boolean {
|
||||
private isSystem (session: SessionData): boolean {
|
||||
const account = session.account
|
||||
return systemAccountUuid === account.uuid
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ interface Result {
|
||||
}
|
||||
|
||||
export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly db: DbAdapter,
|
||||
readonly context: MiddlewareContext,
|
||||
next?: Middleware
|
||||
@@ -101,43 +101,43 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
super(context, next)
|
||||
}
|
||||
|
||||
async findMessages(_: SessionData, params: FindMessagesParams): Promise<Message[]> {
|
||||
async findMessages (_: SessionData, params: FindMessagesParams): Promise<Message[]> {
|
||||
return await this.db.findMessages(params)
|
||||
}
|
||||
|
||||
async findMessagesGroups(_: SessionData, params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
async findMessagesGroups (_: SessionData, params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
return await this.db.findMessagesGroups(params)
|
||||
}
|
||||
|
||||
async findNotificationContexts(
|
||||
async findNotificationContexts (
|
||||
_: SessionData,
|
||||
params: FindNotificationContextParams
|
||||
): Promise<NotificationContext[]> {
|
||||
return await this.db.findNotificationContexts(params)
|
||||
}
|
||||
|
||||
async findNotifications(_: SessionData, params: FindNotificationsParams): Promise<Notification[]> {
|
||||
async findNotifications (_: SessionData, params: FindNotificationsParams): Promise<Notification[]> {
|
||||
return await this.db.findNotifications(params)
|
||||
}
|
||||
|
||||
async findLabels(_: SessionData, params: FindLabelsParams): Promise<Label[]> {
|
||||
async findLabels (_: SessionData, params: FindLabelsParams): Promise<Label[]> {
|
||||
return await this.db.findLabels(params)
|
||||
}
|
||||
|
||||
async findCollaborators(_: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
async findCollaborators (_: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
return await this.db.findCollaborators(params)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
const result = await this.processEvent(session, event)
|
||||
if (result.responseEvent) {
|
||||
if (result.responseEvent != null) {
|
||||
void this.context.head?.response(session, result.responseEvent, derived)
|
||||
}
|
||||
|
||||
return result.result ?? {}
|
||||
}
|
||||
|
||||
private async processEvent(session: SessionData, event: RequestEvent): Promise<Result> {
|
||||
private async processEvent (session: SessionData, event: RequestEvent): Promise<Result> {
|
||||
switch (event.type) {
|
||||
case MessageRequestEventType.CreateMessage:
|
||||
return await this.createMessage(event)
|
||||
@@ -190,7 +190,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async updateThread(event: UpdateThreadEvent): Promise<Result> {
|
||||
private async updateThread (event: UpdateThreadEvent): Promise<Result> {
|
||||
await this.db.updateThread(event.thread, event.updates)
|
||||
return {
|
||||
responseEvent: {
|
||||
@@ -204,7 +204,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async addCollaborators(event: AddCollaboratorsEvent): Promise<Result> {
|
||||
private async addCollaborators (event: AddCollaboratorsEvent): Promise<Result> {
|
||||
const created = event.created ?? new Date()
|
||||
const added = await this.db.addCollaborators(event.card, event.cardType, event.collaborators, created)
|
||||
if (added.length === 0) return {}
|
||||
@@ -221,7 +221,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeCollaborators(event: RemoveCollaboratorsEvent): Promise<Result> {
|
||||
private async removeCollaborators (event: RemoveCollaboratorsEvent): Promise<Result> {
|
||||
if (event.collaborators.length === 0) return {}
|
||||
const created = event.created ?? new Date()
|
||||
await this.db.removeCollaborators(event.card, { accounts: event.collaborators })
|
||||
@@ -239,7 +239,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createMessage(event: CreateMessageEvent): Promise<Result> {
|
||||
private async createMessage (event: CreateMessageEvent): Promise<Result> {
|
||||
const created = event.created ?? new Date()
|
||||
const result = await this.db.createMessage(
|
||||
event.card,
|
||||
@@ -277,7 +277,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createPatch(event: CreatePatchEvent): Promise<Result> {
|
||||
private async createPatch (event: CreatePatchEvent): Promise<Result> {
|
||||
const created = event.created ?? new Date()
|
||||
await this.db.createPatch(
|
||||
event.card,
|
||||
@@ -289,14 +289,14 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
created
|
||||
)
|
||||
|
||||
const patch = {
|
||||
const patch: Patch = {
|
||||
type: event.patchType,
|
||||
messageCreated: event.messageCreated,
|
||||
message: event.message,
|
||||
data: event.data,
|
||||
creator: event.creator,
|
||||
created
|
||||
} as Patch
|
||||
} as any
|
||||
const responseEvent: PatchCreatedEvent = {
|
||||
_id: event._id,
|
||||
type: MessageResponseEventType.PatchCreated,
|
||||
@@ -308,7 +308,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createReaction(event: CreateReactionEvent): Promise<Result> {
|
||||
private async createReaction (event: CreateReactionEvent): Promise<Result> {
|
||||
const created = new Date()
|
||||
await this.db.createReaction(
|
||||
event.card,
|
||||
@@ -337,7 +337,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeReaction(event: RemoveReactionEvent): Promise<Result> {
|
||||
private async removeReaction (event: RemoveReactionEvent): Promise<Result> {
|
||||
await this.db.removeReaction(event.card, event.message, event.messageCreated, event.reaction, event.creator)
|
||||
const responseEvent: ReactionRemovedEvent = {
|
||||
_id: event._id,
|
||||
@@ -353,7 +353,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createFile(event: CreateFileEvent): Promise<Result> {
|
||||
private async createFile (event: CreateFileEvent): Promise<Result> {
|
||||
const created = event.created ?? new Date()
|
||||
await this.db.createFile(event.card, event.message, event.messageCreated, event.data, event.creator, created)
|
||||
const responseEvent: FileCreatedEvent = {
|
||||
@@ -373,7 +373,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeFile(event: RemoveFileEvent): Promise<Result> {
|
||||
private async removeFile (event: RemoveFileEvent): Promise<Result> {
|
||||
await this.db.removeFiles(event.card, { message: event.message, blobId: event.blobId })
|
||||
const responseEvent: FileRemovedEvent = {
|
||||
_id: event._id,
|
||||
@@ -389,7 +389,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createLinkPreview(event: CreateLinkPreviewEvent): Promise<Result> {
|
||||
private async createLinkPreview (event: CreateLinkPreviewEvent): Promise<Result> {
|
||||
const created = new Date()
|
||||
const id = await this.db.createLinkPreview(
|
||||
event.card,
|
||||
@@ -419,7 +419,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeLinkPreview(event: RemoveLinkPreviewEvent): Promise<Result> {
|
||||
private async removeLinkPreview (event: RemoveLinkPreviewEvent): Promise<Result> {
|
||||
await this.db.removeLinkPreview(event.card, event.message, event.id)
|
||||
const responseEvent: LinkPreviewRemovedEvent = {
|
||||
_id: event._id,
|
||||
@@ -435,7 +435,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createNotification(event: CreateNotificationEvent): Promise<Result> {
|
||||
private async createNotification (event: CreateNotificationEvent): Promise<Result> {
|
||||
const id = await this.db.createNotification(
|
||||
event.context,
|
||||
event.message,
|
||||
@@ -465,7 +465,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async updateNotification(event: UpdateNotificationEvent): Promise<Result> {
|
||||
private async updateNotification (event: UpdateNotificationEvent): Promise<Result> {
|
||||
await this.db.updateNotification(event.query, event.updates)
|
||||
const responseEvent: NotificationUpdatedEvent = {
|
||||
_id: event._id,
|
||||
@@ -478,7 +478,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeNotifications(event: RemoveNotificationsEvent): Promise<Result> {
|
||||
private async removeNotifications (event: RemoveNotificationsEvent): Promise<Result> {
|
||||
const ids = await this.db.removeNotifications({
|
||||
context: event.context,
|
||||
account: event.account,
|
||||
@@ -499,7 +499,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createNotificationContext(event: CreateNotificationContextEvent): Promise<Result> {
|
||||
private async createNotificationContext (event: CreateNotificationContextEvent): Promise<Result> {
|
||||
const id = await this.db.createContext(
|
||||
event.account,
|
||||
event.card,
|
||||
@@ -525,7 +525,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeNotificationContext(event: RemoveNotificationContextEvent): Promise<Result> {
|
||||
private async removeNotificationContext (event: RemoveNotificationContextEvent): Promise<Result> {
|
||||
const context = (await this.db.findNotificationContexts({ id: event.context, account: event.account }))[0]
|
||||
if (context === undefined) return {}
|
||||
|
||||
@@ -543,7 +543,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
async updateNotificationContext(event: UpdateNotificationContextEvent): Promise<Result> {
|
||||
async updateNotificationContext (event: UpdateNotificationContextEvent): Promise<Result> {
|
||||
await this.db.updateContext(event.context, event.account, event.updates)
|
||||
|
||||
const responseEvent: NotificationContextUpdatedEvent = {
|
||||
@@ -560,7 +560,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
async createMessagesGroup(event: CreateMessagesGroupEvent): Promise<Result> {
|
||||
async createMessagesGroup (event: CreateMessagesGroupEvent): Promise<Result> {
|
||||
const { fromDate, toDate, count, card, blobId } = event.group
|
||||
await this.db.createMessagesGroup(card, blobId, fromDate, toDate, count)
|
||||
|
||||
@@ -580,13 +580,13 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
async removeMessagesGroup(event: RemoveMessagesGroupEvent): Promise<Result> {
|
||||
async removeMessagesGroup (event: RemoveMessagesGroupEvent): Promise<Result> {
|
||||
await this.db.removeMessagesGroup(event.card, event.blobId)
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
private async createThread(event: CreateThreadEvent): Promise<Result> {
|
||||
private async createThread (event: CreateThreadEvent): Promise<Result> {
|
||||
const date = new Date()
|
||||
await this.db.createThread(event.card, event.message, event.messageCreated, event.thread, event.threadType, date)
|
||||
const responseEvent: ThreadCreatedEvent = {
|
||||
@@ -607,7 +607,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async createLabel(event: CreateLabelEvent): Promise<Result> {
|
||||
private async createLabel (event: CreateLabelEvent): Promise<Result> {
|
||||
const created = new Date()
|
||||
await this.db.createLabel(event.label, event.card, event.cardType, event.account, created)
|
||||
return {
|
||||
@@ -625,7 +625,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeLabel(event: RemoveLabelEvent): Promise<Result> {
|
||||
private async removeLabel (event: RemoveLabelEvent): Promise<Result> {
|
||||
await this.db.removeLabels({
|
||||
label: event.label,
|
||||
card: event.card,
|
||||
@@ -642,7 +642,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async updateCardType(event: UpdateCardTypeEvent): Promise<Result> {
|
||||
private async updateCardType (event: UpdateCardTypeEvent): Promise<Result> {
|
||||
return {
|
||||
responseEvent: {
|
||||
_id: event._id,
|
||||
@@ -655,7 +655,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
private async removeCard(event: RemoveCardEvent): Promise<Result> {
|
||||
private async removeCard (event: RemoveCardEvent): Promise<Result> {
|
||||
return {
|
||||
responseEvent: {
|
||||
_id: event._id,
|
||||
@@ -665,7 +665,7 @@ export class DatabaseMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {
|
||||
close (): void {
|
||||
this.db.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ import type {
|
||||
import { ApiError } from '../error'
|
||||
import type { Middleware, MiddlewareContext, QueryId } from '../types'
|
||||
import { BaseMiddleware } from './base'
|
||||
import { findMessage } from '../triggers/utils.ts'
|
||||
import { findMessage } from '../triggers/utils'
|
||||
|
||||
export class PermissionsMiddleware extends BaseMiddleware implements Middleware {
|
||||
constructor(
|
||||
constructor (
|
||||
readonly db: DbAdapter,
|
||||
readonly context: MiddlewareContext,
|
||||
next?: Middleware
|
||||
@@ -50,7 +50,7 @@ export class PermissionsMiddleware extends BaseMiddleware implements Middleware
|
||||
super(context, next)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
if (derived) return await this.provideEvent(session, event, derived)
|
||||
switch (event.type) {
|
||||
case MessageRequestEventType.CreatePatch: {
|
||||
@@ -92,10 +92,10 @@ export class PermissionsMiddleware extends BaseMiddleware implements Middleware
|
||||
break
|
||||
}
|
||||
|
||||
return this.provideEvent(session, event, derived)
|
||||
return await this.provideEvent(session, event, derived)
|
||||
}
|
||||
|
||||
async checkPatch(session: SessionData, event: CreatePatchEvent): Promise<void> {
|
||||
async checkPatch (session: SessionData, event: CreatePatchEvent): Promise<void> {
|
||||
const account = session.account
|
||||
if (systemAccountUuid === account.uuid) return
|
||||
const socialIds = account.socialIds
|
||||
@@ -117,7 +117,7 @@ export class PermissionsMiddleware extends BaseMiddleware implements Middleware
|
||||
}
|
||||
}
|
||||
|
||||
async findNotificationContexts(
|
||||
async findNotificationContexts (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: QueryId
|
||||
@@ -126,7 +126,7 @@ export class PermissionsMiddleware extends BaseMiddleware implements Middleware
|
||||
return await this.provideFindNotificationContexts(session, paramsWithAccount, queryId)
|
||||
}
|
||||
|
||||
async findNotifications(
|
||||
async findNotifications (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: QueryId
|
||||
@@ -135,26 +135,26 @@ export class PermissionsMiddleware extends BaseMiddleware implements Middleware
|
||||
return await this.provideFindNotifications(session, paramsWithAccount, queryId)
|
||||
}
|
||||
|
||||
async findLabels(session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
async findLabels (session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
const paramsWithAccount = this.expandParamsWithAccount(session, params)
|
||||
return await this.provideFindLabels(session, paramsWithAccount, queryId)
|
||||
}
|
||||
|
||||
private checkSocialId(session: SessionData, creator: SocialID): void {
|
||||
private checkSocialId (session: SessionData, creator: SocialID): void {
|
||||
const account = session.account
|
||||
if (!account.socialIds.includes(creator) && systemAccountUuid !== account.uuid) {
|
||||
throw ApiError.forbidden('social ID is not allowed')
|
||||
}
|
||||
}
|
||||
|
||||
private checkAccount(session: SessionData, creator: AccountID): void {
|
||||
private checkAccount (session: SessionData, creator: AccountID): void {
|
||||
const account = session.account
|
||||
if (account.uuid !== creator && systemAccountUuid !== account.uuid) {
|
||||
throw ApiError.forbidden('account is not allowed')
|
||||
}
|
||||
}
|
||||
|
||||
private onlySystemAccount(session: SessionData): void {
|
||||
private onlySystemAccount (session: SessionData): void {
|
||||
const account = session.account
|
||||
if (systemAccountUuid !== account.uuid) {
|
||||
throw ApiError.forbidden('only system account is allowed')
|
||||
|
||||
@@ -24,7 +24,7 @@ import { notify } from '../notification/notification'
|
||||
export class TriggersMiddleware extends BaseMiddleware implements Middleware {
|
||||
private readonly ctx: MeasureContext
|
||||
|
||||
constructor(
|
||||
constructor (
|
||||
private readonly db: DbAdapter,
|
||||
context: MiddlewareContext,
|
||||
next?: Middleware
|
||||
@@ -39,7 +39,7 @@ export class TriggersMiddleware extends BaseMiddleware implements Middleware {
|
||||
) // 1hour
|
||||
}
|
||||
|
||||
async response(session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
async response (session: SessionData, event: ResponseEvent, derived: boolean): Promise<void> {
|
||||
const ctx: Omit<TriggerCtx, 'ctx'> = {
|
||||
metadata: this.context.metadata,
|
||||
db: this.db,
|
||||
@@ -59,10 +59,10 @@ export class TriggersMiddleware extends BaseMiddleware implements Middleware {
|
||||
ctx: this.ctx.newChild('create-notifications', {})
|
||||
},
|
||||
event
|
||||
).then((res) => void this.propagate(session, res))
|
||||
).then((res) => this.propagate(session, res))
|
||||
}
|
||||
|
||||
private async applyTriggers(session: SessionData, event: ResponseEvent, ctx: Omit<TriggerCtx, 'ctx'>) {
|
||||
private async applyTriggers (session: SessionData, event: ResponseEvent, ctx: Omit<TriggerCtx, 'ctx'>): Promise<void> {
|
||||
const matchedTriggers = triggers.filter(([_, type]) => type === event.type)
|
||||
if (matchedTriggers.length === 0) return
|
||||
|
||||
@@ -83,7 +83,7 @@ export class TriggersMiddleware extends BaseMiddleware implements Middleware {
|
||||
await this.propagate(session, derived)
|
||||
}
|
||||
|
||||
private async propagate(session: SessionData, derived: RequestEvent[]) {
|
||||
private async propagate (session: SessionData, derived: RequestEvent[]): Promise<void> {
|
||||
if (derived.length === 0) return
|
||||
if (this.context.head === undefined) return
|
||||
await Promise.all(derived.map((d) => this.context.head?.event(session, d, true)))
|
||||
|
||||
@@ -39,16 +39,12 @@ import {
|
||||
} from '@hcengineering/communication-types'
|
||||
import { z } from 'zod'
|
||||
|
||||
import type { Middleware, MiddlewareContext, QueryId } from '../types'
|
||||
import type { Middleware, QueryId } from '../types'
|
||||
import { BaseMiddleware } from './base'
|
||||
import { ApiError } from '../error'
|
||||
|
||||
export class ValidateMiddleware extends BaseMiddleware implements Middleware {
|
||||
constructor(context: MiddlewareContext, next?: Middleware) {
|
||||
super(context, next)
|
||||
}
|
||||
|
||||
private validate(data: any, schema: z.ZodObject<any>): void {
|
||||
private validate (data: any, schema: z.ZodObject<any>): void {
|
||||
const validationResult = schema.safeParse(data)
|
||||
if (!validationResult.success) {
|
||||
const errors = validationResult.error.errors.map((err) => err.message)
|
||||
@@ -57,12 +53,12 @@ export class ValidateMiddleware extends BaseMiddleware implements Middleware {
|
||||
}
|
||||
}
|
||||
|
||||
async findMessages(session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
async findMessages (session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
this.validate(params, FindMessagesParamsSchema)
|
||||
return await this.provideFindMessages(session, params, queryId)
|
||||
}
|
||||
|
||||
async findMessagesGroups(
|
||||
async findMessagesGroups (
|
||||
session: SessionData,
|
||||
params: FindMessagesGroupsParams,
|
||||
queryId?: QueryId
|
||||
@@ -71,7 +67,7 @@ export class ValidateMiddleware extends BaseMiddleware implements Middleware {
|
||||
return await this.provideFindMessagesGroups(session, params, queryId)
|
||||
}
|
||||
|
||||
async findNotificationContexts(
|
||||
async findNotificationContexts (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: QueryId
|
||||
@@ -80,7 +76,7 @@ export class ValidateMiddleware extends BaseMiddleware implements Middleware {
|
||||
return await this.provideFindNotificationContexts(session, params, queryId)
|
||||
}
|
||||
|
||||
async findNotifications(
|
||||
async findNotifications (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: QueryId
|
||||
@@ -89,17 +85,17 @@ export class ValidateMiddleware extends BaseMiddleware implements Middleware {
|
||||
return await this.provideFindNotifications(session, params, queryId)
|
||||
}
|
||||
|
||||
async findLabels(session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
async findLabels (session: SessionData, params: FindLabelsParams, queryId?: QueryId): Promise<Label[]> {
|
||||
this.validate(params, FindLabelsParamsSchema)
|
||||
return await this.provideFindLabels(session, params, queryId)
|
||||
}
|
||||
|
||||
async findCollaborators(session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
async findCollaborators (session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
this.validate(params, FindCollaboratorsParamsSchema)
|
||||
return await this.provideFindCollaborators(session, params)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent, derived: boolean): Promise<EventResult> {
|
||||
if (derived) return await this.provideEvent(session, event, derived)
|
||||
switch (event.type) {
|
||||
case MessageRequestEventType.CreateMessage:
|
||||
@@ -184,7 +180,7 @@ const PatchData = z.any()
|
||||
const MessageID = z.string()
|
||||
const NotificationID = z.string()
|
||||
const MessageType = z.string()
|
||||
const MessagesGroup = z.any()
|
||||
const MessagesGroupSchema = z.any()
|
||||
const PatchTypeSchema = z.enum([PatchType.update, PatchType.remove])
|
||||
const RichText = z.string()
|
||||
const SocialID = z.string()
|
||||
@@ -257,7 +253,7 @@ const FindCollaboratorsParamsSchema = FindParamsSchema.extend({
|
||||
card: CardID.optional(),
|
||||
account: z.union([AccountID, z.array(AccountID)]).optional()
|
||||
}).strict()
|
||||
//Events
|
||||
// Events
|
||||
|
||||
const BaseRequestEventSchema = z
|
||||
.object({
|
||||
@@ -265,7 +261,7 @@ const BaseRequestEventSchema = z
|
||||
})
|
||||
.strict()
|
||||
|
||||
//Label events
|
||||
// Label events
|
||||
const CreateLabelEventSchema = BaseRequestEventSchema.extend({
|
||||
type: z.literal(LabelRequestEventType.CreateLabel),
|
||||
label: LabelID,
|
||||
@@ -401,7 +397,7 @@ const UpdateThreadEventSchema = BaseRequestEventSchema.extend({
|
||||
|
||||
const CreateMessagesGroupEventSchema = BaseRequestEventSchema.extend({
|
||||
type: z.literal(MessageRequestEventType.CreateMessagesGroup),
|
||||
group: MessagesGroup
|
||||
group: MessagesGroupSchema
|
||||
}).strict()
|
||||
|
||||
const RemoveMessagesGroupEventSchema = BaseRequestEventSchema.extend({
|
||||
@@ -490,7 +486,7 @@ const RemoveCollaboratorsEventSchema = BaseRequestEventSchema.extend({
|
||||
created: DateSchema.optional()
|
||||
}).strict()
|
||||
|
||||
function deserializeEvent(event: RequestEvent): RequestEvent {
|
||||
function deserializeEvent (event: RequestEvent): RequestEvent {
|
||||
switch (event.type) {
|
||||
case MessageRequestEventType.CreateMessage:
|
||||
case CardRequestEventType.UpdateCardType:
|
||||
@@ -508,12 +504,14 @@ function deserializeEvent(event: RequestEvent): RequestEvent {
|
||||
case MessageRequestEventType.RemoveLinkPreview:
|
||||
return {
|
||||
...event,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
messageCreated: deserializeDate(event.messageCreated)!
|
||||
}
|
||||
case MessageRequestEventType.CreatePatch:
|
||||
case MessageRequestEventType.CreateFile:
|
||||
return {
|
||||
...event,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
messageCreated: deserializeDate(event.messageCreated)!,
|
||||
created: deserializeDate(event.created)
|
||||
}
|
||||
@@ -530,19 +528,24 @@ function deserializeEvent(event: RequestEvent): RequestEvent {
|
||||
...event,
|
||||
group: {
|
||||
...event.group,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
fromDate: deserializeDate(event.group.fromDate)!,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
toDate: deserializeDate(event.group.toDate)!
|
||||
}
|
||||
}
|
||||
case NotificationRequestEventType.CreateNotification:
|
||||
return {
|
||||
...event,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
created: deserializeDate(event.created)!
|
||||
}
|
||||
case NotificationRequestEventType.CreateNotificationContext:
|
||||
return {
|
||||
...event,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
lastView: deserializeDate(event.lastView)!,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
lastUpdate: deserializeDate(event.lastUpdate)!
|
||||
}
|
||||
case NotificationRequestEventType.UpdateNotificationContext:
|
||||
@@ -550,7 +553,9 @@ function deserializeEvent(event: RequestEvent): RequestEvent {
|
||||
...event,
|
||||
updates: {
|
||||
...event.updates,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
lastView: deserializeDate(event.updates.lastView)!,
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
lastUpdate: deserializeDate(event.updates.lastUpdate)!
|
||||
}
|
||||
}
|
||||
@@ -559,7 +564,7 @@ function deserializeEvent(event: RequestEvent): RequestEvent {
|
||||
return event
|
||||
}
|
||||
|
||||
function deserializeDate(date?: Date | string | undefined | null): Date | undefined {
|
||||
function deserializeDate (date?: Date | string | undefined | null): Date | undefined {
|
||||
if (date == null) return undefined
|
||||
if (date instanceof Date) return date
|
||||
return new Date(date)
|
||||
|
||||
@@ -46,7 +46,7 @@ import { TriggersMiddleware } from './middleware/triggers'
|
||||
import { ValidateMiddleware } from './middleware/validate'
|
||||
import { DateMiddleware } from './middleware/date'
|
||||
|
||||
export async function buildMiddlewares(
|
||||
export async function buildMiddlewares (
|
||||
ctx: MeasureContext,
|
||||
workspace: WorkspaceID,
|
||||
metadata: Metadata,
|
||||
@@ -78,12 +78,12 @@ export class Middlewares {
|
||||
|
||||
private readonly middlewares: Middleware[] = []
|
||||
|
||||
private constructor(
|
||||
private constructor (
|
||||
private readonly ctx: MeasureContext,
|
||||
private readonly context: MiddlewareContext
|
||||
) {}
|
||||
|
||||
static async create(
|
||||
static async create (
|
||||
ctx: MeasureContext,
|
||||
context: MiddlewareContext,
|
||||
createFns: MiddlewareCreateFn[]
|
||||
@@ -96,12 +96,12 @@ export class Middlewares {
|
||||
return middlewares
|
||||
}
|
||||
|
||||
private async buildChain(
|
||||
private async buildChain (
|
||||
ctx: MeasureContext,
|
||||
createFns: MiddlewareCreateFn[],
|
||||
context: MiddlewareContext
|
||||
): Promise<Middleware | undefined> {
|
||||
let current: Middleware | undefined = undefined
|
||||
let current: Middleware | undefined
|
||||
for (let index = createFns.length - 1; index >= 0; index--) {
|
||||
const createFn = createFns[index]
|
||||
try {
|
||||
@@ -119,17 +119,17 @@ export class Middlewares {
|
||||
return current
|
||||
}
|
||||
|
||||
async findMessages(session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
async findMessages (session: SessionData, params: FindMessagesParams, queryId?: QueryId): Promise<Message[]> {
|
||||
if (this.head === undefined) return []
|
||||
return await this.head.findMessages(session, params, queryId)
|
||||
}
|
||||
|
||||
async findMessagesGroups(session: SessionData, params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
async findMessagesGroups (session: SessionData, params: FindMessagesGroupsParams): Promise<MessagesGroup[]> {
|
||||
if (this.head === undefined) return []
|
||||
return await this.head.findMessagesGroups(session, params)
|
||||
}
|
||||
|
||||
async findNotificationContexts(
|
||||
async findNotificationContexts (
|
||||
session: SessionData,
|
||||
params: FindNotificationContextParams,
|
||||
queryId?: QueryId
|
||||
@@ -138,7 +138,7 @@ export class Middlewares {
|
||||
return await this.head.findNotificationContexts(session, params, queryId)
|
||||
}
|
||||
|
||||
async findNotifications(
|
||||
async findNotifications (
|
||||
session: SessionData,
|
||||
params: FindNotificationsParams,
|
||||
queryId?: QueryId
|
||||
@@ -147,32 +147,32 @@ export class Middlewares {
|
||||
return await this.head.findNotifications(session, params, queryId)
|
||||
}
|
||||
|
||||
async findLabels(session: SessionData, params: FindLabelsParams): Promise<Label[]> {
|
||||
async findLabels (session: SessionData, params: FindLabelsParams): Promise<Label[]> {
|
||||
if (this.head === undefined) return []
|
||||
return await this.head.findLabels(session, params)
|
||||
}
|
||||
|
||||
async findCollaborators(session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
async findCollaborators (session: SessionData, params: FindCollaboratorsParams): Promise<Collaborator[]> {
|
||||
if (this.head === undefined) return []
|
||||
return await this.head.findCollaborators(session, params)
|
||||
}
|
||||
|
||||
async unsubscribeQuery(session: SessionData, id: number): Promise<void> {
|
||||
async unsubscribeQuery (session: SessionData, id: number): Promise<void> {
|
||||
if (this.head === undefined) return
|
||||
this.head?.unsubscribeQuery(session, id)
|
||||
}
|
||||
|
||||
async event(session: SessionData, event: RequestEvent): Promise<EventResult> {
|
||||
async event (session: SessionData, event: RequestEvent): Promise<EventResult> {
|
||||
if (this.head === undefined) return {}
|
||||
return (await this.head?.event(session, event, false)) ?? {}
|
||||
}
|
||||
|
||||
async closeSession(sessionId: string): Promise<void> {
|
||||
async closeSession (sessionId: string): Promise<void> {
|
||||
if (this.head === undefined) return
|
||||
this.head.closeSession(sessionId)
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
async close (): Promise<void> {
|
||||
for (const mw of this.middlewares) {
|
||||
try {
|
||||
mw.close()
|
||||
|
||||
@@ -39,11 +39,11 @@ import {
|
||||
|
||||
import type { TriggerCtx } from '../types'
|
||||
import { findAccount } from '../utils'
|
||||
import { findMessage } from '../triggers/utils.ts'
|
||||
import { findMessage } from '../triggers/utils'
|
||||
|
||||
const BATCH_SIZE = 500
|
||||
|
||||
export async function notify(ctx: TriggerCtx, event: ResponseEvent): Promise<RequestEvent[]> {
|
||||
export async function notify (ctx: TriggerCtx, event: ResponseEvent): Promise<RequestEvent[]> {
|
||||
switch (event.type) {
|
||||
case MessageResponseEventType.MessageCreated: {
|
||||
return await notifyMessage(ctx, event.message, event.cardType)
|
||||
@@ -66,7 +66,7 @@ export async function notify(ctx: TriggerCtx, event: ResponseEvent): Promise<Req
|
||||
return []
|
||||
}
|
||||
|
||||
async function removeReactionNotification(
|
||||
async function removeReactionNotification (
|
||||
ctx: TriggerCtx,
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
@@ -94,9 +94,9 @@ async function removeReactionNotification(
|
||||
|
||||
if (toDelete === undefined) return result
|
||||
|
||||
const context = (await ctx.db.findNotificationContexts({ card: card, account: messageAccount, limit: 1 }))[0]
|
||||
const context = (await ctx.db.findNotificationContexts({ card, account: messageAccount, limit: 1 }))[0]
|
||||
if (context == null) return result
|
||||
if (context.lastNotify && context.lastNotify.getTime() === toDelete.created.getTime()) {
|
||||
if (context.lastNotify != null && context.lastNotify.getTime() === toDelete.created.getTime()) {
|
||||
const lastNotification = (
|
||||
await ctx.db.findNotifications({
|
||||
account: messageAccount,
|
||||
@@ -129,7 +129,7 @@ async function removeReactionNotification(
|
||||
|
||||
return result
|
||||
}
|
||||
async function notifyReaction(
|
||||
async function notifyReaction (
|
||||
ctx: TriggerCtx,
|
||||
card: CardID,
|
||||
message: MessageID,
|
||||
@@ -147,7 +147,7 @@ async function notifyReaction(
|
||||
const reactionAccount = await findAccount(ctx, reaction.creator)
|
||||
if (reactionAccount === messageAccount) return result
|
||||
|
||||
const context = (await ctx.db.findNotificationContexts({ card: card, account: messageAccount }))[0]
|
||||
const context = (await ctx.db.findNotificationContexts({ card, account: messageAccount }))[0]
|
||||
let contextId: ContextID | undefined = context?.id
|
||||
|
||||
if (context == null) {
|
||||
@@ -165,7 +165,7 @@ async function notifyReaction(
|
||||
notificationType: NotificationType.Reaction,
|
||||
account: messageAccount,
|
||||
context: contextId,
|
||||
message: message,
|
||||
message,
|
||||
messageCreated,
|
||||
created: reaction.created,
|
||||
content
|
||||
@@ -182,7 +182,7 @@ async function notifyReaction(
|
||||
return result
|
||||
}
|
||||
|
||||
async function notifyMessage(ctx: TriggerCtx, message: Message, cardType: CardType): Promise<RequestEvent[]> {
|
||||
async function notifyMessage (ctx: TriggerCtx, message: Message, cardType: CardType): Promise<RequestEvent[]> {
|
||||
const cursor = ctx.db.getCollaboratorsCursor(message.card, message.created, BATCH_SIZE)
|
||||
const creatorAccount = await findAccount(ctx, message.creator)
|
||||
const result: RequestEvent[] = []
|
||||
@@ -212,7 +212,7 @@ async function notifyMessage(ctx: TriggerCtx, message: Message, cardType: CardTy
|
||||
return result
|
||||
}
|
||||
|
||||
async function processCollaborator(
|
||||
async function processCollaborator (
|
||||
ctx: TriggerCtx,
|
||||
cardType: CardType,
|
||||
message: Message,
|
||||
@@ -250,16 +250,16 @@ async function processCollaborator(
|
||||
return result
|
||||
}
|
||||
|
||||
async function createOrUpdateContext(
|
||||
async function createOrUpdateContext (
|
||||
ctx: TriggerCtx,
|
||||
message: Message,
|
||||
collaborator: AccountID,
|
||||
isOwn: boolean,
|
||||
context?: NotificationContext
|
||||
): Promise<{
|
||||
contextId: ContextID | undefined
|
||||
events: RequestEvent[]
|
||||
}> {
|
||||
contextId: ContextID | undefined
|
||||
events: RequestEvent[]
|
||||
}> {
|
||||
if (context == null) {
|
||||
const contextId = await createContext(
|
||||
ctx,
|
||||
@@ -297,7 +297,7 @@ async function createOrUpdateContext(
|
||||
}
|
||||
}
|
||||
|
||||
async function createContext(
|
||||
async function createContext (
|
||||
ctx: TriggerCtx,
|
||||
account: AccountID,
|
||||
card: CardID,
|
||||
@@ -326,7 +326,7 @@ async function createContext(
|
||||
}
|
||||
}
|
||||
|
||||
function isContextRead(context: NotificationContext): boolean {
|
||||
function isContextRead (context: NotificationContext): boolean {
|
||||
const { lastView, lastUpdate } = context
|
||||
|
||||
if (lastView == null) {
|
||||
|
||||
@@ -24,9 +24,9 @@ import {
|
||||
import { type ActivityTypeUpdate, ActivityUpdateType, MessageType } from '@hcengineering/communication-types'
|
||||
|
||||
import type { TriggerCtx, TriggerFn, Triggers } from '../types'
|
||||
import { getNameBySocialID } from './utils.ts'
|
||||
import { getNameBySocialID } from './utils'
|
||||
|
||||
async function createActivityOnCardTypeUpdate(ctx: TriggerCtx, event: CardTypeUpdatedEvent): Promise<RequestEvent[]> {
|
||||
async function createActivityOnCardTypeUpdate (ctx: TriggerCtx, event: CardTypeUpdatedEvent): Promise<RequestEvent[]> {
|
||||
const updateDate: ActivityTypeUpdate = {
|
||||
type: ActivityUpdateType.Type,
|
||||
newType: event.cardType
|
||||
@@ -51,30 +51,30 @@ async function createActivityOnCardTypeUpdate(ctx: TriggerCtx, event: CardTypeUp
|
||||
]
|
||||
}
|
||||
|
||||
async function onCardTypeUpdates(ctx: TriggerCtx, event: CardTypeUpdatedEvent): Promise<RequestEvent[]> {
|
||||
async function onCardTypeUpdates (ctx: TriggerCtx, event: CardTypeUpdatedEvent): Promise<RequestEvent[]> {
|
||||
await ctx.db.updateCollaborators({ card: event.card }, { cardType: event.cardType })
|
||||
await ctx.db.updateLabels(event.card, { cardType: event.cardType })
|
||||
await ctx.db.updateThread(event.card, { threadType: event.cardType })
|
||||
return []
|
||||
}
|
||||
|
||||
async function removeCollaborators(ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
async function removeCollaborators (ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
await ctx.db.removeCollaborators(event.card, {})
|
||||
return []
|
||||
}
|
||||
|
||||
async function removeLabels(ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
async function removeLabels (ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
await ctx.db.removeLabels({ card: event.card })
|
||||
return []
|
||||
}
|
||||
|
||||
async function removeThreads(ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
async function removeThreads (ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
await ctx.db.removeThreads({ card: event.card })
|
||||
await ctx.db.removeThreads({ thread: event.card })
|
||||
return []
|
||||
}
|
||||
|
||||
async function removeNotificationContexts(ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
async function removeNotificationContexts (ctx: TriggerCtx, event: CardRemovedEvent): Promise<RequestEvent[]> {
|
||||
const result: RequestEvent[] = []
|
||||
const contexts = await ctx.db.findNotificationContexts({ card: event.card })
|
||||
for (const context of contexts) {
|
||||
|
||||
@@ -42,12 +42,12 @@ import type { TriggerCtx, TriggerFn, Triggers } from '../types'
|
||||
import { findAccount } from '../utils'
|
||||
import { findMessageInFiles } from './utils'
|
||||
|
||||
async function onMessagesGroupCreated(ctx: TriggerCtx, event: MessagesGroupCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function onMessagesGroupCreated (ctx: TriggerCtx, event: MessagesGroupCreatedEvent): Promise<RequestEvent[]> {
|
||||
ctx.registeredCards.delete(event.group.card)
|
||||
return []
|
||||
}
|
||||
|
||||
async function onMessagesRemoved(ctx: TriggerCtx, event: PatchCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function onMessagesRemoved (ctx: TriggerCtx, event: PatchCreatedEvent): Promise<RequestEvent[]> {
|
||||
const { card, patch } = event
|
||||
if (patch.type !== PatchType.remove) return []
|
||||
const thread = await ctx.db.findThread(card)
|
||||
@@ -79,7 +79,7 @@ async function onMessagesRemoved(ctx: TriggerCtx, event: PatchCreatedEvent): Pro
|
||||
return result
|
||||
}
|
||||
|
||||
async function onFileCreated(ctx: TriggerCtx, event: FileCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function onFileCreated (ctx: TriggerCtx, event: FileCreatedEvent): Promise<RequestEvent[]> {
|
||||
const message = (await ctx.db.findMessages({ card: event.card, id: event.message, limit: 1 }))[0]
|
||||
if (message !== undefined) return []
|
||||
|
||||
@@ -104,7 +104,7 @@ async function onFileCreated(ctx: TriggerCtx, event: FileCreatedEvent): Promise<
|
||||
]
|
||||
}
|
||||
|
||||
async function onFileRemoved(ctx: TriggerCtx, event: FileRemovedEvent): Promise<RequestEvent[]> {
|
||||
async function onFileRemoved (ctx: TriggerCtx, event: FileRemovedEvent): Promise<RequestEvent[]> {
|
||||
const message = (await ctx.db.findMessages({ card: event.card, id: event.message, limit: 1 }))[0]
|
||||
if (message !== undefined) return []
|
||||
const { blobId } = event
|
||||
@@ -122,7 +122,7 @@ async function onFileRemoved(ctx: TriggerCtx, event: FileRemovedEvent): Promise<
|
||||
]
|
||||
}
|
||||
|
||||
async function registerCard(ctx: TriggerCtx, event: MessageCreatedEvent | PatchCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function registerCard (ctx: TriggerCtx, event: MessageCreatedEvent | PatchCreatedEvent): Promise<RequestEvent[]> {
|
||||
const { workspace, metadata } = ctx
|
||||
let card: CardID
|
||||
switch (event.type) {
|
||||
@@ -152,7 +152,7 @@ async function registerCard(ctx: TriggerCtx, event: MessageCreatedEvent | PatchC
|
||||
return []
|
||||
}
|
||||
|
||||
async function addCollaborators(ctx: TriggerCtx, event: MessageCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function addCollaborators (ctx: TriggerCtx, event: MessageCreatedEvent): Promise<RequestEvent[]> {
|
||||
const { creator, type } = event.message
|
||||
if (type === MessageType.Activity) return []
|
||||
const account = await findAccount(ctx, creator)
|
||||
@@ -188,7 +188,7 @@ async function addCollaborators(ctx: TriggerCtx, event: MessageCreatedEvent): Pr
|
||||
]
|
||||
}
|
||||
|
||||
async function addThreadReply(ctx: TriggerCtx, event: MessageCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function addThreadReply (ctx: TriggerCtx, event: MessageCreatedEvent): Promise<RequestEvent[]> {
|
||||
if (event.message.type !== MessageType.Message || ctx.derived) return []
|
||||
const { message } = event
|
||||
const thread = await ctx.db.findThread(message.card)
|
||||
@@ -217,7 +217,7 @@ async function addThreadReply(ctx: TriggerCtx, event: MessageCreatedEvent): Prom
|
||||
]
|
||||
}
|
||||
|
||||
async function onThreadCreated(ctx: TriggerCtx, event: ThreadCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function onThreadCreated (ctx: TriggerCtx, event: ThreadCreatedEvent): Promise<RequestEvent[]> {
|
||||
let message: Message | undefined = (
|
||||
await ctx.db.findMessages({
|
||||
card: event.thread.card,
|
||||
|
||||
@@ -38,10 +38,10 @@ import {
|
||||
import { groupByArray } from '@hcengineering/core'
|
||||
|
||||
import type { TriggerCtx, TriggerFn, Triggers } from '../types'
|
||||
import { findAccount } from '../utils.ts'
|
||||
import { getAddCollaboratorsMessageContent, getRemoveCollaboratorsMessageContent } from './utils.ts'
|
||||
import { findAccount } from '../utils'
|
||||
import { getAddCollaboratorsMessageContent, getRemoveCollaboratorsMessageContent } from './utils'
|
||||
|
||||
async function onAddedCollaborators(ctx: TriggerCtx, event: AddedCollaboratorsEvent): Promise<RequestEvent[]> {
|
||||
async function onAddedCollaborators (ctx: TriggerCtx, event: AddedCollaboratorsEvent): Promise<RequestEvent[]> {
|
||||
const { card, cardType, collaborators } = event
|
||||
if (collaborators.length === 0) return []
|
||||
const result: RequestEvent[] = []
|
||||
@@ -79,7 +79,7 @@ async function onAddedCollaborators(ctx: TriggerCtx, event: AddedCollaboratorsEv
|
||||
return result
|
||||
}
|
||||
|
||||
async function onRemovedCollaborators(ctx: TriggerCtx, event: RemovedCollaboratorsEvent): Promise<RequestEvent[]> {
|
||||
async function onRemovedCollaborators (ctx: TriggerCtx, event: RemovedCollaboratorsEvent): Promise<RequestEvent[]> {
|
||||
const { card, collaborators } = event
|
||||
if (collaborators.length === 0) return []
|
||||
const result: RequestEvent[] = []
|
||||
@@ -128,7 +128,7 @@ async function onRemovedCollaborators(ctx: TriggerCtx, event: RemovedCollaborato
|
||||
return result
|
||||
}
|
||||
|
||||
async function onNotificationContextUpdated(
|
||||
async function onNotificationContextUpdated (
|
||||
ctx: TriggerCtx,
|
||||
event: NotificationContextUpdatedEvent
|
||||
): Promise<RequestEvent[]> {
|
||||
@@ -166,7 +166,7 @@ async function onNotificationContextUpdated(
|
||||
return result
|
||||
}
|
||||
|
||||
async function onNotificationContextRemoved(
|
||||
async function onNotificationContextRemoved (
|
||||
ctx: TriggerCtx,
|
||||
event: NotificationContextRemovedEvent
|
||||
): Promise<RequestEvent[]> {
|
||||
@@ -184,7 +184,7 @@ async function onNotificationContextRemoved(
|
||||
return result
|
||||
}
|
||||
|
||||
async function onMessagesRemoved(ctx: TriggerCtx, event: PatchCreatedEvent): Promise<RequestEvent[]> {
|
||||
async function onMessagesRemoved (ctx: TriggerCtx, event: PatchCreatedEvent): Promise<RequestEvent[]> {
|
||||
if (event.patch.type !== PatchType.remove) return []
|
||||
|
||||
const notifications = await ctx.db.findNotifications({
|
||||
@@ -200,7 +200,7 @@ async function onMessagesRemoved(ctx: TriggerCtx, event: PatchCreatedEvent): Pro
|
||||
for (const [context, ns] of byContextId.entries()) {
|
||||
result.push({
|
||||
type: NotificationRequestEventType.RemoveNotifications,
|
||||
context: context,
|
||||
context,
|
||||
account: ns[0].account,
|
||||
ids: notifications.map((it) => it.id)
|
||||
})
|
||||
|
||||
@@ -27,10 +27,10 @@ import { loadGroupFile } from '@hcengineering/communication-yaml'
|
||||
import { applyPatches } from '@hcengineering/communication-shared'
|
||||
import type { DbAdapter } from '@hcengineering/communication-sdk-types'
|
||||
|
||||
import type { TriggerCtx } from '../types.ts'
|
||||
import { findAccount } from '../utils.ts'
|
||||
import type { TriggerCtx } from '../types'
|
||||
import { findAccount } from '../utils'
|
||||
|
||||
export async function findMessage(
|
||||
export async function findMessage (
|
||||
db: DbAdapter,
|
||||
filesUrl: string,
|
||||
workspace: WorkspaceID,
|
||||
@@ -45,7 +45,7 @@ export async function findMessage(
|
||||
return await findMessageInFiles(db, filesUrl, workspace, card, id, created)
|
||||
}
|
||||
|
||||
export async function findMessageInFiles(
|
||||
export async function findMessageInFiles (
|
||||
db: DbAdapter,
|
||||
filesUrl: string,
|
||||
workspace: WorkspaceID,
|
||||
@@ -88,19 +88,19 @@ export async function findMessageInFiles(
|
||||
}
|
||||
}
|
||||
|
||||
export async function getNameBySocialID(ctx: TriggerCtx, id: SocialID) {
|
||||
export async function getNameBySocialID (ctx: TriggerCtx, id: SocialID): Promise<string> {
|
||||
const account = await findAccount(ctx, id)
|
||||
return account ? ((await ctx.db.getNameByAccount(account)) ?? 'System') : 'System'
|
||||
return account != null ? ((await ctx.db.getNameByAccount(account)) ?? 'System') : 'System'
|
||||
}
|
||||
|
||||
export async function getAddCollaboratorsMessageContent(
|
||||
export async function getAddCollaboratorsMessageContent (
|
||||
ctx: TriggerCtx,
|
||||
sender: AccountID | undefined,
|
||||
collaborators: AccountID[]
|
||||
): Promise<RichText> {
|
||||
const senderName = sender ? ((await ctx.db.getNameByAccount(sender)) ?? 'System') : 'System'
|
||||
const senderName = sender != null ? ((await ctx.db.getNameByAccount(sender)) ?? 'System') : 'System'
|
||||
|
||||
if (sender && collaborators.length === 1 && collaborators.includes(sender)) {
|
||||
if (sender != null && collaborators.length === 1 && collaborators.includes(sender)) {
|
||||
return `${senderName} joined`
|
||||
}
|
||||
|
||||
@@ -111,14 +111,14 @@ export async function getAddCollaboratorsMessageContent(
|
||||
return `${senderName} added ${collaboratorsNames.join(', ')}`
|
||||
}
|
||||
|
||||
export async function getRemoveCollaboratorsMessageContent(
|
||||
export async function getRemoveCollaboratorsMessageContent (
|
||||
ctx: TriggerCtx,
|
||||
sender: AccountID | undefined,
|
||||
collaborators: AccountID[]
|
||||
): Promise<RichText> {
|
||||
const senderName = sender ? ((await ctx.db.getNameByAccount(sender)) ?? 'System') : 'System'
|
||||
const senderName = sender != null ? ((await ctx.db.getNameByAccount(sender)) ?? 'System') : 'System'
|
||||
|
||||
if (sender && collaborators.length === 1 && collaborators.includes(sender)) {
|
||||
if (sender != null && collaborators.length === 1 && collaborators.includes(sender)) {
|
||||
return `${senderName} left`
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user