mirror of
https://github.com/standardnotes/server
synced 2026-01-19 11:04:28 -05:00
Compare commits
10 Commits
@standardn
...
@standardn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27d04c95a1 | ||
|
|
cd830cdf25 | ||
|
|
5b06ea94f9 | ||
|
|
aba4f90485 | ||
|
|
350621ed52 | ||
|
|
69b4324c78 | ||
|
|
b2be0a7c0b | ||
|
|
cab0dfba39 | ||
|
|
296ca47d63 | ||
|
|
1cad18a681 |
6
.github/ci.env
vendored
6
.github/ci.env
vendored
@@ -23,12 +23,6 @@ MYSQL_USER=std_notes_user
|
||||
MYSQL_PASSWORD=changeme123
|
||||
MYSQL_ROOT_PASSWORD=changeme123
|
||||
|
||||
MONGO_HOST=secondary_db
|
||||
MONGO_PORT=27017
|
||||
MONGO_USERNAME=standardnotes
|
||||
MONGO_PASSWORD=standardnotes
|
||||
MONGO_DATABASE=standardnotes
|
||||
|
||||
AUTH_JWT_SECRET=f95259c5e441f5a4646d76422cfb3df4c4488842901aa50b6c51b8be2e0040e9
|
||||
AUTH_SERVER_ENCRYPTION_SERVER_KEY=1087415dfde3093797f9a7ca93a49e7d7aa1861735eb0d32aae9c303b8c3d060
|
||||
VALET_TOKEN_SECRET=4b886819ebe1e908077c6cae96311b48a8416bd60cc91c03060e15bdf6b30d1f
|
||||
|
||||
17
.github/workflows/e2e-home-server.yml
vendored
17
.github/workflows/e2e-home-server.yml
vendored
@@ -29,7 +29,6 @@ jobs:
|
||||
matrix:
|
||||
db_type: [mysql, sqlite]
|
||||
cache_type: [redis, memory]
|
||||
secondary_db_enabled: [true, false]
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -51,14 +50,6 @@ jobs:
|
||||
MYSQL_DATABASE: standardnotes
|
||||
MYSQL_USER: standardnotes
|
||||
MYSQL_PASSWORD: standardnotes
|
||||
secondary_db:
|
||||
image: mongo:5.0
|
||||
ports:
|
||||
- 27017:27017
|
||||
env:
|
||||
MONGO_INITDB_ROOT_USERNAME: standardnotes
|
||||
MONGO_INITDB_ROOT_PASSWORD: standardnotes
|
||||
MONGO_INITDB_DATABASE: standardnotes
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -98,12 +89,6 @@ jobs:
|
||||
echo "DB_DEBUG_LEVEL=all" >> packages/home-server/.env
|
||||
echo "REDIS_URL=redis://localhost:6379" >> packages/home-server/.env
|
||||
echo "CACHE_TYPE=${{ matrix.cache_type }}" >> packages/home-server/.env
|
||||
echo "SECONDARY_DB_ENABLED=${{ matrix.secondary_db_enabled }}" >> packages/home-server/.env
|
||||
echo "MONGO_HOST=localhost" >> packages/home-server/.env
|
||||
echo "MONGO_PORT=27017" >> packages/home-server/.env
|
||||
echo "MONGO_DATABASE=standardnotes" >> packages/home-server/.env
|
||||
echo "MONGO_USERNAME=standardnotes" >> packages/home-server/.env
|
||||
echo "MONGO_PASSWORD=standardnotes" >> packages/home-server/.env
|
||||
echo "FILES_SERVER_URL=http://localhost:3123" >> packages/home-server/.env
|
||||
echo "E2E_TESTING=true" >> packages/home-server/.env
|
||||
|
||||
@@ -122,7 +107,7 @@ jobs:
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: home-server-failure-logs-${{ inputs.suite }}-${{ matrix.db_type }}-${{ matrix.cache_type }}-${{ matrix.secondary_db_enabled }}
|
||||
name: home-server-failure-logs-${{ inputs.suite }}-${{ matrix.db_type }}-${{ matrix.cache_type }}
|
||||
retention-days: 5
|
||||
path: |
|
||||
logs/output.log
|
||||
|
||||
5
.github/workflows/e2e-self-hosted.yml
vendored
5
.github/workflows/e2e-self-hosted.yml
vendored
@@ -26,8 +26,6 @@ jobs:
|
||||
name: (Self Hosting) E2E Test Suite
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
secondary_db_enabled: [true, false]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
services:
|
||||
@@ -53,7 +51,6 @@ jobs:
|
||||
env:
|
||||
DB_TYPE: mysql
|
||||
CACHE_TYPE: redis
|
||||
SECONDARY_DB_ENABLED: ${{ matrix.secondary_db_enabled }}
|
||||
|
||||
- name: Wait for server to start
|
||||
run: docker/is-available.sh http://localhost:3123 $(pwd)/logs
|
||||
@@ -65,7 +62,7 @@ jobs:
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: self-hosted-failure-logs-${{ inputs.suite }}-${{ matrix.secondary_db_enabled }}
|
||||
name: self-hosted-failure-logs-${{ inputs.suite }}
|
||||
retention-days: 5
|
||||
path: |
|
||||
logs/*.err
|
||||
|
||||
6
.github/workflows/pr.yml
vendored
6
.github/workflows/pr.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Install
|
||||
run: yarn install --immutable
|
||||
run: yarn install
|
||||
|
||||
- name: Build
|
||||
run: yarn build
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Install
|
||||
run: yarn install --immutable
|
||||
run: yarn install
|
||||
|
||||
- name: Build
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
@@ -86,7 +86,7 @@ jobs:
|
||||
node-version-file: '.nvmrc'
|
||||
|
||||
- name: Install
|
||||
run: yarn install --immutable
|
||||
run: yarn install
|
||||
|
||||
- name: Build
|
||||
if: steps.cache-build.outputs.cache-hit != 'true'
|
||||
|
||||
14
.pnp.cjs
generated
14
.pnp.cjs
generated
@@ -5627,7 +5627,7 @@ const RAW_RUNTIME_STATE =
|
||||
["opentelemetry-instrumentation-typeorm", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:0.39.1"],\
|
||||
["prettier", "npm:3.0.3"],\
|
||||
["reflect-metadata", "npm:0.1.13"],\
|
||||
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
|
||||
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.4.0-canary.0"],\
|
||||
["ts-jest", "virtual:fd909b174d079e30b336c4ce72c38a88c1e447767b1a8dd7655e07719a1e31b97807f0931368724fc78897ff15e6a6d00b83316c0f76d11f85111f342e08bb79#npm:29.1.0"],\
|
||||
["typescript", "patch:typescript@npm%3A5.0.4#optional!builtin<compat/typescript>::version=5.0.4&hash=b5f058"],\
|
||||
["winston", "npm:3.9.0"]\
|
||||
@@ -15107,17 +15107,17 @@ const RAW_RUNTIME_STATE =
|
||||
}]\
|
||||
]],\
|
||||
["sqs-consumer", [\
|
||||
["npm:7.3.0", {\
|
||||
"packageLocation": "./.yarn/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
|
||||
["npm:7.4.0-canary.0", {\
|
||||
"packageLocation": "./.yarn/cache/sqs-consumer-npm-7.4.0-canary.0-2eeb36c4ab-7ecff41c97.zip/node_modules/sqs-consumer/",\
|
||||
"packageDependencies": [\
|
||||
["sqs-consumer", "npm:7.3.0"]\
|
||||
["sqs-consumer", "npm:7.4.0-canary.0"]\
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0", {\
|
||||
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-bf07118bf0/0/cache/sqs-consumer-npm-7.3.0-a47c08ef71-367ea2a6f3.zip/node_modules/sqs-consumer/",\
|
||||
["virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.4.0-canary.0", {\
|
||||
"packageLocation": "./.yarn/__virtual__/sqs-consumer-virtual-6da87e1296/0/cache/sqs-consumer-npm-7.4.0-canary.0-2eeb36c4ab-7ecff41c97.zip/node_modules/sqs-consumer/",\
|
||||
"packageDependencies": [\
|
||||
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.3.0"],\
|
||||
["sqs-consumer", "virtual:685a6222c3349423674bb7f0684ba34e2ab20912010f352e04dcf707a156e13183fc382e2417cb37a60f3e7b52fd0178c53181674890e1773eb83e190dc13378#npm:7.4.0-canary.0"],\
|
||||
["@aws-sdk/client-sqs", "npm:3.427.0"],\
|
||||
["@types/aws-sdk__client-sqs", null],\
|
||||
["debug", "virtual:ac3d8e680759ce54399273724d44e041d6c9b73454d191d411a8c44bb27e22f02aaf6ed9d3ad0ac1c298eac4833cff369c9c7b84c573016112c4f84be2cd8543#npm:4.3.4"]\
|
||||
|
||||
Binary file not shown.
@@ -22,7 +22,6 @@ services:
|
||||
environment:
|
||||
DB_TYPE: "${DB_TYPE}"
|
||||
CACHE_TYPE: "${CACHE_TYPE}"
|
||||
SECONDARY_DB_ENABLED: "${SECONDARY_DB_ENABLED}"
|
||||
container_name: server-ci
|
||||
ports:
|
||||
- 3123:3000
|
||||
@@ -61,21 +60,6 @@ services:
|
||||
networks:
|
||||
- standardnotes_self_hosted
|
||||
|
||||
secondary_db:
|
||||
image: mongo:5.0
|
||||
container_name: secondary_db-ci
|
||||
ports:
|
||||
- 27017
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./data/mongo:/data/db
|
||||
environment:
|
||||
MONGO_INITDB_ROOT_USERNAME: standardnotes
|
||||
MONGO_INITDB_ROOT_PASSWORD: standardnotes
|
||||
MONGO_INITDB_DATABASE: standardnotes
|
||||
networks:
|
||||
- standardnotes_self_hosted
|
||||
|
||||
cache:
|
||||
image: redis:6.0-alpine
|
||||
container_name: cache-ci
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [2.32.0](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.7...@standardnotes/analytics@2.32.0) (2023-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [2.31.7](https://github.com/standardnotes/server/compare/@standardnotes/analytics@2.31.6...@standardnotes/analytics@2.31.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -7,7 +7,7 @@ const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Analytic
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
|
||||
@@ -26,6 +26,7 @@ void container.load().then((container) => {
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
|
||||
subscriberFactory.create().start()
|
||||
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
|
||||
|
||||
subscriber.start()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/analytics",
|
||||
"version": "2.31.7",
|
||||
"version": "2.32.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -5,9 +5,9 @@ import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventSubscriberInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { MapperInterface } from '@standardnotes/domain-core'
|
||||
import { MapperInterface, ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const Mixpanel = require('mixpanel')
|
||||
|
||||
@@ -17,8 +17,8 @@ import { AppDataSource } from './DataSource'
|
||||
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
|
||||
import {
|
||||
SNSOpenTelemetryDomainEventPublisher,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
SQSOpenTelemetryDomainEventSubscriber,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { Timer, TimerInterface } from '@standardnotes/time'
|
||||
import { PeriodKeyGeneratorInterface } from '../Domain/Time/PeriodKeyGeneratorInterface'
|
||||
@@ -240,12 +240,14 @@ export class ContainerConfigLoader {
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
|
||||
.bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
|
||||
.toConstantValue(
|
||||
new SQSDomainEventSubscriberFactory(
|
||||
container.get(TYPES.SQS),
|
||||
container.get(TYPES.SQS_QUEUE_URL),
|
||||
container.get(TYPES.DomainEventMessageHandler),
|
||||
new SQSOpenTelemetryDomainEventSubscriber(
|
||||
ServiceIdentifier.NAMES.AnalyticsWorker,
|
||||
container.get<SQSClient>(TYPES.SQS),
|
||||
container.get<string>(TYPES.SQS_QUEUE_URL),
|
||||
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),
|
||||
container.get<winston.Logger>(TYPES.Logger),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ const TYPES = {
|
||||
RevenueModificationMap: Symbol.for('RevenueModificationMap'),
|
||||
// Services
|
||||
DomainEventPublisher: Symbol.for('DomainEventPublisher'),
|
||||
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
|
||||
DomainEventSubscriber: Symbol.for('DomainEventSubscriber'),
|
||||
DomainEventFactory: Symbol.for('DomainEventFactory'),
|
||||
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
|
||||
AnalyticsStore: Symbol.for('AnalyticsStore'),
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.79.13](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.12...@standardnotes/api-gateway@1.79.13) (2023-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/api-gateway
|
||||
|
||||
## [1.79.12](https://github.com/standardnotes/api-gateway/compare/@standardnotes/api-gateway@1.79.11...@standardnotes/api-gateway@1.79.12) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/api-gateway",
|
||||
"version": "1.79.12",
|
||||
"version": "1.79.13",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.159.0](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.8...@standardnotes/auth-server@1.159.0) (2023-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [1.158.8](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.7...@standardnotes/auth-server@1.158.8) (2023-10-16)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **auth:** logs for triggering transition ([1cad18a](https://github.com/standardnotes/server/commit/1cad18a681d933c67244d43dd6f3c2ec405149be))
|
||||
|
||||
## [1.158.7](https://github.com/standardnotes/server/compare/@standardnotes/auth-server@1.158.6...@standardnotes/auth-server@1.158.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -43,7 +43,8 @@ const requestTransition = async (
|
||||
`[TRANSITION ${timestamp}] Found ${users.length} users created between ${startDateString} and ${endDateString}`,
|
||||
)
|
||||
|
||||
let usersTriggered = 0
|
||||
let itemTransitionsTriggered = 0
|
||||
let revisionTransitionsTriggered = 0
|
||||
const forceRun = forceRunParam === 'true'
|
||||
for (const user of users) {
|
||||
const itemsTransitionStatus = await transitionStatusRepository.getStatus(user.uuid, 'items')
|
||||
@@ -60,14 +61,15 @@ const requestTransition = async (
|
||||
continue
|
||||
}
|
||||
|
||||
let wasTransitionRequested = false
|
||||
logger.info(
|
||||
`[TRANSITION ${timestamp}] Transition status for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
|
||||
)
|
||||
|
||||
if (
|
||||
itemsTransitionStatus === null ||
|
||||
itemsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
|
||||
(itemsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
|
||||
) {
|
||||
wasTransitionRequested = true
|
||||
await transitionStatusRepository.remove(user.uuid, 'items')
|
||||
|
||||
await domainEventPublisher.publish(
|
||||
@@ -77,6 +79,8 @@ const requestTransition = async (
|
||||
timestamp,
|
||||
}),
|
||||
)
|
||||
|
||||
itemTransitionsTriggered++
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -84,7 +88,6 @@ const requestTransition = async (
|
||||
revisionsTransitionStatus.value === TransitionStatus.STATUSES.Failed ||
|
||||
(revisionsTransitionStatus.value === TransitionStatus.STATUSES.InProgress && forceRun)
|
||||
) {
|
||||
wasTransitionRequested = true
|
||||
await transitionStatusRepository.remove(user.uuid, 'revisions')
|
||||
|
||||
await domainEventPublisher.publish(
|
||||
@@ -94,19 +97,13 @@ const requestTransition = async (
|
||||
timestamp,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
usersTriggered += 1
|
||||
|
||||
if (wasTransitionRequested) {
|
||||
logger.info(
|
||||
`[TRANSITION ${timestamp}] Transition requested for user ${user.uuid} - items status: ${itemsTransitionStatus?.value}, revisions status: ${revisionsTransitionStatus?.value}, has transition role: ${userHasTransitionRole}`,
|
||||
)
|
||||
revisionTransitionsTriggered++
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(
|
||||
`[TRANSITION ${timestamp}] Triggered transition for ${usersTriggered} users created between ${startDateString} and ${endDateString}`,
|
||||
`[TRANSITION ${timestamp}] Triggered ${itemTransitionsTriggered} item transitions and ${revisionTransitionsTriggered} revision transitions for users created between ${startDateString} and ${endDateString}`,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Logger } from 'winston'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
|
||||
@@ -26,8 +26,7 @@ void container.load().then((container) => {
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(
|
||||
TYPES.Auth_DomainEventSubscriberFactory,
|
||||
)
|
||||
subscriberFactory.create().start()
|
||||
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
|
||||
|
||||
subscriber.start()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/auth-server",
|
||||
"version": "1.158.7",
|
||||
"version": "1.159.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventSubscriberInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { TimerInterface, Timer } from '@standardnotes/time'
|
||||
import { UAParser } from 'ua-parser-js'
|
||||
@@ -90,8 +90,8 @@ import {
|
||||
DirectCallDomainEventPublisher,
|
||||
DirectCallEventMessageHandler,
|
||||
SNSOpenTelemetryDomainEventPublisher,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
SQSOpenTelemetryDomainEventSubscriber,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { GetUserSubscription } from '../Domain/UseCase/GetUserSubscription/GetUserSubscription'
|
||||
import { ChangeCredentials } from '../Domain/UseCase/ChangeCredentials/ChangeCredentials'
|
||||
@@ -188,6 +188,7 @@ import {
|
||||
ControllerContainer,
|
||||
ControllerContainerInterface,
|
||||
MapperInterface,
|
||||
ServiceIdentifier,
|
||||
SharedVaultUser,
|
||||
} from '@standardnotes/domain-core'
|
||||
import { SessionTracePersistenceMapper } from '../Mapping/SessionTracePersistenceMapper'
|
||||
@@ -1262,12 +1263,14 @@ export class ContainerConfigLoader {
|
||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Auth_Logger)))
|
||||
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Auth_DomainEventSubscriberFactory)
|
||||
.bind<DomainEventSubscriberInterface>(TYPES.Auth_DomainEventSubscriber)
|
||||
.toConstantValue(
|
||||
new SQSDomainEventSubscriberFactory(
|
||||
container.get(TYPES.Auth_SQS),
|
||||
container.get(TYPES.Auth_SQS_QUEUE_URL),
|
||||
container.get(TYPES.Auth_DomainEventMessageHandler),
|
||||
new SQSOpenTelemetryDomainEventSubscriber(
|
||||
ServiceIdentifier.NAMES.AuthWorker,
|
||||
container.get<SQSClient>(TYPES.Auth_SQS),
|
||||
container.get<string>(TYPES.Auth_SQS_QUEUE_URL),
|
||||
container.get<DomainEventMessageHandlerInterface>(TYPES.Auth_DomainEventMessageHandler),
|
||||
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ const TYPES = {
|
||||
Auth_WebSocketConnectionTokenDecoder: Symbol.for('Auth_WebSocketConnectionTokenDecoder'),
|
||||
Auth_AuthenticationMethodResolver: Symbol.for('Auth_AuthenticationMethodResolver'),
|
||||
Auth_DomainEventPublisher: Symbol.for('Auth_DomainEventPublisher'),
|
||||
Auth_DomainEventSubscriberFactory: Symbol.for('Auth_DomainEventSubscriberFactory'),
|
||||
Auth_DomainEventSubscriber: Symbol.for('Auth_DomainEventSubscriber'),
|
||||
Auth_DomainEventFactory: Symbol.for('Auth_DomainEventFactory'),
|
||||
Auth_DomainEventMessageHandler: Symbol.for('Auth_DomainEventMessageHandler'),
|
||||
Auth_HTTPClient: Symbol.for('Auth_HTTPClient'),
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.20.0](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.7...@standardnotes/domain-events-infra@1.20.0) (2023-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [1.19.7](https://github.com/standardnotes/server/compare/@standardnotes/domain-events-infra@1.19.6...@standardnotes/domain-events-infra@1.19.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/domain-events-infra",
|
||||
"version": "1.19.7",
|
||||
"version": "1.20.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
@@ -43,7 +43,7 @@
|
||||
"ioredis": "^5.2.4",
|
||||
"opentelemetry-instrumentation-typeorm": "^0.39.1",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"sqs-consumer": "^7.3.0",
|
||||
"sqs-consumer": "7.4.0-canary.0",
|
||||
"winston": "^3.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Consumer } from 'sqs-consumer'
|
||||
import * as OpenTelemetryApi from '@opentelemetry/api'
|
||||
import { Message, SQSClient } from '@aws-sdk/client-sqs'
|
||||
import { DomainEventSubscriberInterface, DomainEventMessageHandlerInterface } from '@standardnotes/domain-events'
|
||||
import { Logger } from 'winston'
|
||||
|
||||
export class SQSOpenTelemetryDomainEventSubscriber implements DomainEventSubscriberInterface {
|
||||
private currentSpan: OpenTelemetryApi.Span | undefined
|
||||
|
||||
constructor(
|
||||
private serviceName: string,
|
||||
private sqs: SQSClient,
|
||||
private queueUrl: string,
|
||||
private domainEventMessageHandler: DomainEventMessageHandlerInterface,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
start(): void {
|
||||
const sqsConsumer = Consumer.create({
|
||||
attributeNames: ['All'],
|
||||
messageAttributeNames: ['All'],
|
||||
queueUrl: this.queueUrl,
|
||||
sqs: this.sqs,
|
||||
preReceiveMessageCallback: this.startParentSpan.bind(this),
|
||||
handleMessage: this.handleMessage.bind(this),
|
||||
})
|
||||
|
||||
sqsConsumer.on('error', this.handleError.bind(this))
|
||||
sqsConsumer.on('processing_error', this.handleError.bind(this))
|
||||
|
||||
sqsConsumer.start()
|
||||
}
|
||||
|
||||
async startParentSpan(): Promise<void> {
|
||||
const tracer = OpenTelemetryApi.trace.getTracer(`${this.serviceName}-domain-event-subscriber`)
|
||||
|
||||
this.currentSpan = tracer.startSpan(this.serviceName, { kind: OpenTelemetryApi.SpanKind.CONSUMER })
|
||||
}
|
||||
|
||||
async handleMessage(message: Message): Promise<void> {
|
||||
await this.domainEventMessageHandler.handleMessage(<string>message.Body)
|
||||
|
||||
if (this.currentSpan) {
|
||||
this.currentSpan.end()
|
||||
this.currentSpan = undefined
|
||||
}
|
||||
}
|
||||
|
||||
handleError(error: Error): void {
|
||||
this.logger.error('Error occured while handling SQS message: %O', error)
|
||||
|
||||
if (this.currentSpan) {
|
||||
this.currentSpan.recordException(error)
|
||||
this.currentSpan.end()
|
||||
this.currentSpan = undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
import { Logger } from 'winston'
|
||||
import * as zlib from 'zlib'
|
||||
import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { OpenTelemetryTracer } from '../OpenTelemetry/OpenTelemetryTracer'
|
||||
import { OpenTelemetryTracerInterface } from '../OpenTelemetry/OpenTelemetryTracerInterface'
|
||||
|
||||
export class SQSOpenTelemetryEventMessageHandler implements DomainEventMessageHandlerInterface {
|
||||
private tracer: OpenTelemetryTracerInterface | undefined
|
||||
|
||||
constructor(
|
||||
private serviceName: string,
|
||||
private handlers: Map<string, DomainEventHandlerInterface>,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
async handleMessage(message: string): Promise<void> {
|
||||
const messageParsed = JSON.parse(message)
|
||||
|
||||
const domainEventJson = zlib.unzipSync(Buffer.from(messageParsed.Message, 'base64')).toString()
|
||||
|
||||
const domainEvent: DomainEventInterface = JSON.parse(domainEventJson)
|
||||
|
||||
domainEvent.createdAt = new Date(domainEvent.createdAt)
|
||||
|
||||
const handler = this.handlers.get(domainEvent.type)
|
||||
if (!handler) {
|
||||
this.logger.debug(`Event handler for event type ${domainEvent.type} does not exist`)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.logger.debug(`Received event: ${domainEvent.type}`)
|
||||
|
||||
this.tracer = new OpenTelemetryTracer()
|
||||
|
||||
this.tracer.startSpan(this.serviceName, domainEvent.type)
|
||||
|
||||
try {
|
||||
await handler.handle(domainEvent)
|
||||
} catch (error) {
|
||||
this.tracer.stopSpanWithError(error as Error)
|
||||
|
||||
throw error
|
||||
}
|
||||
|
||||
this.tracer.stopSpan()
|
||||
}
|
||||
|
||||
async handleError(error: Error): Promise<void> {
|
||||
this.logger.error('Error occured while handling SQS message: %O', error)
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,4 @@ export * from './SNS/SNSOpenTelemetryDomainEventPublisher'
|
||||
export * from './SQS/SQSBounceNotificiationHandler'
|
||||
export * from './SQS/SQSDomainEventSubscriberFactory'
|
||||
export * from './SQS/SQSEventMessageHandler'
|
||||
export * from './SQS/SQSOpenTelemetryEventMessageHandler'
|
||||
export * from './SQS/SQSOpenTelemetryDomainEventSubscriber'
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.13.13](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.12...@standardnotes/event-store@1.13.13) (2023-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
## [1.13.12](https://github.com/standardnotes/server/compare/@standardnotes/event-store@1.13.11...@standardnotes/event-store@1.13.12) (2023-10-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/event-store
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/event-store",
|
||||
"version": "1.13.12",
|
||||
"version": "1.13.13",
|
||||
"description": "Event Store Service",
|
||||
"private": true,
|
||||
"main": "dist/src/index.js",
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.31.0](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.7...@standardnotes/files-server@1.31.0) (2023-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/files/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [1.30.7](https://github.com/standardnotes/files/compare/@standardnotes/files-server@1.30.6...@standardnotes/files-server@1.30.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Logger } from 'winston'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
|
||||
@@ -26,8 +26,7 @@ void container.load().then((container) => {
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(
|
||||
TYPES.Files_DomainEventSubscriberFactory,
|
||||
)
|
||||
subscriberFactory.create().start()
|
||||
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Files_DomainEventSubscriber)
|
||||
|
||||
subscriber.start()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/files-server",
|
||||
"version": "1.30.7",
|
||||
"version": "1.31.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -17,8 +17,8 @@ import {
|
||||
DirectCallDomainEventPublisher,
|
||||
DirectCallEventMessageHandler,
|
||||
SNSOpenTelemetryDomainEventPublisher,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
SQSOpenTelemetryDomainEventSubscriber,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { StreamDownloadFile } from '../Domain/UseCase/StreamDownloadFile/StreamDownloadFile'
|
||||
import { FileDownloaderInterface } from '../Domain/Services/FileDownloaderInterface'
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventSubscriberInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { MarkFilesToBeRemoved } from '../Domain/UseCase/MarkFilesToBeRemoved/MarkFilesToBeRemoved'
|
||||
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
|
||||
@@ -52,6 +52,7 @@ import { S3FileMover } from '../Infra/S3/S3FileMover'
|
||||
import { FSFileMover } from '../Infra/FS/FSFileMover'
|
||||
import { MoveFile } from '../Domain/UseCase/MoveFile/MoveFile'
|
||||
import { SharedVaultValetTokenAuthMiddleware } from '../Infra/InversifyExpress/Middleware/SharedVaultValetTokenAuthMiddleware'
|
||||
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(configuration?: {
|
||||
@@ -298,12 +299,14 @@ export class ContainerConfigLoader {
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Files_DomainEventMessageHandler)
|
||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Files_Logger)))
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Files_DomainEventSubscriberFactory)
|
||||
.bind<DomainEventSubscriberInterface>(TYPES.Files_DomainEventSubscriber)
|
||||
.toConstantValue(
|
||||
new SQSDomainEventSubscriberFactory(
|
||||
container.get(TYPES.Files_SQS),
|
||||
container.get(TYPES.Files_SQS_QUEUE_URL),
|
||||
container.get(TYPES.Files_DomainEventMessageHandler),
|
||||
new SQSOpenTelemetryDomainEventSubscriber(
|
||||
ServiceIdentifier.NAMES.FilesWorker,
|
||||
container.get<SQSClient>(TYPES.Files_SQS),
|
||||
container.get<string>(TYPES.Files_SQS_QUEUE_URL),
|
||||
container.get<DomainEventMessageHandlerInterface>(TYPES.Files_DomainEventMessageHandler),
|
||||
container.get<winston.Logger>(TYPES.Files_Logger),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ const TYPES = {
|
||||
|
||||
// Handlers
|
||||
Files_DomainEventMessageHandler: Symbol.for('Files_DomainEventMessageHandler'),
|
||||
Files_DomainEventSubscriberFactory: Symbol.for('Files_DomainEventSubscriberFactory'),
|
||||
Files_DomainEventSubscriber: Symbol.for('Files_DomainEventSubscriber'),
|
||||
Files_AccountDeletionRequestedEventHandler: Symbol.for('Files_AccountDeletionRequestedEventHandler'),
|
||||
Files_SharedSubscriptionInvitationCanceledEventHandler: Symbol.for(
|
||||
'Files_SharedSubscriptionInvitationCanceledEventHandler',
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.17.15](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.14...@standardnotes/home-server@1.17.15) (2023-10-17)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.17.14](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.13...@standardnotes/home-server@1.17.14) (2023-10-16)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
## [1.17.13](https://github.com/standardnotes/server/compare/@standardnotes/home-server@1.17.12...@standardnotes/home-server@1.17.13) (2023-10-13)
|
||||
|
||||
**Note:** Version bump only for package @standardnotes/home-server
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/home-server",
|
||||
"version": "1.17.13",
|
||||
"version": "1.17.15",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.46.0](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.45.7...@standardnotes/revisions-server@1.46.0) (2023-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [1.45.7](https://github.com/standardnotes/server/compare/@standardnotes/revisions-server@1.45.6...@standardnotes/revisions-server@1.45.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Logger } from 'winston'
|
||||
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
@@ -22,8 +22,7 @@ void container.load().then((container) => {
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(
|
||||
TYPES.Revisions_DomainEventSubscriberFactory,
|
||||
)
|
||||
subscriberFactory.create().start()
|
||||
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Revisions_DomainEventSubscriber)
|
||||
|
||||
subscriber.start()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/revisions-server",
|
||||
"version": "1.45.7",
|
||||
"version": "1.46.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import { ControllerContainer, ControllerContainerInterface, MapperInterface } from '@standardnotes/domain-core'
|
||||
import {
|
||||
ControllerContainer,
|
||||
ControllerContainerInterface,
|
||||
MapperInterface,
|
||||
ServiceIdentifier,
|
||||
} from '@standardnotes/domain-core'
|
||||
import Redis from 'ioredis'
|
||||
import { Container, interfaces } from 'inversify'
|
||||
import { MongoRepository, Repository } from 'typeorm'
|
||||
@@ -26,15 +31,15 @@ import { SQSClient, SQSClientConfig } from '@aws-sdk/client-sqs'
|
||||
import {
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventPublisherInterface,
|
||||
DomainEventSubscriberInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import {
|
||||
SQSEventMessageHandler,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
DirectCallEventMessageHandler,
|
||||
DirectCallDomainEventPublisher,
|
||||
SNSOpenTelemetryDomainEventPublisher,
|
||||
SQSOpenTelemetryDomainEventSubscriber,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { DumpRepositoryInterface } from '../Domain/Dump/DumpRepositoryInterface'
|
||||
import { AccountDeletionRequestedEventHandler } from '../Domain/Handler/AccountDeletionRequestedEventHandler'
|
||||
@@ -507,14 +512,16 @@ export class ContainerConfigLoader {
|
||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Revisions_Logger)))
|
||||
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Revisions_DomainEventSubscriberFactory)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SQSDomainEventSubscriberFactory(
|
||||
context.container.get(TYPES.Revisions_SQS),
|
||||
context.container.get(TYPES.Revisions_SQS_QUEUE_URL),
|
||||
context.container.get(TYPES.Revisions_DomainEventMessageHandler),
|
||||
)
|
||||
})
|
||||
.bind<DomainEventSubscriberInterface>(TYPES.Revisions_DomainEventSubscriber)
|
||||
.toConstantValue(
|
||||
new SQSOpenTelemetryDomainEventSubscriber(
|
||||
ServiceIdentifier.NAMES.RevisionsWorker,
|
||||
container.get<SQSClient>(TYPES.Revisions_SQS),
|
||||
container.get<string>(TYPES.Revisions_SQS_QUEUE_URL),
|
||||
container.get<DomainEventMessageHandlerInterface>(TYPES.Revisions_DomainEventMessageHandler),
|
||||
container.get<winston.Logger>(TYPES.Revisions_Logger),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Inversify Controllers
|
||||
|
||||
@@ -65,7 +65,7 @@ const TYPES = {
|
||||
Revisions_SharedVaultRemovedEventHandler: Symbol.for('Revisions_SharedVaultRemovedEventHandler'),
|
||||
// Services
|
||||
Revisions_CrossServiceTokenDecoder: Symbol.for('Revisions_CrossServiceTokenDecoder'),
|
||||
Revisions_DomainEventSubscriberFactory: Symbol.for('Revisions_DomainEventSubscriberFactory'),
|
||||
Revisions_DomainEventSubscriber: Symbol.for('Revisions_DomainEventSubscriber'),
|
||||
Revisions_DomainEventMessageHandler: Symbol.for('Revisions_DomainEventMessageHandler'),
|
||||
Revisions_DomainEventPublisher: Symbol.for('Revisions_DomainEventPublisher'),
|
||||
Revisions_DomainEventFactory: Symbol.for('Revisions_DomainEventFactory'),
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.26.0](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.25.7...@standardnotes/scheduler-server@1.26.0) (2023-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [1.25.7](https://github.com/standardnotes/server/compare/@standardnotes/scheduler-server@1.25.6...@standardnotes/scheduler-server@1.25.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -7,7 +7,7 @@ const sdk = new OpenTelemetrySDK({ serviceName: ServiceIdentifier.NAMES.Schedule
|
||||
sdk.start()
|
||||
|
||||
import { Logger } from 'winston'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
|
||||
import * as dayjs from 'dayjs'
|
||||
import * as utc from 'dayjs/plugin/utc'
|
||||
|
||||
@@ -26,6 +26,7 @@ void container.load().then((container) => {
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
|
||||
subscriberFactory.create().start()
|
||||
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
|
||||
|
||||
subscriber.start()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/scheduler-server",
|
||||
"version": "1.25.7",
|
||||
"version": "1.26.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventPublisherInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventSubscriberInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
|
||||
import { Env } from './Env'
|
||||
@@ -16,8 +16,8 @@ import { AppDataSource } from './DataSource'
|
||||
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
|
||||
import {
|
||||
SNSOpenTelemetryDomainEventPublisher,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
SQSOpenTelemetryDomainEventSubscriber,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { Timer, TimerInterface } from '@standardnotes/time'
|
||||
import { PredicateRepositoryInterface } from '../Domain/Predicate/PredicateRepositoryInterface'
|
||||
@@ -35,6 +35,7 @@ import { VerifyPredicates } from '../Domain/UseCase/VerifyPredicates/VerifyPredi
|
||||
import { UserRegisteredEventHandler } from '../Domain/Handler/UserRegisteredEventHandler'
|
||||
import { SubscriptionCancelledEventHandler } from '../Domain/Handler/SubscriptionCancelledEventHandler'
|
||||
import { ExitDiscountAppliedEventHandler } from '../Domain/Handler/ExitDiscountAppliedEventHandler'
|
||||
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(): Promise<Container> {
|
||||
@@ -150,12 +151,14 @@ export class ContainerConfigLoader {
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
|
||||
.bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
|
||||
.toConstantValue(
|
||||
new SQSDomainEventSubscriberFactory(
|
||||
container.get(TYPES.SQS),
|
||||
container.get(TYPES.SQS_QUEUE_URL),
|
||||
container.get(TYPES.DomainEventMessageHandler),
|
||||
new SQSOpenTelemetryDomainEventSubscriber(
|
||||
ServiceIdentifier.NAMES.SchedulerWorker,
|
||||
container.get<SQSClient>(TYPES.SQS),
|
||||
container.get<string>(TYPES.SQS_QUEUE_URL),
|
||||
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),
|
||||
container.get<winston.Logger>(TYPES.Logger),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ const TYPES = {
|
||||
ExitDiscountAppliedEventHandler: Symbol.for('ExitDiscountAppliedEventHandler'),
|
||||
// Services
|
||||
DomainEventPublisher: Symbol.for('DomainEventPublisher'),
|
||||
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
|
||||
DomainEventSubscriber: Symbol.for('DomainEventSubscriber'),
|
||||
DomainEventFactory: Symbol.for('DomainEventFactory'),
|
||||
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
|
||||
Timer: Symbol.for('Timer'),
|
||||
|
||||
@@ -3,6 +3,16 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.118.0](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.117.7...@standardnotes/syncing-server@1.118.0) (2023-10-17)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **syncing-server:** binding ([5b06ea9](https://github.com/standardnotes/syncing-server-js/commit/5b06ea94f9734c1a82549235058b7f63c7665fb7))
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/syncing-server-js/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [1.117.7](https://github.com/standardnotes/syncing-server-js/compare/@standardnotes/syncing-server@1.117.6...@standardnotes/syncing-server@1.117.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Logger } from 'winston'
|
||||
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
|
||||
const container = new ContainerConfigLoader('worker')
|
||||
@@ -20,11 +20,9 @@ void container.load().then((container) => {
|
||||
|
||||
const logger: Logger = container.get(TYPES.Sync_Logger)
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(
|
||||
TYPES.Sync_DomainEventSubscriberFactory,
|
||||
)
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
subscriberFactory.create().start()
|
||||
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.Sync_DomainEventSubscriber)
|
||||
|
||||
subscriber.start()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/syncing-server",
|
||||
"version": "1.117.7",
|
||||
"version": "1.118.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -14,8 +14,8 @@ import {
|
||||
DirectCallDomainEventPublisher,
|
||||
DirectCallEventMessageHandler,
|
||||
SNSOpenTelemetryDomainEventPublisher,
|
||||
SQSDomainEventSubscriberFactory,
|
||||
SQSEventMessageHandler,
|
||||
SQSOpenTelemetryDomainEventSubscriber,
|
||||
} from '@standardnotes/domain-events-infra'
|
||||
import { DomainEventFactoryInterface } from '../Domain/Event/DomainEventFactoryInterface'
|
||||
import { DomainEventFactory } from '../Domain/Event/DomainEventFactory'
|
||||
@@ -43,8 +43,8 @@ import { ContentDecoder, ContentDecoderInterface } from '@standardnotes/common'
|
||||
import {
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventPublisherInterface,
|
||||
DomainEventSubscriberInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import axios, { AxiosInstance } from 'axios'
|
||||
import { ExtensionsHttpService } from '../Domain/Extension/ExtensionsHttpService'
|
||||
@@ -60,6 +60,7 @@ import {
|
||||
ControllerContainer,
|
||||
ControllerContainerInterface,
|
||||
MapperInterface,
|
||||
ServiceIdentifier,
|
||||
SharedVaultUser,
|
||||
} from '@standardnotes/domain-core'
|
||||
import { BaseItemsController } from '../Infra/InversifyExpressUtils/Base/BaseItemsController'
|
||||
@@ -288,24 +289,20 @@ export class ContainerConfigLoader {
|
||||
)
|
||||
})
|
||||
|
||||
container.bind<SQSClient>(TYPES.Sync_SQS).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
|
||||
const sqsConfig: SQSClientConfig = {
|
||||
region: env.get('SQS_AWS_REGION'),
|
||||
const sqsConfig: SQSClientConfig = {
|
||||
region: env.get('SQS_AWS_REGION', true),
|
||||
}
|
||||
if (env.get('SQS_ENDPOINT', true)) {
|
||||
sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
|
||||
sqsConfig.credentials = {
|
||||
accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
if (env.get('SQS_ENDPOINT', true)) {
|
||||
sqsConfig.endpoint = env.get('SQS_ENDPOINT', true)
|
||||
}
|
||||
if (env.get('SQS_ACCESS_KEY_ID', true) && env.get('SQS_SECRET_ACCESS_KEY', true)) {
|
||||
sqsConfig.credentials = {
|
||||
accessKeyId: env.get('SQS_ACCESS_KEY_ID', true),
|
||||
secretAccessKey: env.get('SQS_SECRET_ACCESS_KEY', true),
|
||||
}
|
||||
}
|
||||
|
||||
return new SQSClient(sqsConfig)
|
||||
})
|
||||
}
|
||||
const sqsClient = new SQSClient(sqsConfig)
|
||||
container.bind<SQSClient>(TYPES.Sync_SQS).toConstantValue(sqsClient)
|
||||
|
||||
container.bind<S3Client | undefined>(TYPES.Sync_S3).toDynamicValue((context: interfaces.Context) => {
|
||||
const env: Env = context.container.get(TYPES.Sync_Env)
|
||||
@@ -1137,17 +1134,19 @@ export class ContainerConfigLoader {
|
||||
container
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.Sync_DomainEventMessageHandler)
|
||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Sync_Logger)))
|
||||
}
|
||||
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.Sync_DomainEventSubscriberFactory)
|
||||
.toDynamicValue((context: interfaces.Context) => {
|
||||
return new SQSDomainEventSubscriberFactory(
|
||||
context.container.get(TYPES.Sync_SQS),
|
||||
context.container.get(TYPES.Sync_SQS_QUEUE_URL),
|
||||
context.container.get(TYPES.Sync_DomainEventMessageHandler),
|
||||
container
|
||||
.bind<DomainEventSubscriberInterface>(TYPES.Sync_DomainEventSubscriber)
|
||||
.toConstantValue(
|
||||
new SQSOpenTelemetryDomainEventSubscriber(
|
||||
ServiceIdentifier.NAMES.SyncingServerWorker,
|
||||
container.get<SQSClient>(TYPES.Sync_SQS),
|
||||
container.get<string>(TYPES.Sync_SQS_QUEUE_URL),
|
||||
container.get<DomainEventMessageHandlerInterface>(TYPES.Sync_DomainEventMessageHandler),
|
||||
container.get<Logger>(TYPES.Sync_Logger),
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
container
|
||||
.bind<ControllerContainerInterface>(TYPES.Sync_ControllerContainer)
|
||||
|
||||
@@ -105,7 +105,7 @@ const TYPES = {
|
||||
// Services
|
||||
Sync_ContentDecoder: Symbol.for('Sync_ContentDecoder'),
|
||||
Sync_DomainEventPublisher: Symbol.for('Sync_DomainEventPublisher'),
|
||||
Sync_DomainEventSubscriberFactory: Symbol.for('Sync_DomainEventSubscriberFactory'),
|
||||
Sync_DomainEventSubscriber: Symbol.for('Sync_DomainEventSubscriber'),
|
||||
Sync_DomainEventFactory: Symbol.for('Sync_DomainEventFactory'),
|
||||
Sync_DomainEventMessageHandler: Symbol.for('Sync_DomainEventMessageHandler'),
|
||||
Sync_HTTPClient: Symbol.for('Sync_HTTPClient'),
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [1.17.0](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.16.7...@standardnotes/websockets-server@1.17.0) (2023-10-17)
|
||||
|
||||
### Features
|
||||
|
||||
* add wrapping sqs receive message with open telemetry ([aba4f90](https://github.com/standardnotes/server/commit/aba4f90485e1b40baac34561321a5381945aa27e))
|
||||
|
||||
## [1.16.7](https://github.com/standardnotes/server/compare/@standardnotes/websockets-server@1.16.6...@standardnotes/websockets-server@1.16.7) (2023-10-13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Logger } from 'winston'
|
||||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { DomainEventSubscriberFactoryInterface } from '@standardnotes/domain-events'
|
||||
import { DomainEventSubscriberInterface } from '@standardnotes/domain-events'
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
void container.load().then((container) => {
|
||||
@@ -22,6 +22,7 @@ void container.load().then((container) => {
|
||||
|
||||
logger.info('Starting worker...')
|
||||
|
||||
const subscriberFactory: DomainEventSubscriberFactoryInterface = container.get(TYPES.DomainEventSubscriberFactory)
|
||||
subscriberFactory.create().start()
|
||||
const subscriber = container.get<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
|
||||
|
||||
subscriber.start()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@standardnotes/websockets-server",
|
||||
"version": "1.16.7",
|
||||
"version": "1.17.0",
|
||||
"engines": {
|
||||
"node": ">=18.0.0 <21.0.0"
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Container } from 'inversify'
|
||||
import {
|
||||
DomainEventHandlerInterface,
|
||||
DomainEventMessageHandlerInterface,
|
||||
DomainEventSubscriberFactoryInterface,
|
||||
DomainEventSubscriberInterface,
|
||||
} from '@standardnotes/domain-events'
|
||||
import { Env } from './Env'
|
||||
import TYPES from './Types'
|
||||
@@ -18,7 +18,7 @@ import { RedisWebSocketsConnectionRepository } from '../Infra/Redis/RedisWebSock
|
||||
import { AddWebSocketsConnection } from '../Domain/UseCase/AddWebSocketsConnection/AddWebSocketsConnection'
|
||||
import { RemoveWebSocketsConnection } from '../Domain/UseCase/RemoveWebSocketsConnection/RemoveWebSocketsConnection'
|
||||
import { WebSocketsClientMessenger } from '../Infra/WebSockets/WebSocketsClientMessenger'
|
||||
import { SQSDomainEventSubscriberFactory, SQSEventMessageHandler } from '@standardnotes/domain-events-infra'
|
||||
import { SQSEventMessageHandler, SQSOpenTelemetryDomainEventSubscriber } from '@standardnotes/domain-events-infra'
|
||||
import { ApiGatewayAuthMiddleware } from '../Controller/ApiGatewayAuthMiddleware'
|
||||
|
||||
import {
|
||||
@@ -34,6 +34,7 @@ import { WebSocketsController } from '../Controller/WebSocketsController'
|
||||
import { WebSocketServerInterface } from '@standardnotes/api'
|
||||
import { ClientMessengerInterface } from '../Client/ClientMessengerInterface'
|
||||
import { WebSocketMessageRequestedEventHandler } from '../Domain/Handler/WebSocketMessageRequestedEventHandler'
|
||||
import { ServiceIdentifier } from '@standardnotes/domain-core'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(): Promise<Container> {
|
||||
@@ -142,12 +143,14 @@ export class ContainerConfigLoader {
|
||||
.bind<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler)
|
||||
.toConstantValue(new SQSEventMessageHandler(eventHandlers, container.get(TYPES.Logger)))
|
||||
container
|
||||
.bind<DomainEventSubscriberFactoryInterface>(TYPES.DomainEventSubscriberFactory)
|
||||
.bind<DomainEventSubscriberInterface>(TYPES.DomainEventSubscriber)
|
||||
.toConstantValue(
|
||||
new SQSDomainEventSubscriberFactory(
|
||||
container.get(TYPES.SQS),
|
||||
container.get(TYPES.SQS_QUEUE_URL),
|
||||
container.get(TYPES.DomainEventMessageHandler),
|
||||
new SQSOpenTelemetryDomainEventSubscriber(
|
||||
ServiceIdentifier.NAMES.WebsocketsWorker,
|
||||
container.get<SQSClient>(TYPES.SQS),
|
||||
container.get<string>(TYPES.SQS_QUEUE_URL),
|
||||
container.get<DomainEventMessageHandlerInterface>(TYPES.DomainEventMessageHandler),
|
||||
container.get<winston.Logger>(TYPES.Logger),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ const TYPES = {
|
||||
// Services
|
||||
CrossServiceTokenDecoder: Symbol.for('CrossServiceTokenDecoder'),
|
||||
WebSocketConnectionTokenEncoder: Symbol.for('WebSocketConnectionTokenEncoder'),
|
||||
DomainEventSubscriberFactory: Symbol.for('DomainEventSubscriberFactory'),
|
||||
DomainEventSubscriber: Symbol.for('DomainEventSubscriber'),
|
||||
DomainEventMessageHandler: Symbol.for('DomainEventMessageHandler'),
|
||||
HTTPClient: Symbol.for('HTTPClient'),
|
||||
WebSocketsClientMessenger: Symbol.for('WebSocketsClientMessenger'),
|
||||
|
||||
10
yarn.lock
10
yarn.lock
@@ -4438,7 +4438,7 @@ __metadata:
|
||||
opentelemetry-instrumentation-typeorm: "npm:^0.39.1"
|
||||
prettier: "npm:^3.0.3"
|
||||
reflect-metadata: "npm:^0.1.13"
|
||||
sqs-consumer: "npm:^7.3.0"
|
||||
sqs-consumer: "npm:7.4.0-canary.0"
|
||||
ts-jest: "npm:^29.1.0"
|
||||
typescript: "npm:^5.0.4"
|
||||
winston: "npm:^3.8.1"
|
||||
@@ -12735,15 +12735,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sqs-consumer@npm:^7.3.0":
|
||||
version: 7.3.0
|
||||
resolution: "sqs-consumer@npm:7.3.0"
|
||||
"sqs-consumer@npm:7.4.0-canary.0":
|
||||
version: 7.4.0-canary.0
|
||||
resolution: "sqs-consumer@npm:7.4.0-canary.0"
|
||||
dependencies:
|
||||
"@aws-sdk/client-sqs": "npm:^3.363.0"
|
||||
debug: "npm:^4.3.4"
|
||||
peerDependencies:
|
||||
"@aws-sdk/client-sqs": ^3.363.0
|
||||
checksum: 367ea2a6f3ea5da331efbb7052e643f1657aafa138c8404f336389effbbaba734858bd4daf29c86ab0b4c8a015863ddac6b19482302324f46d45a38fae731f54
|
||||
checksum: 7ecff41c977775f5e61e9f58f79a86b3939bd9ade9cecd7532d8344c454ec059267645c87544d38dbb4c4403e65c908d51c69aee3776c009310c3ba79c1172c7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
Reference in New Issue
Block a user