notification.js•20.7 kB
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildNotificationsFromMetadata = exports.buildGqlStatusObjectFromMetadata = exports.polyfillNotification = exports.polyfillGqlStatusObject = exports.GqlStatusObject = exports.Notification = exports.notificationClassification = exports.notificationCategory = exports.notificationSeverityLevel = void 0;
/**
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* 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.
*/
var json = __importStar(require("./json"));
var internal_1 = require("./internal");
var gql_constants_1 = require("./gql-constants");
var unknownGqlStatus = {
WARNING: {
gql_status: '01N42',
status_description: 'warn: unknown warning'
},
NO_DATA: {
gql_status: '02N42',
status_description: 'note: no data - unknown subcondition'
},
INFORMATION: {
gql_status: '03N42',
status_description: 'info: unknown notification'
},
ERROR: {
gql_status: '50N42',
status_description: 'error: general processing exception - unexpected error'
}
};
/**
* @typedef {'WARNING' | 'INFORMATION' | 'UNKNOWN'} NotificationSeverityLevel
*/
/**
* Constants that represents the Severity level in the {@link Notification}
*/
var notificationSeverityLevel = {
WARNING: 'WARNING',
INFORMATION: 'INFORMATION',
UNKNOWN: 'UNKNOWN'
};
exports.notificationSeverityLevel = notificationSeverityLevel;
Object.freeze(notificationSeverityLevel);
var severityLevels = Object.values(notificationSeverityLevel);
/**
* @typedef {'HINT' | 'UNRECOGNIZED' | 'UNSUPPORTED' |'PERFORMANCE' | 'TOPOLOGY' | 'SECURITY' | 'DEPRECATION' | 'GENERIC' | 'SCHEMA' | 'UNKNOWN' } NotificationCategory
*/
/**
* Constants that represents the Category in the {@link Notification}
*/
var notificationCategory = {
HINT: 'HINT',
UNRECOGNIZED: 'UNRECOGNIZED',
UNSUPPORTED: 'UNSUPPORTED',
PERFORMANCE: 'PERFORMANCE',
DEPRECATION: 'DEPRECATION',
TOPOLOGY: 'TOPOLOGY',
SECURITY: 'SECURITY',
GENERIC: 'GENERIC',
SCHEMA: 'SCHEMA',
UNKNOWN: 'UNKNOWN'
};
exports.notificationCategory = notificationCategory;
Object.freeze(notificationCategory);
var categories = Object.values(notificationCategory);
/**
* @typedef {NotificationCategory} NotificationClassification
* @experimental
*/
/**
* Constants that represents the Classification in the {@link GqlStatusObject}
* @type {notificationCategory}
* @experimental
*/
var notificationClassification = notificationCategory;
exports.notificationClassification = notificationClassification;
/**
* Class for Cypher notifications
* @access public
*/
var Notification = /** @class */ (function () {
/**
* Create a Notification instance
* @constructor
* @param {Object} notification - Object with notification data
*/
function Notification(notification) {
/**
* The code
* @type {string}
* @public
*/
this.code = notification.code;
/**
* The title
* @type {string}
* @public
*/
this.title = notification.title;
/**
* The description
* @type {string}
* @public
*/
this.description = notification.description;
/**
* The raw severity
*
* Use {@link Notification#rawSeverityLevel} for the raw value or {@link Notification#severityLevel} for an enumerated value.
*
* @type {string}
* @public
* @deprecated This property will be removed in 6.0.
*/
this.severity = notification.severity;
/**
* The position which the notification had occur.
*
* @type {NotificationPosition}
* @public
*/
this.position = _constructPosition(notification.position);
/**
* The severity level
*
* @type {NotificationSeverityLevel}
* @public
* @example
* const { summary } = await session.run("RETURN 1")
*
* for (const notification of summary.notifications) {
* switch(notification.severityLevel) {
* case neo4j.notificationSeverityLevel.INFORMATION: // or simply 'INFORMATION'
* console.info(`${notification.title} - ${notification.description}`)
* break
* case neo4j.notificationSeverityLevel.WARNING: // or simply 'WARNING'
* console.warn(`${notification.title} - ${notification.description}`)
* break
* case neo4j.notificationSeverityLevel.UNKNOWN: // or simply 'UNKNOWN'
* default:
* // the raw info came from the server could be found at notification.rawSeverityLevel
* console.log(`${notification.title} - ${notification.description}`)
* break
* }
* }
*/
this.severityLevel = _asEnumerableSeverity(notification.severity);
/**
* The severity level returned by the server without any validation.
*
* @type {string}
* @public
*/
this.rawSeverityLevel = notification.severity;
/**
* The category
*
* @type {NotificationCategory}
* @public
* @example
* const { summary } = await session.run("RETURN 1")
*
* for (const notification of summary.notifications) {
* switch(notification.category) {
* case neo4j.notificationCategory.QUERY: // or simply 'QUERY'
* console.info(`${notification.title} - ${notification.description}`)
* break
* case neo4j.notificationCategory.PERFORMANCE: // or simply 'PERFORMANCE'
* console.warn(`${notification.title} - ${notification.description}`)
* break
* case neo4j.notificationCategory.UNKNOWN: // or simply 'UNKNOWN'
* default:
* // the raw info came from the server could be found at notification.rawCategory
* console.log(`${notification.title} - ${notification.description}`)
* break
* }
* }
*/
this.category = _asEnumerableClassification(notification.category);
/**
* The category returned by the server without any validation.
*
* @type {string|undefined}
* @public
*/
this.rawCategory = notification.category;
}
return Notification;
}());
exports.Notification = Notification;
/**
* Representation for GqlStatusObject found when executing a query.
* <p>
* This object represents a status of query execution.
* This status is a superset of {@link Notification}.
*
* @experimental
* @public
*/
var GqlStatusObject = /** @class */ (function () {
/**
*
* @param rawGqlStatusObject
* @private
*/
function GqlStatusObject(rawGqlStatusObject) {
var _a;
/**
* The GQLSTATUS
*
* @type {string}
* @public
*/
this.gqlStatus = rawGqlStatusObject.gql_status;
/**
* The GQLSTATUS description
*
* @type {string}
* @public
*/
this.statusDescription = rawGqlStatusObject.status_description;
/**
* The diagnostic record as it is.
*
* @type {object}
* @public
*/
this.diagnosticRecord = (_a = rawGqlStatusObject.diagnostic_record) !== null && _a !== void 0 ? _a : {};
/**
* The position at which the notification had occurred.
*
* @type {NotificationPosition | undefined}
* @public
*/
this.position = this.diagnosticRecord._position != null ? _constructPosition(this.diagnosticRecord._position) : undefined;
/**
* The severity
*
* @type {NotificationSeverityLevel}
* @public
* @example
* const { summary } = await session.run("RETURN 1")
*
* for (const gqlStatusObject of summary.gqlStatusObjects) {
* switch(gqlStatusObject.severity) {
* case neo4j.notificationSeverityLevel.INFORMATION: // or simply 'INFORMATION'
* console.info(gqlStatusObject.statusDescription)
* break
* case neo4j.notificationSeverityLevel.WARNING: // or simply 'WARNING'
* console.warn(gqlStatusObject.statusDescription)
* break
* case neo4j.notificationSeverityLevel.UNKNOWN: // or simply 'UNKNOWN'
* default:
* // the raw info came from the server could be found at gqlStatusObject.rawSeverity
* console.log(gqlStatusObject.statusDescription)
* break
* }
* }
*/
this.severity = _asEnumerableSeverity(this.diagnosticRecord._severity);
/**
* The severity returned in the diagnostic record from the server without any validation.
*
* @type {string | undefined}
* @public
*/
this.rawSeverity = this.diagnosticRecord._severity;
/**
* The classification
*
* @type {NotificationClassification}
* @public
* @example
* const { summary } = await session.run("RETURN 1")
*
* for (const gqlStatusObject of summary.gqlStatusObjects) {
* switch(gqlStatusObject.classification) {
* case neo4j.notificationClassification.QUERY: // or simply 'QUERY'
* console.info(gqlStatusObject.statusDescription)
* break
* case neo4j.notificationClassification.PERFORMANCE: // or simply 'PERFORMANCE'
* console.warn(gqlStatusObject.statusDescription)
* break
* case neo4j.notificationClassification.UNKNOWN: // or simply 'UNKNOWN'
* default:
* // the raw info came from the server can be found at notification.rawCategory
* console.log(gqlStatusObject.statusDescription)
* break
* }
* }
*/
this.classification = _asEnumerableClassification(this.diagnosticRecord._classification);
/**
* The category returned by the server without any validation.
*
* @type {string|undefined}
* @public
*/
this.rawClassification = this.diagnosticRecord._classification;
/**
* Indicates if this object represents a notification and it can be filtered using
* NotificationFilter.
*
* Only GqlStatusObject which is Notification has meaningful position, severity and
* classification.
*
* @type {boolean}
* @public
*/
this.isNotification = rawGqlStatusObject.neo4j_code != null;
Object.freeze(this);
}
Object.defineProperty(GqlStatusObject.prototype, "diagnosticRecordAsJsonString", {
/**
* The json string representation of the diagnostic record.
* The goal of this method is provide a serialized object for human inspection.
*
* @type {string}
* @public
*/
get: function () {
return json.stringify(this.diagnosticRecord, { useCustomToString: true });
},
enumerable: false,
configurable: true
});
return GqlStatusObject;
}());
exports.GqlStatusObject = GqlStatusObject;
/**
*
* @private
* @param status
* @returns {Notification|undefined}
*/
function polyfillNotification(status) {
var _a, _b, _c;
// Non notification status should have neo4j_code
if (status.neo4j_code == null) {
return undefined;
}
return new Notification({
code: status.neo4j_code,
title: status.title,
description: status.description,
severity: (_a = status.diagnostic_record) === null || _a === void 0 ? void 0 : _a._severity,
category: (_b = status.diagnostic_record) === null || _b === void 0 ? void 0 : _b._classification,
position: (_c = status.diagnostic_record) === null || _c === void 0 ? void 0 : _c._position
});
}
exports.polyfillNotification = polyfillNotification;
/**
* @private
* @param notification
* @returns {GqlStatusObject}
*/
function polyfillGqlStatusObject(notification) {
var _a;
var defaultStatus = notification.severity === notificationSeverityLevel.WARNING ? unknownGqlStatus.WARNING : unknownGqlStatus.INFORMATION;
var polyfilledRawObj = {
gql_status: defaultStatus.gql_status,
status_description: (_a = notification.description) !== null && _a !== void 0 ? _a : defaultStatus.status_description,
neo4j_code: notification.code,
title: notification.title,
diagnostic_record: __assign({}, gql_constants_1.rawPolyfilledDiagnosticRecord)
};
if (notification.severity != null) {
polyfilledRawObj.diagnostic_record._severity = notification.severity;
}
if (notification.category != null) {
polyfilledRawObj.diagnostic_record._classification = notification.category;
}
if (notification.position != null) {
polyfilledRawObj.diagnostic_record._position = notification.position;
}
return new GqlStatusObject(polyfilledRawObj);
}
exports.polyfillGqlStatusObject = polyfillGqlStatusObject;
/**
* This objects are used for polyfilling the first status on the status list
*
* @private
*/
var staticGqlStatusObjects = {
SUCCESS: new GqlStatusObject({
gql_status: '00000',
status_description: 'note: successful completion',
diagnostic_record: gql_constants_1.rawPolyfilledDiagnosticRecord
}),
NO_DATA: new GqlStatusObject({
gql_status: '02000',
status_description: 'note: no data',
diagnostic_record: gql_constants_1.rawPolyfilledDiagnosticRecord
}),
NO_DATA_UNKNOWN_SUBCONDITION: new GqlStatusObject(__assign(__assign({}, unknownGqlStatus.NO_DATA), { diagnostic_record: gql_constants_1.rawPolyfilledDiagnosticRecord })),
OMITTED_RESULT: new GqlStatusObject({
gql_status: '00001',
status_description: 'note: successful completion - omitted result',
diagnostic_record: gql_constants_1.rawPolyfilledDiagnosticRecord
})
};
Object.freeze(staticGqlStatusObjects);
/**
*
* @private
* @param metadata
* @returns
*/
function buildGqlStatusObjectFromMetadata(metadata) {
var _a, _b;
function getGqlStatusObjectFromStreamSummary(summary) {
if ((summary === null || summary === void 0 ? void 0 : summary.have_records_streamed) === true) {
return staticGqlStatusObjects.SUCCESS;
}
if ((summary === null || summary === void 0 ? void 0 : summary.has_keys) === false) {
return staticGqlStatusObjects.OMITTED_RESULT;
}
if ((summary === null || summary === void 0 ? void 0 : summary.pulled) === true) {
return staticGqlStatusObjects.NO_DATA;
}
return staticGqlStatusObjects.NO_DATA_UNKNOWN_SUBCONDITION;
}
if (metadata.statuses != null) {
return metadata.statuses.map(function (status) { return new GqlStatusObject(status); });
}
var clientGenerated = getGqlStatusObjectFromStreamSummary(metadata.stream_summary);
var polyfilledObjects = __spreadArray([clientGenerated], __read(((_b = (_a = metadata.notifications) === null || _a === void 0 ? void 0 : _a.map(polyfillGqlStatusObject)) !== null && _b !== void 0 ? _b : [])), false);
return polyfilledObjects.sort(function (a, b) { return calculateWeight(a) - calculateWeight(b); });
}
exports.buildGqlStatusObjectFromMetadata = buildGqlStatusObjectFromMetadata;
var gqlStatusWeightByClass = Object.freeze({
'02': 0,
'01': 1,
'00': 2
});
/**
* GqlStatus weight
*
* @private
*/
function calculateWeight(gqlStatusObject) {
var _a, _b;
var gqlClass = (_a = gqlStatusObject.gqlStatus) === null || _a === void 0 ? void 0 : _a.slice(0, 2);
// @ts-expect-error
return (_b = gqlStatusWeightByClass[gqlClass]) !== null && _b !== void 0 ? _b : 9999;
}
/**
*
* @private
* @param metadata
* @returns
*/
function buildNotificationsFromMetadata(metadata) {
if (metadata.notifications != null) {
return metadata.notifications.map(function (n) { return new Notification(n); });
}
if (metadata.statuses != null) {
return metadata.statuses.map(polyfillNotification).filter(function (n) { return n != null; });
}
return [];
}
exports.buildNotificationsFromMetadata = buildNotificationsFromMetadata;
/**
*
* @private
* @param pos
* @returns {NotificationPosition}
*/
function _constructPosition(pos) {
if (pos == null) {
return {};
}
/* eslint-disable @typescript-eslint/no-non-null-assertion */
return {
offset: internal_1.util.toNumber(pos.offset),
line: internal_1.util.toNumber(pos.line),
column: internal_1.util.toNumber(pos.column)
};
/* eslint-enable @typescript-eslint/no-non-null-assertion */
}
function _asEnumerableSeverity(severity) {
return severityLevels.includes(severity)
? severity
: notificationSeverityLevel.UNKNOWN;
}
function _asEnumerableClassification(classification) {
return categories.includes(classification)
? classification
: notificationClassification.UNKNOWN;
}
exports.default = Notification;