You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
8.1 KiB
185 lines
8.1 KiB
"use strict"; |
|
/** |
|
* |
|
* common |
|
* |
|
*/ |
|
Object.defineProperty(exports, "__esModule", { value: true }); |
|
exports.stringifyMessage = exports.parseMessage = exports.isMessage = exports.validateMessage = exports.MessageType = exports.CloseCode = exports.DEPRECATED_GRAPHQL_WS_PROTOCOL = exports.GRAPHQL_TRANSPORT_WS_PROTOCOL = void 0; |
|
const utils_1 = require("./utils"); |
|
/** |
|
* The WebSocket sub-protocol used for the [GraphQL over WebSocket Protocol](https://github.com/graphql/graphql-over-http/blob/main/rfcs/GraphQLOverWebSocket.md). |
|
* |
|
* @category Common |
|
*/ |
|
exports.GRAPHQL_TRANSPORT_WS_PROTOCOL = 'graphql-transport-ws'; |
|
/** |
|
* The deprecated subprotocol used by [subscriptions-transport-ws](https://github.com/apollographql/subscriptions-transport-ws). |
|
* |
|
* @private |
|
*/ |
|
exports.DEPRECATED_GRAPHQL_WS_PROTOCOL = 'graphql-ws'; |
|
/** |
|
* `graphql-ws` expected and standard close codes of the [GraphQL over WebSocket Protocol](https://github.com/graphql/graphql-over-http/blob/main/rfcs/GraphQLOverWebSocket.md). |
|
* |
|
* @category Common |
|
*/ |
|
var CloseCode; |
|
(function (CloseCode) { |
|
CloseCode[CloseCode["InternalServerError"] = 4500] = "InternalServerError"; |
|
CloseCode[CloseCode["InternalClientError"] = 4005] = "InternalClientError"; |
|
CloseCode[CloseCode["BadRequest"] = 4400] = "BadRequest"; |
|
CloseCode[CloseCode["BadResponse"] = 4004] = "BadResponse"; |
|
/** Tried subscribing before connect ack */ |
|
CloseCode[CloseCode["Unauthorized"] = 4401] = "Unauthorized"; |
|
CloseCode[CloseCode["Forbidden"] = 4403] = "Forbidden"; |
|
CloseCode[CloseCode["SubprotocolNotAcceptable"] = 4406] = "SubprotocolNotAcceptable"; |
|
CloseCode[CloseCode["ConnectionInitialisationTimeout"] = 4408] = "ConnectionInitialisationTimeout"; |
|
CloseCode[CloseCode["ConnectionAcknowledgementTimeout"] = 4504] = "ConnectionAcknowledgementTimeout"; |
|
/** Subscriber distinction is very important */ |
|
CloseCode[CloseCode["SubscriberAlreadyExists"] = 4409] = "SubscriberAlreadyExists"; |
|
CloseCode[CloseCode["TooManyInitialisationRequests"] = 4429] = "TooManyInitialisationRequests"; |
|
})(CloseCode || (exports.CloseCode = CloseCode = {})); |
|
/** |
|
* Types of messages allowed to be sent by the client/server over the WS protocol. |
|
* |
|
* @category Common |
|
*/ |
|
var MessageType; |
|
(function (MessageType) { |
|
MessageType["ConnectionInit"] = "connection_init"; |
|
MessageType["ConnectionAck"] = "connection_ack"; |
|
MessageType["Ping"] = "ping"; |
|
MessageType["Pong"] = "pong"; |
|
MessageType["Subscribe"] = "subscribe"; |
|
MessageType["Next"] = "next"; |
|
MessageType["Error"] = "error"; |
|
MessageType["Complete"] = "complete"; |
|
})(MessageType || (exports.MessageType = MessageType = {})); |
|
/** |
|
* Validates the message against the GraphQL over WebSocket Protocol. |
|
* |
|
* Invalid messages will throw descriptive errors. |
|
* |
|
* @category Common |
|
*/ |
|
function validateMessage(val) { |
|
if (!(0, utils_1.isObject)(val)) { |
|
throw new Error(`Message is expected to be an object, but got ${(0, utils_1.extendedTypeof)(val)}`); |
|
} |
|
if (!val.type) { |
|
throw new Error(`Message is missing the 'type' property`); |
|
} |
|
if (typeof val.type !== 'string') { |
|
throw new Error(`Message is expects the 'type' property to be a string, but got ${(0, utils_1.extendedTypeof)(val.type)}`); |
|
} |
|
switch (val.type) { |
|
case MessageType.ConnectionInit: |
|
case MessageType.ConnectionAck: |
|
case MessageType.Ping: |
|
case MessageType.Pong: { |
|
if (val.payload != null && !(0, utils_1.isObject)(val.payload)) { |
|
throw new Error(`"${val.type}" message expects the 'payload' property to be an object or nullish or missing, but got "${val.payload}"`); |
|
} |
|
break; |
|
} |
|
case MessageType.Subscribe: { |
|
if (typeof val.id !== 'string') { |
|
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${(0, utils_1.extendedTypeof)(val.id)}`); |
|
} |
|
if (!val.id) { |
|
throw new Error(`"${val.type}" message requires a non-empty 'id' property`); |
|
} |
|
if (!(0, utils_1.isObject)(val.payload)) { |
|
throw new Error(`"${val.type}" message expects the 'payload' property to be an object, but got ${(0, utils_1.extendedTypeof)(val.payload)}`); |
|
} |
|
if (typeof val.payload.query !== 'string') { |
|
throw new Error(`"${val.type}" message payload expects the 'query' property to be a string, but got ${(0, utils_1.extendedTypeof)(val.payload.query)}`); |
|
} |
|
if (val.payload.variables != null && !(0, utils_1.isObject)(val.payload.variables)) { |
|
throw new Error(`"${val.type}" message payload expects the 'variables' property to be a an object or nullish or missing, but got ${(0, utils_1.extendedTypeof)(val.payload.variables)}`); |
|
} |
|
if (val.payload.operationName != null && |
|
(0, utils_1.extendedTypeof)(val.payload.operationName) !== 'string') { |
|
throw new Error(`"${val.type}" message payload expects the 'operationName' property to be a string or nullish or missing, but got ${(0, utils_1.extendedTypeof)(val.payload.operationName)}`); |
|
} |
|
if (val.payload.extensions != null && !(0, utils_1.isObject)(val.payload.extensions)) { |
|
throw new Error(`"${val.type}" message payload expects the 'extensions' property to be a an object or nullish or missing, but got ${(0, utils_1.extendedTypeof)(val.payload.extensions)}`); |
|
} |
|
break; |
|
} |
|
case MessageType.Next: { |
|
if (typeof val.id !== 'string') { |
|
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${(0, utils_1.extendedTypeof)(val.id)}`); |
|
} |
|
if (!val.id) { |
|
throw new Error(`"${val.type}" message requires a non-empty 'id' property`); |
|
} |
|
if (!(0, utils_1.isObject)(val.payload)) { |
|
throw new Error(`"${val.type}" message expects the 'payload' property to be an object, but got ${(0, utils_1.extendedTypeof)(val.payload)}`); |
|
} |
|
break; |
|
} |
|
case MessageType.Error: { |
|
if (typeof val.id !== 'string') { |
|
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${(0, utils_1.extendedTypeof)(val.id)}`); |
|
} |
|
if (!val.id) { |
|
throw new Error(`"${val.type}" message requires a non-empty 'id' property`); |
|
} |
|
if (!(0, utils_1.areGraphQLErrors)(val.payload)) { |
|
throw new Error(`"${val.type}" message expects the 'payload' property to be an array of GraphQL errors, but got ${JSON.stringify(val.payload)}`); |
|
} |
|
break; |
|
} |
|
case MessageType.Complete: { |
|
if (typeof val.id !== 'string') { |
|
throw new Error(`"${val.type}" message expects the 'id' property to be a string, but got ${(0, utils_1.extendedTypeof)(val.id)}`); |
|
} |
|
if (!val.id) { |
|
throw new Error(`"${val.type}" message requires a non-empty 'id' property`); |
|
} |
|
break; |
|
} |
|
default: |
|
throw new Error(`Invalid message 'type' property "${val.type}"`); |
|
} |
|
return val; |
|
} |
|
exports.validateMessage = validateMessage; |
|
/** |
|
* Checks if the provided value is a valid GraphQL over WebSocket message. |
|
* |
|
* @deprecated Use `validateMessage` instead. |
|
* |
|
* @category Common |
|
*/ |
|
function isMessage(val) { |
|
try { |
|
validateMessage(val); |
|
return true; |
|
} |
|
catch (_a) { |
|
return false; |
|
} |
|
} |
|
exports.isMessage = isMessage; |
|
/** |
|
* Parses the raw websocket message data to a valid message. |
|
* |
|
* @category Common |
|
*/ |
|
function parseMessage(data, reviver) { |
|
return validateMessage(typeof data === 'string' ? JSON.parse(data, reviver) : data); |
|
} |
|
exports.parseMessage = parseMessage; |
|
/** |
|
* Stringifies a valid message ready to be sent through the socket. |
|
* |
|
* @category Common |
|
*/ |
|
function stringifyMessage(msg, replacer) { |
|
validateMessage(msg); |
|
return JSON.stringify(msg, replacer); |
|
} |
|
exports.stringifyMessage = stringifyMessage;
|
|
|