feat(skill): automatically onboard to openapi tooling (#34179)
* feat(skill): automatically onboard to openapi tooling Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> * test skill against notifications backend Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> * update URLs to point to main repo and describe multiple client types Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> * address PR feedback Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> * revert erroneous changes Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> * add changeset Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> * address review feedback: skill doc fixes and entityRef schema dedup Disambiguate generated entityRef/orderField types and correct skill guidance on operationId casing and OpenAPI version support. Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> * note in skill that handler-side validation should be stripped Reviewers may forget that manual InputError guards and primitive-type checks become dead weight once the OpenAPI validator runs. Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com> --------- Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build",
|
||||
"clean": "backstage-cli package clean",
|
||||
"generate": "backstage-repo-tools package schema openapi generate --server",
|
||||
"lint": "backstage-cli package lint",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
"postpack": "backstage-cli package postpack",
|
||||
@@ -42,6 +43,7 @@
|
||||
"test": "backstage-cli package test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-openapi-utils": "workspace:^",
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/catalog-model": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
@@ -64,6 +66,7 @@
|
||||
"@backstage/plugin-auth-backend-module-guest-provider": "workspace:^",
|
||||
"@backstage/plugin-events-backend": "workspace:^",
|
||||
"@backstage/plugin-signals-backend": "workspace:^",
|
||||
"@backstage/repo-tools": "workspace:^",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"supertest": "^7.0.0"
|
||||
|
||||
@@ -0,0 +1,675 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: notifications
|
||||
version: '1'
|
||||
description: The Backstage backend plugin that powers user notifications.
|
||||
license:
|
||||
name: Apache-2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
contact: {}
|
||||
servers:
|
||||
- url: /
|
||||
components:
|
||||
examples: {}
|
||||
headers: {}
|
||||
parameters:
|
||||
notificationId:
|
||||
name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
offset:
|
||||
name: offset
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
limit:
|
||||
name: limit
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
orderField:
|
||||
name: orderField
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
description: One or more "field,direction" pairs. Direction is "asc" or "desc". Pass multiple to express compound sorts.
|
||||
schema:
|
||||
$ref: '#/components/schemas/OrderField'
|
||||
topic:
|
||||
name: topic
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
search:
|
||||
name: search
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
read:
|
||||
name: read
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
saved:
|
||||
name: saved
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- 'true'
|
||||
- 'false'
|
||||
createdAfter:
|
||||
name: createdAfter
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
description: ISO 8601 date-time string. Validated by the handler.
|
||||
schema:
|
||||
type: string
|
||||
minimumSeverity:
|
||||
name: minimumSeverity
|
||||
in: query
|
||||
required: false
|
||||
allowReserved: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSeverity'
|
||||
requestBodies: {}
|
||||
responses:
|
||||
ErrorResponse:
|
||||
description: An error response from the backend.
|
||||
content:
|
||||
application/json; charset=utf-8:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Error'
|
||||
schemas:
|
||||
NotificationSeverity:
|
||||
type: string
|
||||
enum:
|
||||
- critical
|
||||
- high
|
||||
- normal
|
||||
- low
|
||||
|
||||
NotificationPayload:
|
||||
type: object
|
||||
required:
|
||||
- title
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
description: Notification title
|
||||
description:
|
||||
type: string
|
||||
description: Optional longer description for the notification
|
||||
link:
|
||||
type: string
|
||||
description: Optional link where the notification is pointing to
|
||||
severity:
|
||||
$ref: '#/components/schemas/NotificationSeverity'
|
||||
topic:
|
||||
type: string
|
||||
description: Optional notification topic
|
||||
scope:
|
||||
type: string
|
||||
description: Notification scope, can be used to re-send same notifications in case the scope and origin matches.
|
||||
icon:
|
||||
type: string
|
||||
description: Optional notification icon
|
||||
metadata:
|
||||
type: object
|
||||
description: Optional additional customizable metadata.
|
||||
additionalProperties: true
|
||||
|
||||
NotificationResponsePayload:
|
||||
description: Response variant of NotificationPayload. Optional string fields may be returned as null when unset.
|
||||
type: object
|
||||
required:
|
||||
- title
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
description:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
link:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
severity:
|
||||
$ref: '#/components/schemas/NotificationSeverity'
|
||||
topic:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
scope:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
icon:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
metadata:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
|
||||
Notification:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- user
|
||||
- created
|
||||
- origin
|
||||
- payload
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: Unique identifier for the notification.
|
||||
user:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
description: User entity reference, or null for broadcast notifications.
|
||||
created:
|
||||
type: string
|
||||
format: date-time
|
||||
saved:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
format: date-time
|
||||
read:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
format: date-time
|
||||
updated:
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
format: date-time
|
||||
origin:
|
||||
type: string
|
||||
description: Origin of the notification (the sender's reference).
|
||||
payload:
|
||||
$ref: '#/components/schemas/NotificationResponsePayload'
|
||||
|
||||
NotificationStatus:
|
||||
type: object
|
||||
required:
|
||||
- unread
|
||||
- read
|
||||
properties:
|
||||
unread:
|
||||
type: integer
|
||||
read:
|
||||
type: integer
|
||||
|
||||
TopicSetting:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
|
||||
OriginSetting:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- enabled
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
topics:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/TopicSetting'
|
||||
|
||||
ChannelSetting:
|
||||
type: object
|
||||
required:
|
||||
- id
|
||||
- origins
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
enabled:
|
||||
type: boolean
|
||||
origins:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/OriginSetting'
|
||||
|
||||
NotificationSettings:
|
||||
type: object
|
||||
required:
|
||||
- channels
|
||||
properties:
|
||||
channels:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ChannelSetting'
|
||||
|
||||
EntityRef:
|
||||
description: A single entity ref, or a list of entity refs.
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
OrderField:
|
||||
description: One or more "field,direction" pairs, given as a single string or an array of strings.
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
NotificationRecipients:
|
||||
oneOf:
|
||||
- type: object
|
||||
required:
|
||||
- type
|
||||
- entityRef
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- entity
|
||||
entityRef:
|
||||
$ref: '#/components/schemas/EntityRef'
|
||||
excludeEntityRef:
|
||||
$ref: '#/components/schemas/EntityRef'
|
||||
- type: object
|
||||
required:
|
||||
- type
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- broadcast
|
||||
|
||||
NotificationSendOptions:
|
||||
type: object
|
||||
required:
|
||||
- recipients
|
||||
- payload
|
||||
properties:
|
||||
recipients:
|
||||
$ref: '#/components/schemas/NotificationRecipients'
|
||||
payload:
|
||||
$ref: '#/components/schemas/NotificationPayload'
|
||||
|
||||
UpdateNotificationsRequest:
|
||||
type: object
|
||||
required:
|
||||
- ids
|
||||
properties:
|
||||
ids:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
read:
|
||||
type: boolean
|
||||
saved:
|
||||
type: boolean
|
||||
|
||||
ListNotificationsResponse:
|
||||
type: object
|
||||
required:
|
||||
- totalCount
|
||||
- notifications
|
||||
properties:
|
||||
totalCount:
|
||||
type: integer
|
||||
notifications:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Notification'
|
||||
|
||||
GetTopicsResponse:
|
||||
type: object
|
||||
required:
|
||||
- topics
|
||||
properties:
|
||||
topics:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
Error:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- message
|
||||
request:
|
||||
type: object
|
||||
properties:
|
||||
method:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
required:
|
||||
- method
|
||||
- url
|
||||
response:
|
||||
type: object
|
||||
properties:
|
||||
statusCode:
|
||||
type: number
|
||||
required:
|
||||
- statusCode
|
||||
required:
|
||||
- error
|
||||
- request
|
||||
- response
|
||||
securitySchemes:
|
||||
JWT:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
paths:
|
||||
/:
|
||||
get:
|
||||
operationId: ListNotificationsLegacy
|
||||
deprecated: true
|
||||
description: Deprecated alias for `GET /notifications`.
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/offset'
|
||||
- $ref: '#/components/parameters/limit'
|
||||
- $ref: '#/components/parameters/orderField'
|
||||
- $ref: '#/components/parameters/topic'
|
||||
- $ref: '#/components/parameters/search'
|
||||
- $ref: '#/components/parameters/read'
|
||||
- $ref: '#/components/parameters/saved'
|
||||
- $ref: '#/components/parameters/createdAfter'
|
||||
- $ref: '#/components/parameters/minimumSeverity'
|
||||
responses:
|
||||
'200':
|
||||
description: A page of notifications for the current user.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListNotificationsResponse'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
post:
|
||||
operationId: CreateNotificationsLegacy
|
||||
deprecated: true
|
||||
description: Deprecated alias for `POST /notifications`.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSendOptions'
|
||||
responses:
|
||||
'200':
|
||||
description: The notifications that were created.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Notification'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/notifications:
|
||||
get:
|
||||
operationId: ListNotifications
|
||||
description: List notifications for the current user.
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/offset'
|
||||
- $ref: '#/components/parameters/limit'
|
||||
- $ref: '#/components/parameters/orderField'
|
||||
- $ref: '#/components/parameters/topic'
|
||||
- $ref: '#/components/parameters/search'
|
||||
- $ref: '#/components/parameters/read'
|
||||
- $ref: '#/components/parameters/saved'
|
||||
- $ref: '#/components/parameters/createdAfter'
|
||||
- $ref: '#/components/parameters/minimumSeverity'
|
||||
responses:
|
||||
'200':
|
||||
description: A page of notifications for the current user.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ListNotificationsResponse'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
post:
|
||||
operationId: CreateNotifications
|
||||
description: Send a notification to one or more recipients (service credentials required).
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSendOptions'
|
||||
responses:
|
||||
'200':
|
||||
description: The notifications that were created.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Notification'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/update:
|
||||
post:
|
||||
operationId: UpdateNotificationsLegacy
|
||||
deprecated: true
|
||||
description: Deprecated alias for `POST /notifications/update`.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateNotificationsRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: The notifications that were updated.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Notification'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/notifications/update:
|
||||
post:
|
||||
operationId: UpdateNotifications
|
||||
description: Mark notifications as read/unread or saved/unsaved.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/UpdateNotificationsRequest'
|
||||
responses:
|
||||
'200':
|
||||
description: The notifications that were updated.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Notification'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/status:
|
||||
get:
|
||||
operationId: GetStatus
|
||||
description: Get the unread/read counts for the current user.
|
||||
responses:
|
||||
'200':
|
||||
description: The current user's notification status.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationStatus'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/settings:
|
||||
get:
|
||||
operationId: GetSettings
|
||||
description: Get the current user's notification settings, merged with defaults.
|
||||
responses:
|
||||
'200':
|
||||
description: Effective notification settings for the user.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSettings'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
post:
|
||||
operationId: UpdateSettings
|
||||
description: Update the current user's notification settings.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSettings'
|
||||
responses:
|
||||
'200':
|
||||
description: Effective notification settings for the user.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSettings'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/topics:
|
||||
get:
|
||||
operationId: GetTopics
|
||||
description: List notification topics that the user has received notifications on.
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/search'
|
||||
- $ref: '#/components/parameters/read'
|
||||
- $ref: '#/components/parameters/saved'
|
||||
- $ref: '#/components/parameters/createdAfter'
|
||||
- $ref: '#/components/parameters/minimumSeverity'
|
||||
responses:
|
||||
'200':
|
||||
description: The list of topics.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GetTopicsResponse'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/{id}:
|
||||
get:
|
||||
operationId: GetNotificationLegacy
|
||||
deprecated: true
|
||||
description: Deprecated alias for `GET /notifications/{id}`.
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/notificationId'
|
||||
responses:
|
||||
'200':
|
||||
description: The requested notification.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Notification'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
|
||||
/notifications/{id}:
|
||||
get:
|
||||
operationId: GetNotification
|
||||
description: Get a single notification by id for the current user.
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/notificationId'
|
||||
responses:
|
||||
'200':
|
||||
description: The requested notification.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Notification'
|
||||
default:
|
||||
$ref: '#/components/responses/ErrorResponse'
|
||||
security:
|
||||
- {}
|
||||
- JWT: []
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { GetTopicsResponse } from '../models/GetTopicsResponse.model';
|
||||
import { ListNotificationsResponse } from '../models/ListNotificationsResponse.model';
|
||||
import { Notification } from '../models/Notification.model';
|
||||
import { NotificationSendOptions } from '../models/NotificationSendOptions.model';
|
||||
import { NotificationSettings } from '../models/NotificationSettings.model';
|
||||
import { NotificationSeverity } from '../models/NotificationSeverity.model';
|
||||
import { NotificationStatus } from '../models/NotificationStatus.model';
|
||||
import { OrderField } from '../models/OrderField.model';
|
||||
import { UpdateNotificationsRequest } from '../models/UpdateNotificationsRequest.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type CreateNotifications = {
|
||||
body: NotificationSendOptions;
|
||||
response: Array<Notification> | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type CreateNotificationsLegacy = {
|
||||
body: NotificationSendOptions;
|
||||
response: Array<Notification> | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type GetNotification = {
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
response: Notification | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type GetNotificationLegacy = {
|
||||
path: {
|
||||
id: string;
|
||||
};
|
||||
response: Notification | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type GetSettings = {
|
||||
response: NotificationSettings | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type GetStatus = {
|
||||
response: NotificationStatus | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type GetTopics = {
|
||||
query: {
|
||||
search?: string;
|
||||
read?: 'true' | 'false';
|
||||
saved?: 'true' | 'false';
|
||||
createdAfter?: string;
|
||||
minimumSeverity?: NotificationSeverity;
|
||||
};
|
||||
response: GetTopicsResponse | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type ListNotifications = {
|
||||
query: {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
orderField?: OrderField;
|
||||
topic?: string;
|
||||
search?: string;
|
||||
read?: 'true' | 'false';
|
||||
saved?: 'true' | 'false';
|
||||
createdAfter?: string;
|
||||
minimumSeverity?: NotificationSeverity;
|
||||
};
|
||||
response: ListNotificationsResponse | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type ListNotificationsLegacy = {
|
||||
query: {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
orderField?: OrderField;
|
||||
topic?: string;
|
||||
search?: string;
|
||||
read?: 'true' | 'false';
|
||||
saved?: 'true' | 'false';
|
||||
createdAfter?: string;
|
||||
minimumSeverity?: NotificationSeverity;
|
||||
};
|
||||
response: ListNotificationsResponse | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type UpdateNotifications = {
|
||||
body: UpdateNotificationsRequest;
|
||||
response: Array<Notification> | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type UpdateNotificationsLegacy = {
|
||||
body: UpdateNotificationsRequest;
|
||||
response: Array<Notification> | Error;
|
||||
};
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type UpdateSettings = {
|
||||
body: NotificationSettings;
|
||||
response: NotificationSettings | Error;
|
||||
};
|
||||
|
||||
export type EndpointMap = {
|
||||
'#post|/notifications': CreateNotifications;
|
||||
|
||||
'#post|/': CreateNotificationsLegacy;
|
||||
|
||||
'#get|/notifications/{id}': GetNotification;
|
||||
|
||||
'#get|/{id}': GetNotificationLegacy;
|
||||
|
||||
'#get|/settings': GetSettings;
|
||||
|
||||
'#get|/status': GetStatus;
|
||||
|
||||
'#get|/topics': GetTopics;
|
||||
|
||||
'#get|/notifications': ListNotifications;
|
||||
|
||||
'#get|/': ListNotificationsLegacy;
|
||||
|
||||
'#post|/notifications/update': UpdateNotifications;
|
||||
|
||||
'#post|/update': UpdateNotificationsLegacy;
|
||||
|
||||
'#post|/settings': UpdateSettings;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
export * from './Api.server';
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './apis';
|
||||
export * from './router';
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { OriginSetting } from '../models/OriginSetting.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ChannelSetting {
|
||||
id: string;
|
||||
enabled?: boolean;
|
||||
origins: Array<OriginSetting>;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* A single entity ref, or a list of entity refs.
|
||||
* @public
|
||||
*/
|
||||
export type EntityRef = Array<string> | string;
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ErrorError {
|
||||
name: string;
|
||||
message: string;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ErrorRequest {
|
||||
method: string;
|
||||
url: string;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ErrorResponse {
|
||||
statusCode: number;
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface GetTopicsResponse {
|
||||
topics: Array<string>;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { Notification } from '../models/Notification.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ListNotificationsResponse {
|
||||
totalCount: number;
|
||||
notifications: Array<Notification>;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { ErrorError } from '../models/ErrorError.model';
|
||||
import { ErrorRequest } from '../models/ErrorRequest.model';
|
||||
import { ErrorResponse } from '../models/ErrorResponse.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ModelError {
|
||||
error: ErrorError;
|
||||
request: ErrorRequest;
|
||||
response: ErrorResponse;
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { NotificationResponsePayload } from '../models/NotificationResponsePayload.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface Notification {
|
||||
/**
|
||||
* Unique identifier for the notification.
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* User entity reference, or null for broadcast notifications.
|
||||
*/
|
||||
user: string | null;
|
||||
created: Date;
|
||||
saved?: Date | null;
|
||||
read?: Date | null;
|
||||
updated?: Date | null;
|
||||
/**
|
||||
* Origin of the notification (the sender\'s reference).
|
||||
*/
|
||||
origin: string;
|
||||
payload: NotificationResponsePayload;
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { NotificationSeverity } from '../models/NotificationSeverity.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface NotificationPayload {
|
||||
/**
|
||||
* Notification title
|
||||
*/
|
||||
title: string;
|
||||
/**
|
||||
* Optional longer description for the notification
|
||||
*/
|
||||
description?: string;
|
||||
/**
|
||||
* Optional link where the notification is pointing to
|
||||
*/
|
||||
link?: string;
|
||||
severity?: NotificationSeverity;
|
||||
/**
|
||||
* Optional notification topic
|
||||
*/
|
||||
topic?: string;
|
||||
/**
|
||||
* Notification scope, can be used to re-send same notifications in case the scope and origin matches.
|
||||
*/
|
||||
scope?: string;
|
||||
/**
|
||||
* Optional notification icon
|
||||
*/
|
||||
icon?: string;
|
||||
/**
|
||||
* Optional additional customizable metadata.
|
||||
*/
|
||||
metadata?: { [key: string]: any };
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { NotificationRecipientsOneOf } from '../models/NotificationRecipientsOneOf.model';
|
||||
import { NotificationRecipientsOneOf1 } from '../models/NotificationRecipientsOneOf1.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NotificationRecipients =
|
||||
| NotificationRecipientsOneOf
|
||||
| NotificationRecipientsOneOf1;
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { EntityRef } from '../models/EntityRef.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface NotificationRecipientsOneOf {
|
||||
type: NotificationRecipientsOneOfTypeEnum;
|
||||
entityRef: EntityRef;
|
||||
excludeEntityRef?: EntityRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NotificationRecipientsOneOfTypeEnum = 'entity';
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface NotificationRecipientsOneOf1 {
|
||||
type: NotificationRecipientsOneOf1TypeEnum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NotificationRecipientsOneOf1TypeEnum = 'broadcast';
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { NotificationSeverity } from '../models/NotificationSeverity.model';
|
||||
|
||||
/**
|
||||
* Response variant of NotificationPayload. Optional string fields may be returned as null when unset.
|
||||
* @public
|
||||
*/
|
||||
export interface NotificationResponsePayload {
|
||||
title: string;
|
||||
description?: string | null;
|
||||
link?: string | null;
|
||||
severity?: NotificationSeverity;
|
||||
topic?: string | null;
|
||||
scope?: string | null;
|
||||
icon?: string | null;
|
||||
metadata?: { [key: string]: any };
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { NotificationPayload } from '../models/NotificationPayload.model';
|
||||
import { NotificationRecipients } from '../models/NotificationRecipients.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface NotificationSendOptions {
|
||||
recipients: NotificationRecipients;
|
||||
payload: NotificationPayload;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { ChannelSetting } from '../models/ChannelSetting.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface NotificationSettings {
|
||||
channels: Array<ChannelSetting>;
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NotificationSeverity = 'critical' | 'high' | 'normal' | 'low';
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface NotificationStatus {
|
||||
unread: number;
|
||||
read: number;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* One or more \"field,direction\" pairs, given as a single string or an array of strings.
|
||||
* @public
|
||||
*/
|
||||
export type OrderField = Array<string> | string;
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { TopicSetting } from '../models/TopicSetting.model';
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface OriginSetting {
|
||||
id: string;
|
||||
enabled: boolean;
|
||||
topics?: Array<TopicSetting>;
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface TopicSetting {
|
||||
id: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface UpdateNotificationsRequest {
|
||||
ids: Array<string>;
|
||||
read?: boolean;
|
||||
saved?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from '../models/ChannelSetting.model';
|
||||
export * from '../models/EntityRef.model';
|
||||
export * from '../models/ErrorError.model';
|
||||
export * from '../models/ErrorRequest.model';
|
||||
export * from '../models/ErrorResponse.model';
|
||||
export * from '../models/GetTopicsResponse.model';
|
||||
export * from '../models/ListNotificationsResponse.model';
|
||||
export * from '../models/ModelError.model';
|
||||
export * from '../models/Notification.model';
|
||||
export * from '../models/NotificationPayload.model';
|
||||
export * from '../models/NotificationRecipients.model';
|
||||
export * from '../models/NotificationRecipientsOneOf.model';
|
||||
export * from '../models/NotificationRecipientsOneOf1.model';
|
||||
export * from '../models/NotificationResponsePayload.model';
|
||||
export * from '../models/NotificationSendOptions.model';
|
||||
export * from '../models/NotificationSettings.model';
|
||||
export * from '../models/NotificationSeverity.model';
|
||||
export * from '../models/NotificationStatus.model';
|
||||
export * from '../models/OrderField.model';
|
||||
export * from '../models/OriginSetting.model';
|
||||
export * from '../models/TopicSetting.model';
|
||||
export * from '../models/UpdateNotificationsRequest.model';
|
||||
@@ -0,0 +1,988 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// ******************************************************************
|
||||
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
|
||||
// ******************************************************************
|
||||
import { createValidatedOpenApiRouterFromGeneratedEndpointMap } from '@backstage/backend-openapi-utils';
|
||||
import { EndpointMap } from './apis';
|
||||
|
||||
export const spec = {
|
||||
openapi: '3.1.0',
|
||||
info: {
|
||||
title: 'notifications',
|
||||
version: '1',
|
||||
description: 'The Backstage backend plugin that powers user notifications.',
|
||||
license: {
|
||||
name: 'Apache-2.0',
|
||||
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
|
||||
},
|
||||
contact: {},
|
||||
},
|
||||
servers: [
|
||||
{
|
||||
url: '/',
|
||||
},
|
||||
],
|
||||
components: {
|
||||
examples: {},
|
||||
headers: {},
|
||||
parameters: {
|
||||
notificationId: {
|
||||
name: 'id',
|
||||
in: 'path',
|
||||
required: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
offset: {
|
||||
name: 'offset',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
},
|
||||
},
|
||||
limit: {
|
||||
name: 'limit',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'integer',
|
||||
minimum: 0,
|
||||
},
|
||||
},
|
||||
orderField: {
|
||||
name: 'orderField',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
description:
|
||||
'One or more "field,direction" pairs. Direction is "asc" or "desc". Pass multiple to express compound sorts.',
|
||||
schema: {
|
||||
$ref: '#/components/schemas/OrderField',
|
||||
},
|
||||
},
|
||||
topic: {
|
||||
name: 'topic',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
search: {
|
||||
name: 'search',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
read: {
|
||||
name: 'read',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
},
|
||||
saved: {
|
||||
name: 'saved',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
type: 'string',
|
||||
enum: ['true', 'false'],
|
||||
},
|
||||
},
|
||||
createdAfter: {
|
||||
name: 'createdAfter',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
description: 'ISO 8601 date-time string. Validated by the handler.',
|
||||
schema: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
minimumSeverity: {
|
||||
name: 'minimumSeverity',
|
||||
in: 'query',
|
||||
required: false,
|
||||
allowReserved: true,
|
||||
schema: {
|
||||
$ref: '#/components/schemas/NotificationSeverity',
|
||||
},
|
||||
},
|
||||
},
|
||||
requestBodies: {},
|
||||
responses: {
|
||||
ErrorResponse: {
|
||||
description: 'An error response from the backend.',
|
||||
content: {
|
||||
'application/json; charset=utf-8': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/Error',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
schemas: {
|
||||
NotificationSeverity: {
|
||||
type: 'string',
|
||||
enum: ['critical', 'high', 'normal', 'low'],
|
||||
},
|
||||
NotificationPayload: {
|
||||
type: 'object',
|
||||
required: ['title'],
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
description: 'Notification title',
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: 'Optional longer description for the notification',
|
||||
},
|
||||
link: {
|
||||
type: 'string',
|
||||
description: 'Optional link where the notification is pointing to',
|
||||
},
|
||||
severity: {
|
||||
$ref: '#/components/schemas/NotificationSeverity',
|
||||
},
|
||||
topic: {
|
||||
type: 'string',
|
||||
description: 'Optional notification topic',
|
||||
},
|
||||
scope: {
|
||||
type: 'string',
|
||||
description:
|
||||
'Notification scope, can be used to re-send same notifications in case the scope and origin matches.',
|
||||
},
|
||||
icon: {
|
||||
type: 'string',
|
||||
description: 'Optional notification icon',
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
description: 'Optional additional customizable metadata.',
|
||||
additionalProperties: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
NotificationResponsePayload: {
|
||||
description:
|
||||
'Response variant of NotificationPayload. Optional string fields may be returned as null when unset.',
|
||||
type: 'object',
|
||||
required: ['title'],
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string',
|
||||
},
|
||||
description: {
|
||||
type: ['string', 'null'],
|
||||
},
|
||||
link: {
|
||||
type: ['string', 'null'],
|
||||
},
|
||||
severity: {
|
||||
$ref: '#/components/schemas/NotificationSeverity',
|
||||
},
|
||||
topic: {
|
||||
type: ['string', 'null'],
|
||||
},
|
||||
scope: {
|
||||
type: ['string', 'null'],
|
||||
},
|
||||
icon: {
|
||||
type: ['string', 'null'],
|
||||
},
|
||||
metadata: {
|
||||
type: 'object',
|
||||
additionalProperties: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Notification: {
|
||||
type: 'object',
|
||||
required: ['id', 'user', 'created', 'origin', 'payload'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'Unique identifier for the notification.',
|
||||
},
|
||||
user: {
|
||||
type: ['string', 'null'],
|
||||
description:
|
||||
'User entity reference, or null for broadcast notifications.',
|
||||
},
|
||||
created: {
|
||||
type: 'string',
|
||||
format: 'date-time',
|
||||
},
|
||||
saved: {
|
||||
type: ['string', 'null'],
|
||||
format: 'date-time',
|
||||
},
|
||||
read: {
|
||||
type: ['string', 'null'],
|
||||
format: 'date-time',
|
||||
},
|
||||
updated: {
|
||||
type: ['string', 'null'],
|
||||
format: 'date-time',
|
||||
},
|
||||
origin: {
|
||||
type: 'string',
|
||||
description: "Origin of the notification (the sender's reference).",
|
||||
},
|
||||
payload: {
|
||||
$ref: '#/components/schemas/NotificationResponsePayload',
|
||||
},
|
||||
},
|
||||
},
|
||||
NotificationStatus: {
|
||||
type: 'object',
|
||||
required: ['unread', 'read'],
|
||||
properties: {
|
||||
unread: {
|
||||
type: 'integer',
|
||||
},
|
||||
read: {
|
||||
type: 'integer',
|
||||
},
|
||||
},
|
||||
},
|
||||
TopicSetting: {
|
||||
type: 'object',
|
||||
required: ['id', 'enabled'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
},
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
OriginSetting: {
|
||||
type: 'object',
|
||||
required: ['id', 'enabled'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
},
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
},
|
||||
topics: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/TopicSetting',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ChannelSetting: {
|
||||
type: 'object',
|
||||
required: ['id', 'origins'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
},
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
},
|
||||
origins: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/OriginSetting',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
NotificationSettings: {
|
||||
type: 'object',
|
||||
required: ['channels'],
|
||||
properties: {
|
||||
channels: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/ChannelSetting',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
EntityRef: {
|
||||
description: 'A single entity ref, or a list of entity refs.',
|
||||
oneOf: [
|
||||
{
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
OrderField: {
|
||||
description:
|
||||
'One or more "field,direction" pairs, given as a single string or an array of strings.',
|
||||
oneOf: [
|
||||
{
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
NotificationRecipients: {
|
||||
oneOf: [
|
||||
{
|
||||
type: 'object',
|
||||
required: ['type', 'entityRef'],
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
enum: ['entity'],
|
||||
},
|
||||
entityRef: {
|
||||
$ref: '#/components/schemas/EntityRef',
|
||||
},
|
||||
excludeEntityRef: {
|
||||
$ref: '#/components/schemas/EntityRef',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
required: ['type'],
|
||||
properties: {
|
||||
type: {
|
||||
type: 'string',
|
||||
enum: ['broadcast'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
NotificationSendOptions: {
|
||||
type: 'object',
|
||||
required: ['recipients', 'payload'],
|
||||
properties: {
|
||||
recipients: {
|
||||
$ref: '#/components/schemas/NotificationRecipients',
|
||||
},
|
||||
payload: {
|
||||
$ref: '#/components/schemas/NotificationPayload',
|
||||
},
|
||||
},
|
||||
},
|
||||
UpdateNotificationsRequest: {
|
||||
type: 'object',
|
||||
required: ['ids'],
|
||||
properties: {
|
||||
ids: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
read: {
|
||||
type: 'boolean',
|
||||
},
|
||||
saved: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
ListNotificationsResponse: {
|
||||
type: 'object',
|
||||
required: ['totalCount', 'notifications'],
|
||||
properties: {
|
||||
totalCount: {
|
||||
type: 'integer',
|
||||
},
|
||||
notifications: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/Notification',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
GetTopicsResponse: {
|
||||
type: 'object',
|
||||
required: ['topics'],
|
||||
properties: {
|
||||
topics: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Error: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
error: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: {
|
||||
type: 'string',
|
||||
},
|
||||
message: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: ['name', 'message'],
|
||||
},
|
||||
request: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
method: {
|
||||
type: 'string',
|
||||
},
|
||||
url: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
required: ['method', 'url'],
|
||||
},
|
||||
response: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
statusCode: {
|
||||
type: 'number',
|
||||
},
|
||||
},
|
||||
required: ['statusCode'],
|
||||
},
|
||||
},
|
||||
required: ['error', 'request', 'response'],
|
||||
},
|
||||
},
|
||||
securitySchemes: {
|
||||
JWT: {
|
||||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
bearerFormat: 'JWT',
|
||||
},
|
||||
},
|
||||
},
|
||||
paths: {
|
||||
'/': {
|
||||
get: {
|
||||
operationId: 'ListNotificationsLegacy',
|
||||
deprecated: true,
|
||||
description: 'Deprecated alias for `GET /notifications`.',
|
||||
parameters: [
|
||||
{
|
||||
$ref: '#/components/parameters/offset',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/limit',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/orderField',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/topic',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/search',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/read',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/saved',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/createdAfter',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/minimumSeverity',
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'A page of notifications for the current user.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/ListNotificationsResponse',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
post: {
|
||||
operationId: 'CreateNotificationsLegacy',
|
||||
deprecated: true,
|
||||
description: 'Deprecated alias for `POST /notifications`.',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/NotificationSendOptions',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'The notifications that were created.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/Notification',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/notifications': {
|
||||
get: {
|
||||
operationId: 'ListNotifications',
|
||||
description: 'List notifications for the current user.',
|
||||
parameters: [
|
||||
{
|
||||
$ref: '#/components/parameters/offset',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/limit',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/orderField',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/topic',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/search',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/read',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/saved',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/createdAfter',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/minimumSeverity',
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'A page of notifications for the current user.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/ListNotificationsResponse',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
post: {
|
||||
operationId: 'CreateNotifications',
|
||||
description:
|
||||
'Send a notification to one or more recipients (service credentials required).',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/NotificationSendOptions',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'The notifications that were created.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/Notification',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/update': {
|
||||
post: {
|
||||
operationId: 'UpdateNotificationsLegacy',
|
||||
deprecated: true,
|
||||
description: 'Deprecated alias for `POST /notifications/update`.',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/UpdateNotificationsRequest',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'The notifications that were updated.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/Notification',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/notifications/update': {
|
||||
post: {
|
||||
operationId: 'UpdateNotifications',
|
||||
description: 'Mark notifications as read/unread or saved/unsaved.',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/UpdateNotificationsRequest',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'The notifications that were updated.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: '#/components/schemas/Notification',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/status': {
|
||||
get: {
|
||||
operationId: 'GetStatus',
|
||||
description: 'Get the unread/read counts for the current user.',
|
||||
responses: {
|
||||
'200': {
|
||||
description: "The current user's notification status.",
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/NotificationStatus',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/settings': {
|
||||
get: {
|
||||
operationId: 'GetSettings',
|
||||
description:
|
||||
"Get the current user's notification settings, merged with defaults.",
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Effective notification settings for the user.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/NotificationSettings',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
post: {
|
||||
operationId: 'UpdateSettings',
|
||||
description: "Update the current user's notification settings.",
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/NotificationSettings',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'Effective notification settings for the user.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/NotificationSettings',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/topics': {
|
||||
get: {
|
||||
operationId: 'GetTopics',
|
||||
description:
|
||||
'List notification topics that the user has received notifications on.',
|
||||
parameters: [
|
||||
{
|
||||
$ref: '#/components/parameters/search',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/read',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/saved',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/createdAfter',
|
||||
},
|
||||
{
|
||||
$ref: '#/components/parameters/minimumSeverity',
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'The list of topics.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/GetTopicsResponse',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/{id}': {
|
||||
get: {
|
||||
operationId: 'GetNotificationLegacy',
|
||||
deprecated: true,
|
||||
description: 'Deprecated alias for `GET /notifications/{id}`.',
|
||||
parameters: [
|
||||
{
|
||||
$ref: '#/components/parameters/notificationId',
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'The requested notification.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/Notification',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
'/notifications/{id}': {
|
||||
get: {
|
||||
operationId: 'GetNotification',
|
||||
description: 'Get a single notification by id for the current user.',
|
||||
parameters: [
|
||||
{
|
||||
$ref: '#/components/parameters/notificationId',
|
||||
},
|
||||
],
|
||||
responses: {
|
||||
'200': {
|
||||
description: 'The requested notification.',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
$ref: '#/components/schemas/Notification',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
default: {
|
||||
$ref: '#/components/responses/ErrorResponse',
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{},
|
||||
{
|
||||
JWT: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
export const createOpenApiRouter = async (
|
||||
options?: Parameters<
|
||||
typeof createValidatedOpenApiRouterFromGeneratedEndpointMap
|
||||
>['1'],
|
||||
) =>
|
||||
createValidatedOpenApiRouterFromGeneratedEndpointMap<EndpointMap>(
|
||||
spec,
|
||||
options,
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2026 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './generated';
|
||||
@@ -14,8 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import express, { Request, Response } from 'express';
|
||||
import Router from 'express-promise-router';
|
||||
import express, { Request } from 'express';
|
||||
import { createOpenApiRouter, EndpointMap } from '../schema/openapi';
|
||||
import { internal as openapi } from '@backstage/backend-openapi-utils';
|
||||
import {
|
||||
normalizeSeverity,
|
||||
NotificationGetOptions,
|
||||
@@ -45,7 +46,6 @@ import {
|
||||
NotificationReadSignal,
|
||||
NotificationSettings,
|
||||
notificationSeverities,
|
||||
NotificationStatus,
|
||||
OriginSetting,
|
||||
} from '@backstage/plugin-notifications-common';
|
||||
import { parseEntityOrderFieldParams } from './parseEntityOrderFieldParams';
|
||||
@@ -108,7 +108,7 @@ export async function createRouter(
|
||||
recipientResolver ??
|
||||
new DefaultNotificationRecipientResolver(auth, catalog);
|
||||
|
||||
const getUser = async (req: Request<unknown>) => {
|
||||
const getUser = async (req: Request<any, any, any, any, any>) => {
|
||||
const credentials = await httpAuth.credentials(req, { allow: ['user'] });
|
||||
const info = await userInfo.getUserInfo(credentials);
|
||||
return info.userEntityRef;
|
||||
@@ -454,114 +454,112 @@ export async function createRouter(
|
||||
};
|
||||
|
||||
const appendCommonOptions = (
|
||||
req: Request,
|
||||
req: {
|
||||
query: openapi.StaticQueryParamsSchema<EndpointMap, '/topics', 'get'>;
|
||||
},
|
||||
opts: NotificationGetOptions | TopicGetOptions,
|
||||
) => {
|
||||
if (req.query.search) {
|
||||
opts.search = req.query.search.toString();
|
||||
opts.search = req.query.search;
|
||||
}
|
||||
if (req.query.read === 'true') {
|
||||
opts.read = true;
|
||||
} else if (req.query.read === 'false') {
|
||||
opts.read = false;
|
||||
// or keep undefined
|
||||
}
|
||||
|
||||
if (req.query.saved === 'true') {
|
||||
opts.saved = true;
|
||||
} else if (req.query.saved === 'false') {
|
||||
opts.saved = false;
|
||||
// or keep undefined
|
||||
}
|
||||
if (req.query.createdAfter) {
|
||||
const sinceEpoch = Date.parse(String(req.query.createdAfter));
|
||||
const sinceEpoch = Date.parse(req.query.createdAfter);
|
||||
if (isNaN(sinceEpoch)) {
|
||||
throw new InputError('Unexpected date format');
|
||||
}
|
||||
opts.createdAfter = new Date(sinceEpoch);
|
||||
}
|
||||
if (req.query.minimumSeverity) {
|
||||
opts.minimumSeverity = normalizeSeverity(
|
||||
req.query.minimumSeverity.toString(),
|
||||
);
|
||||
opts.minimumSeverity = normalizeSeverity(req.query.minimumSeverity);
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Move to use OpenAPI router instead
|
||||
const router = Router();
|
||||
router.use(express.json());
|
||||
const router = await createOpenApiRouter();
|
||||
|
||||
const listNotificationsHandler = async (req: Request, res: Response) => {
|
||||
const listNotificationsHandler: openapi.EndpointMapRequestHandler<
|
||||
EndpointMap,
|
||||
'/notifications',
|
||||
'get'
|
||||
> = async (req, res) => {
|
||||
const user = await getUser(req);
|
||||
const opts: NotificationGetOptions = {
|
||||
user: user,
|
||||
};
|
||||
if (req.query.offset) {
|
||||
opts.offset = Number.parseInt(req.query.offset.toString(), 10);
|
||||
const opts: NotificationGetOptions = { user };
|
||||
if (req.query.offset !== undefined) {
|
||||
opts.offset = req.query.offset;
|
||||
}
|
||||
if (req.query.limit) {
|
||||
opts.limit = Number.parseInt(req.query.limit.toString(), 10);
|
||||
if (req.query.limit !== undefined) {
|
||||
opts.limit = req.query.limit;
|
||||
}
|
||||
if (req.query.orderField) {
|
||||
opts.orderField = parseEntityOrderFieldParams(req.query);
|
||||
if (req.query.orderField !== undefined) {
|
||||
opts.orderField = parseEntityOrderFieldParams({
|
||||
orderField: req.query.orderField,
|
||||
});
|
||||
}
|
||||
|
||||
if (req.query.topic) {
|
||||
opts.topic = req.query.topic.toString();
|
||||
opts.topic = req.query.topic;
|
||||
}
|
||||
|
||||
appendCommonOptions(req, opts);
|
||||
|
||||
const [notifications, totalCount] = await Promise.all([
|
||||
store.getNotifications(opts),
|
||||
store.getNotificationsCount(opts),
|
||||
]);
|
||||
res.json({
|
||||
totalCount,
|
||||
notifications,
|
||||
});
|
||||
res.json({ totalCount, notifications });
|
||||
};
|
||||
|
||||
router.get('/', listNotificationsHandler); // Deprecated endpoint
|
||||
router.get('/', listNotificationsHandler); // Deprecated alias of /notifications
|
||||
router.get('/notifications', listNotificationsHandler);
|
||||
|
||||
router.get('/status', async (req: Request<any, NotificationStatus>, res) => {
|
||||
router.get('/status', async (req, res) => {
|
||||
const user = await getUser(req);
|
||||
const status = await store.getStatus({ user });
|
||||
res.json(status);
|
||||
});
|
||||
|
||||
router.get(
|
||||
'/settings',
|
||||
async (req: Request<any, NotificationSettings>, res) => {
|
||||
const user = await getUser(req);
|
||||
const response = await getNotificationSettings(user);
|
||||
res.json(response);
|
||||
},
|
||||
);
|
||||
router.get('/settings', async (req, res) => {
|
||||
const user = await getUser(req);
|
||||
const response = await getNotificationSettings(user);
|
||||
res.json(response);
|
||||
});
|
||||
|
||||
router.post(
|
||||
'/settings',
|
||||
async (
|
||||
req: Request<any, NotificationSettings, NotificationSettings>,
|
||||
res,
|
||||
) => {
|
||||
const user = await getUser(req);
|
||||
const channels = getNotificationChannels();
|
||||
const settings: NotificationSettings = req.body;
|
||||
if (settings.channels.some(c => !channels.includes(c.id))) {
|
||||
throw new InputError('Invalid channel');
|
||||
}
|
||||
await store.saveNotificationSettings({ user, settings });
|
||||
const response = await getNotificationSettings(user);
|
||||
res.json(response);
|
||||
},
|
||||
);
|
||||
router.post('/settings', async (req, res) => {
|
||||
const user = await getUser(req);
|
||||
const channels = getNotificationChannels();
|
||||
const settings: NotificationSettings = req.body;
|
||||
if (settings.channels.some(c => !channels.includes(c.id))) {
|
||||
throw new InputError('Invalid channel');
|
||||
}
|
||||
await store.saveNotificationSettings({ user, settings });
|
||||
const response = await getNotificationSettings(user);
|
||||
res.json(response);
|
||||
});
|
||||
|
||||
const getNotificationHandler = async (req: Request, res: Response) => {
|
||||
router.get('/topics', async (req, res) => {
|
||||
const user = await getUser(req);
|
||||
const opts: TopicGetOptions = { user };
|
||||
appendCommonOptions(req, opts);
|
||||
const topics = await store.getTopics(opts);
|
||||
res.json(topics);
|
||||
});
|
||||
|
||||
const getNotificationHandler: openapi.EndpointMapRequestHandler<
|
||||
EndpointMap,
|
||||
'/notifications/{id}',
|
||||
'get'
|
||||
> = async (req, res) => {
|
||||
const user = await getUser(req);
|
||||
const opts: NotificationGetOptions = {
|
||||
user: user,
|
||||
user,
|
||||
limit: 1,
|
||||
ids: [req.params.id],
|
||||
};
|
||||
@@ -572,31 +570,17 @@ export async function createRouter(
|
||||
res.json(notifications[0]);
|
||||
};
|
||||
|
||||
// Get topics
|
||||
const listTopicsHandler = async (req: Request, res: Response) => {
|
||||
const user = await getUser(req);
|
||||
const opts: TopicGetOptions = {
|
||||
user: user,
|
||||
};
|
||||
|
||||
appendCommonOptions(req, opts);
|
||||
|
||||
const topics = await store.getTopics(opts);
|
||||
res.json(topics);
|
||||
};
|
||||
|
||||
router.get('/topics', listTopicsHandler);
|
||||
|
||||
// Make sure this is the last "GET" handler
|
||||
router.get('/:id', getNotificationHandler); // Deprecated endpoint
|
||||
// Make sure this is the last "GET" handler.
|
||||
router.get('/:id', getNotificationHandler); // Deprecated alias of /notifications/:id
|
||||
router.get('/notifications/:id', getNotificationHandler);
|
||||
|
||||
const updateNotificationsHandler = async (req: Request, res: Response) => {
|
||||
const updateNotificationsHandler: openapi.EndpointMapRequestHandler<
|
||||
EndpointMap,
|
||||
'/notifications/update',
|
||||
'post'
|
||||
> = async (req, res) => {
|
||||
const user = await getUser(req);
|
||||
const { ids, read, saved } = req.body;
|
||||
if (!ids || !Array.isArray(ids)) {
|
||||
throw new InputError();
|
||||
}
|
||||
|
||||
if (read === true) {
|
||||
await store.markRead({ user, ids });
|
||||
@@ -609,7 +593,7 @@ export async function createRouter(
|
||||
});
|
||||
}
|
||||
} else if (read === false) {
|
||||
await store.markUnread({ user: user, ids });
|
||||
await store.markUnread({ user, ids });
|
||||
|
||||
if (signals) {
|
||||
await signals.publish<NotificationReadSignal>({
|
||||
@@ -621,16 +605,16 @@ export async function createRouter(
|
||||
}
|
||||
|
||||
if (saved === true) {
|
||||
await store.markSaved({ user: user, ids });
|
||||
await store.markSaved({ user, ids });
|
||||
} else if (saved === false) {
|
||||
await store.markUnsaved({ user: user, ids });
|
||||
await store.markUnsaved({ user, ids });
|
||||
}
|
||||
|
||||
const notifications = await store.getNotifications({ ids, user: user });
|
||||
const notifications = await store.getNotifications({ ids, user });
|
||||
res.json(notifications);
|
||||
};
|
||||
|
||||
router.post('/update', updateNotificationsHandler); // Deprecated endpoint
|
||||
router.post('/update', updateNotificationsHandler); // Deprecated alias of /notifications/update
|
||||
router.post('/notifications/update', updateNotificationsHandler);
|
||||
|
||||
const sendBroadcastNotification = async (
|
||||
@@ -768,10 +752,11 @@ export async function createRouter(
|
||||
return sent.filter(n => n !== undefined);
|
||||
};
|
||||
|
||||
const createNotificationHandler = async (
|
||||
req: Request<any, Notification[], NotificationSendOptions>,
|
||||
res: Response,
|
||||
) => {
|
||||
const createNotificationsHandler: openapi.EndpointMapRequestHandler<
|
||||
EndpointMap,
|
||||
'/notifications',
|
||||
'post'
|
||||
> = async (req, res) => {
|
||||
const credentials = await httpAuth.credentials(req, {
|
||||
allow: ['service'],
|
||||
});
|
||||
@@ -848,8 +833,8 @@ export async function createRouter(
|
||||
};
|
||||
|
||||
// Add new notification
|
||||
router.post('/', createNotificationHandler);
|
||||
router.post('/notifications', createNotificationHandler);
|
||||
router.post('/', createNotificationsHandler); // Deprecated alias of /notifications
|
||||
router.post('/notifications', createNotificationsHandler);
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user