New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

datocms-listen

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

datocms-listen - npm Package Compare versions

Comparing version 0.1.14 to 0.1.15

81

dist/subscribeToQuery/__tests__/index.test.js

@@ -96,4 +96,3 @@ "use strict";

};
MyEventSource.prototype.close = function () {
};
MyEventSource.prototype.close = function () { };
return MyEventSource;

@@ -218,2 +217,76 @@ }());

}); });
it("handles TypedDocumentNode as query", function () { return __awaiter(void 0, void 0, void 0, function () {
var fetcher, onUpdateEventDefer, HomeDocument, data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
fetcher = makeFakeFetch();
onUpdateEventDefer = (0, p_defer_1["default"])();
HomeDocument = {
kind: "Document",
definitions: [
{
kind: "OperationDefinition",
operation: "query",
name: { kind: "Name", value: "Home" },
selectionSet: {
kind: "SelectionSet",
selections: [
{
kind: "Field",
name: { kind: "Name", value: "allArticles" },
selectionSet: {
kind: "SelectionSet",
selections: [
{ kind: "Field", name: { kind: "Name", value: "id" } },
{ kind: "Field", name: { kind: "Name", value: "title" } },
{
kind: "Field",
name: { kind: "Name", value: "_createdAt" }
},
{
kind: "Field",
name: { kind: "Name", value: "_publishedAt" }
},
]
}
},
]
}
},
]
};
(0, index_1.subscribeToQuery)({
query: HomeDocument,
token: "XXX",
preview: true,
environment: "foobar",
reconnectionPeriod: 10,
fetcher: fetcher,
eventSourceClass: MockEventSource,
onUpdate: function (data) {
onUpdateEventDefer.resolve(data);
}
});
setTimeout(function () {
if (streams[0].listeners["open"]) {
streams[0].listeners["open"].forEach(function (cb) { return cb(true); });
}
}, 100);
setTimeout(function () {
if (streams[0].listeners["update"]) {
var error_3 = {
data: JSON.stringify(true)
};
streams[0].listeners["update"].forEach(function (cb) { return cb(error_3); });
}
}, 200);
return [4 /*yield*/, onUpdateEventDefer.promise];
case 1:
data = _a.sent();
expect(data).toEqual(true);
return [2 /*return*/];
}
});
}); });
it("notifies events", function () { return __awaiter(void 0, void 0, void 0, function () {

@@ -276,3 +349,3 @@ var fetcher, onEventDefer, event;

});
var error = new MessageEvent('FetchError', { data: data });
var error = new MessageEvent("FetchError", { data: data });
streams[0].listeners["onerror"].forEach(function (cb) { return cb(error); });

@@ -283,3 +356,3 @@ }, 200);

error = _a.sent();
console.log('error:', error);
console.log("error:", error);
data = JSON.parse(error.data);

@@ -286,0 +359,0 @@ expect(data.message).toEqual("Not Found");

@@ -0,1 +1,35 @@

import type * as GraphQLWeb from "@0no-co/graphql.web";
/** A GraphQL `DocumentNode` with attached generics for its result data and variables.
*
* @remarks
* A GraphQL {@link DocumentNode} defines both the variables it accepts on request and the `data`
* shape it delivers on a response in the GraphQL query language.
*
* To bridge the gap to TypeScript, tools may be used to generate TypeScript types that define the shape
* of `data` and `variables` ahead of time. These types are then attached to GraphQL documents using this
* `TypedDocumentNode` type.
*
* Using a `DocumentNode` that is typed like this will cause any `urql` API to type its input `variables`
* and resulting `data` using the types provided.
*
* @privateRemarks
* For compatibility reasons this type has been copied and internalized from:
* https://github.com/dotansimha/graphql-typed-document-node/blob/3711b12/packages/core/src/index.ts#L3-L10
*
* @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information.
*/
export declare type TypedDocumentNode<Result = {
[key: string]: any;
}, Variables = {
[key: string]: any;
}> = GraphQLWeb.DocumentNode & {
/** Type to support `@graphql-typed-document-node/core`
* @internal
*/
__apiType?: (variables: Variables) => Result;
/** Type to support `TypedQueryDocumentNode` from `graphql`
* @internal
*/
__ensureTypesOfVariablesAndResultMatching?: (variables: Variables) => Result;
};
export declare type UpdateData<QueryResult> = {

@@ -18,3 +52,3 @@ /** The raw GraphQL response */

};
export declare type ConnectionStatus = 'connecting' | 'connected' | 'closed';
export declare type ConnectionStatus = "connecting" | "connected" | "closed";
export declare type EventData = {

@@ -31,4 +65,4 @@ /** The current status of the connection **/

export declare type Options<QueryResult, QueryVariables> = {
/** The GraphQL query to subscribe */
query: string;
/** The GraphQL query to subscribe, or a TypedDocumentNode */
query: string | TypedDocumentNode<QueryResult, QueryVariables>;
/** GraphQL variables for the query */

@@ -35,0 +69,0 @@ variables?: QueryVariables;

40

dist/subscribeToQuery/index.js

@@ -66,2 +66,3 @@ "use strict";

exports.subscribeToQuery = exports.InvalidResponseError = exports.Response400Error = exports.Response500Error = void 0;
var graphql_web_1 = require("@0no-co/graphql.web");
var MessageEventMock = /** @class */ (function () {

@@ -74,3 +75,3 @@ function MessageEventMock(type, options) {

}());
var MessageEventClass = typeof MessageEvent !== 'undefined'
var MessageEventClass = typeof MessageEvent !== "undefined"
? MessageEvent

@@ -113,3 +114,3 @@ : MessageEventMock;

return __awaiter(this, void 0, void 0, function () {
var query, token, variables, preview, includeDrafts, excludeInvalid, environment, customFetcher, customEventSourceClass, onStatusChange, onUpdate, onChannelError, onError, onEvent, customReconnectionPeriod, customBaseUrl, fetcher, EventSourceClass, reconnectionPeriod, baseUrl, waitAndReconnect, channelUrl, req, registration, e_1, event_1;
var query, token, variables, preview, includeDrafts, excludeInvalid, environment, customFetcher, customEventSourceClass, onStatusChange, onUpdate, onChannelError, onError, onEvent, customReconnectionPeriod, customBaseUrl, fetcher, EventSourceClass, reconnectionPeriod, baseUrl, waitAndReconnect, channelUrl, realQuery, req, registration, e_1, event_1;
var _this = this;

@@ -123,3 +124,3 @@ return __generator(this, function (_a) {

reconnectionPeriod = Math.min(customReconnectionPeriod || 1000, 20000);
baseUrl = customBaseUrl || 'https://graphql-listen.datocms.com';
baseUrl = customBaseUrl || "https://graphql-listen.datocms.com";
waitAndReconnect = function () { return __awaiter(_this, void 0, void 0, function () {

@@ -136,3 +137,3 @@ return __generator(this, function (_a) {

if (onStatusChange) {
onStatusChange('connecting');
onStatusChange("connecting");
}

@@ -142,6 +143,7 @@ _a.label = 1;

_a.trys.push([1, 4, , 5]);
realQuery = typeof query === "string" ? query : (0, graphql_web_1.print)(query);
return [4 /*yield*/, fetcher(baseUrl, {
headers: __assign(__assign(__assign({ Authorization: "Bearer ".concat(token), Accept: "application/json" }, (environment ? { 'X-Environment': environment } : {})), (includeDrafts || preview ? { 'X-Include-Drafts': 'true' } : {})), (excludeInvalid ? { 'X-Exclude-Invalid': 'true' } : {})),
method: 'POST',
body: JSON.stringify({ query: query, variables: variables })
headers: __assign(__assign(__assign({ Authorization: "Bearer ".concat(token), Accept: "application/json" }, (environment ? { "X-Environment": environment } : {})), (includeDrafts || preview ? { "X-Include-Drafts": "true" } : {})), (excludeInvalid ? { "X-Exclude-Invalid": "true" } : {})),
method: "POST",
body: JSON.stringify({ query: realQuery, variables: variables })
})];

@@ -156,4 +158,4 @@ case 2:

}
if (req.headers.get('Content-Type') !== 'application/json') {
throw new InvalidResponseError("Invalid content type: ".concat(req.headers.get('Content-Type')), req);
if (req.headers.get("Content-Type") !== "application/json") {
throw new InvalidResponseError("Invalid content type: ".concat(req.headers.get("Content-Type")), req);
}

@@ -166,5 +168,5 @@ return [4 /*yield*/, req.json()];

onEvent({
status: 'connecting',
status: "connecting",
channelUrl: channelUrl,
message: 'Received channel URL',
message: "Received channel URL",
response: req

@@ -177,3 +179,3 @@ });

if (onError) {
event_1 = new MessageEventClass('FetchError', { data: e_1 });
event_1 = new MessageEventClass("FetchError", { data: e_1 });
onError(event_1);

@@ -185,3 +187,3 @@ }

if (onStatusChange) {
onStatusChange('closed');
onStatusChange("closed");
}

@@ -198,5 +200,5 @@ return [2 /*return*/, waitAndReconnect()];

};
eventSource.addEventListener('open', function () {
eventSource.addEventListener("open", function () {
if (onStatusChange) {
onStatusChange('connected');
onStatusChange("connected");
}

@@ -209,3 +211,3 @@ resolve(unsubscribe);

if (onStatusChange) {
onStatusChange('closed');
onStatusChange("closed");
}

@@ -217,7 +219,7 @@ if (!stopReconnecting) {

}, 300);
eventSource.addEventListener('update', function (event) {
eventSource.addEventListener("update", function (event) {
var updateData = JSON.parse(event.data);
onUpdate(updateData);
});
eventSource.addEventListener('channelError', function (event) {
eventSource.addEventListener("channelError", function (event) {
var errorData = JSON.parse(event.data);

@@ -232,3 +234,3 @@ if (errorData.fatal) {

});
eventSource.addEventListener('onerror', function (event) {
eventSource.addEventListener("onerror", function (event) {
var messageEvent = event;

@@ -235,0 +237,0 @@ if (onError) {

{
"name": "datocms-listen",
"version": "0.1.14",
"version": "0.1.15",
"types": "dist/index.d.ts",

@@ -18,2 +18,3 @@ "main": "dist/index.js",

"devDependencies": {
"@graphql-typed-document-node/core": "^3.2.0",
"@types/jest": "^26.0.0",

@@ -63,3 +64,6 @@ "@types/raf": "^3.4.0",

]
},
"dependencies": {
"@0no-co/graphql.web": "^1.0.1"
}
}

@@ -85,18 +85,18 @@ # datocms-listen

| prop | type | required | description | default |
| ------------------ | ----------------------------------------------------------------------------------------- | ------------------ | ------------------------------------------------------------------ | ------------------------------------ |
| query | string | :white_check_mark: | The GraphQL query to subscribe | |
| token | string | :white_check_mark: | DatoCMS API token to use | |
| onUpdate | function | :white_check_mark: | Callback function to receive query update events | |
| onChannelError | function | :x: | Callback function to receive channelError events | |
| onStatusChange | function | :x: | Callback function to receive status change events | |
| onError | function | :x: | Callback function to receive error events | |
| onEvent | function | :x: | Callback function to receive other events | |
| variables | Object | :x: | GraphQL variables for the query | |
| preview | boolean | :x: | If true, the Content Delivery API with draft content will be used | false |
| environment | string | :x: | The name of the DatoCMS environment where to perform the query | defaults to primary environment |
| reconnectionPeriod | number | :x: | In case of network errors, the period (in ms) to wait to reconnect | 1000 |
| fetcher | a [fetch-like function](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) | :x: | The fetch function to use to perform the registration query | window.fetch |
| eventSourceClass | an [EventSource-like](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) class | :x: | The EventSource class to use to open up the SSE connection | window.EventSource |
| baseUrl | string | :x: | The base URL to use to perform the query | `https://graphql-listen.datocms.com` |
| prop | type | required | description | default |
| ------------------ | ------------------------------------------------------------------------------------------ | ------------------ | ------------------------------------------------------------------ | ------------------------------------ |
| query | string \| [`TypedDocumentNode`](https://github.com/dotansimha/graphql-typed-document-node) | :white_check_mark: | The GraphQL query to subscribe | |
| token | string | :white_check_mark: | DatoCMS API token to use | |
| onUpdate | function | :white_check_mark: | Callback function to receive query update events | |
| onChannelError | function | :x: | Callback function to receive channelError events | |
| onStatusChange | function | :x: | Callback function to receive status change events | |
| onError | function | :x: | Callback function to receive error events | |
| onEvent | function | :x: | Callback function to receive other events | |
| variables | Object | :x: | GraphQL variables for the query | |
| preview | boolean | :x: | If true, the Content Delivery API with draft content will be used | false |
| environment | string | :x: | The name of the DatoCMS environment where to perform the query | defaults to primary environment |
| reconnectionPeriod | number | :x: | In case of network errors, the period (in ms) to wait to reconnect | 1000 |
| fetcher | a [fetch-like function](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) | :x: | The fetch function to use to perform the registration query | window.fetch |
| eventSourceClass | an [EventSource-like](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) class | :x: | The EventSource class to use to open up the SSE connection | window.EventSource |
| baseUrl | string | :x: | The base URL to use to perform the query | `https://graphql-listen.datocms.com` |

@@ -137,5 +137,5 @@ ## Events

| prop | type | description |
| -------- | ------ | ------------------------------------------------------- |
| message | string | An human friendly message explaining the error |
| prop | type | description |
| ------- | ------ | ---------------------------------------------- |
| message | string | An human friendly message explaining the error |

@@ -148,7 +148,7 @@ ### `onEvent(event: EventData)`

| prop | type | description |
| ---------- | ------ | ------------------------------------------------------- |
| status | string | The current connection status (see above) |
| channelUrl | string | The current channel URL |
| message | string | An human friendly message explaining the event |
| prop | type | description |
| ---------- | ------ | ---------------------------------------------- |
| status | string | The current connection status (see above) |
| channelUrl | string | The current channel URL |
| message | string | An human friendly message explaining the event |

@@ -155,0 +155,0 @@ ## Return value

@@ -1,2 +0,8 @@

import { ChannelErrorData, EventData, Options, subscribeToQuery } from "../index";
import {
ChannelErrorData,
EventData,
Options,
subscribeToQuery,
} from "../index";
import { TypedDocumentNode } from "@graphql-typed-document-node/core";
import pDefer from "p-defer";

@@ -9,3 +15,3 @@

const makeFakeFetch = ({serverErrors = 1}: FakeFetchOptions = {}) => {
const makeFakeFetch = ({ serverErrors = 1 }: FakeFetchOptions = {}) => {
let times = 0;

@@ -37,3 +43,3 @@

return (fetcher as any) as Options<any, any>["fetcher"];
return fetcher as any as Options<any, any>["fetcher"];
};

@@ -64,7 +70,6 @@

close() {
}
close() {}
}
const MockEventSource = (MyEventSource as any) as Options<
const MockEventSource = MyEventSource as any as Options<
any,

@@ -145,3 +150,3 @@ any

const fetcher = makeFakeFetch();
const onUpdateEventDefer= pDefer<boolean>();
const onUpdateEventDefer = pDefer<boolean>();

@@ -180,2 +185,89 @@ subscribeToQuery({

it("handles TypedDocumentNode as query", async () => {
const fetcher = makeFakeFetch();
const onUpdateEventDefer = pDefer<boolean>();
// generated via
type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
type HomeQueryVariables = Exact<{ [key: string]: never }>;
type HomeQuery = {
__typename?: "Query";
allArticles: Array<{
__typename?: "ArticleRecord";
id: string;
title: string;
_createdAt: string;
_publishedAt?: string | null;
}>;
};
const HomeDocument = {
kind: "Document",
definitions: [
{
kind: "OperationDefinition",
operation: "query",
name: { kind: "Name", value: "Home" },
selectionSet: {
kind: "SelectionSet",
selections: [
{
kind: "Field",
name: { kind: "Name", value: "allArticles" },
selectionSet: {
kind: "SelectionSet",
selections: [
{ kind: "Field", name: { kind: "Name", value: "id" } },
{ kind: "Field", name: { kind: "Name", value: "title" } },
{
kind: "Field",
name: { kind: "Name", value: "_createdAt" },
},
{
kind: "Field",
name: { kind: "Name", value: "_publishedAt" },
},
],
},
},
],
},
},
],
} as unknown as TypedDocumentNode<HomeQuery, HomeQueryVariables>;
subscribeToQuery({
query: HomeDocument,
token: `XXX`,
preview: true,
environment: "foobar",
reconnectionPeriod: 10,
fetcher,
eventSourceClass: MockEventSource,
onUpdate: (data) => {
onUpdateEventDefer.resolve(data as any as boolean);
},
});
setTimeout(() => {
if (streams[0].listeners["open"]) {
streams[0].listeners["open"].forEach((cb) => cb(true));
}
}, 100);
setTimeout(() => {
if (streams[0].listeners["update"]) {
const error = {
data: JSON.stringify(true),
};
streams[0].listeners["update"].forEach((cb) => cb(error));
}
}, 200);
const data = await onUpdateEventDefer.promise;
expect(data).toEqual(true);
});
it("notifies events", async () => {

@@ -204,3 +296,3 @@ const fetcher = makeFakeFetch();

it("notifies errors", async () => {
const fetcher = makeFakeFetch({serverErrors: 0});
const fetcher = makeFakeFetch({ serverErrors: 0 });
const onErrorDefer = pDefer<MessageEvent>();

@@ -230,5 +322,5 @@

const data = JSON.stringify({
message: "Not Found"
message: "Not Found",
});
const error = new MessageEvent('FetchError', {data});
const error = new MessageEvent("FetchError", { data });
streams[0].listeners["onerror"].forEach((cb) => cb(error));

@@ -238,3 +330,3 @@ }, 200);

const error = await onErrorDefer.promise;
console.log('error:', error);
console.log("error:", error);
const data = JSON.parse(error.data);

@@ -241,0 +333,0 @@ expect(data.message).toEqual("Not Found");

@@ -0,1 +1,38 @@

import type * as GraphQLWeb from "@0no-co/graphql.web";
import { print } from "@0no-co/graphql.web";
/** A GraphQL `DocumentNode` with attached generics for its result data and variables.
*
* @remarks
* A GraphQL {@link DocumentNode} defines both the variables it accepts on request and the `data`
* shape it delivers on a response in the GraphQL query language.
*
* To bridge the gap to TypeScript, tools may be used to generate TypeScript types that define the shape
* of `data` and `variables` ahead of time. These types are then attached to GraphQL documents using this
* `TypedDocumentNode` type.
*
* Using a `DocumentNode` that is typed like this will cause any `urql` API to type its input `variables`
* and resulting `data` using the types provided.
*
* @privateRemarks
* For compatibility reasons this type has been copied and internalized from:
* https://github.com/dotansimha/graphql-typed-document-node/blob/3711b12/packages/core/src/index.ts#L3-L10
*
* @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information.
*/
export type TypedDocumentNode<
Result = { [key: string]: any },
Variables = { [key: string]: any },
> = GraphQLWeb.DocumentNode & {
/** Type to support `@graphql-typed-document-node/core`
* @internal
*/
__apiType?: (variables: Variables) => Result;
/** Type to support `TypedQueryDocumentNode` from `graphql`
* @internal
*/
__ensureTypesOfVariablesAndResultMatching?: (variables: Variables) => Result;
};
export type UpdateData<QueryResult> = {

@@ -20,3 +57,3 @@ /** The raw GraphQL response */

export type ConnectionStatus = 'connecting' | 'connected' | 'closed';
export type ConnectionStatus = "connecting" | "connected" | "closed";

@@ -35,4 +72,4 @@ export type EventData = {

export type Options<QueryResult, QueryVariables> = {
/** The GraphQL query to subscribe */
query: string;
/** The GraphQL query to subscribe, or a TypedDocumentNode */
query: string | TypedDocumentNode<QueryResult, QueryVariables>;
/** GraphQL variables for the query */

@@ -95,3 +132,3 @@ variables?: QueryVariables;

const MessageEventClass: typeof MessageEvent =
typeof MessageEvent !== 'undefined'
typeof MessageEvent !== "undefined"
? MessageEvent

@@ -156,3 +193,3 @@ : (MessageEventMock as any);

const reconnectionPeriod = Math.min(customReconnectionPeriod || 1000, 20000);
const baseUrl = customBaseUrl || 'https://graphql-listen.datocms.com';
const baseUrl = customBaseUrl || "https://graphql-listen.datocms.com";

@@ -171,6 +208,8 @@ const waitAndReconnect = async () => {

if (onStatusChange) {
onStatusChange('connecting');
onStatusChange("connecting");
}
try {
const realQuery = typeof query === "string" ? query : print(query);
const req = await fetcher(baseUrl, {

@@ -180,8 +219,8 @@ headers: {

Accept: `application/json`,
...(environment ? { 'X-Environment': environment } : {}),
...(includeDrafts || preview ? { 'X-Include-Drafts': 'true' } : {}),
...(excludeInvalid ? { 'X-Exclude-Invalid': 'true' } : {}),
...(environment ? { "X-Environment": environment } : {}),
...(includeDrafts || preview ? { "X-Include-Drafts": "true" } : {}),
...(excludeInvalid ? { "X-Exclude-Invalid": "true" } : {}),
},
method: 'POST',
body: JSON.stringify({ query, variables }),
method: "POST",
body: JSON.stringify({ query: realQuery, variables }),
});

@@ -203,5 +242,5 @@

if (req.headers.get('Content-Type') !== 'application/json') {
if (req.headers.get("Content-Type") !== "application/json") {
throw new InvalidResponseError(
`Invalid content type: ${req.headers.get('Content-Type')}`,
`Invalid content type: ${req.headers.get("Content-Type")}`,
req,

@@ -216,5 +255,5 @@ );

onEvent({
status: 'connecting',
status: "connecting",
channelUrl,
message: 'Received channel URL',
message: "Received channel URL",
response: req,

@@ -225,3 +264,3 @@ });

if (onError) {
const event = new MessageEventClass<Error>('FetchError', { data: e });
const event = new MessageEventClass<Error>("FetchError", { data: e });
onError(event);

@@ -235,3 +274,3 @@ }

if (onStatusChange) {
onStatusChange('closed');
onStatusChange("closed");
}

@@ -253,5 +292,5 @@

eventSource.addEventListener('open', () => {
eventSource.addEventListener("open", () => {
if (onStatusChange) {
onStatusChange('connected');
onStatusChange("connected");
}

@@ -266,3 +305,3 @@ resolve(unsubscribe);

if (onStatusChange) {
onStatusChange('closed');
onStatusChange("closed");
}

@@ -276,3 +315,3 @@

eventSource.addEventListener('update', (event) => {
eventSource.addEventListener("update", (event) => {
const updateData = JSON.parse(

@@ -284,3 +323,3 @@ (event as any).data,

eventSource.addEventListener('channelError', (event) => {
eventSource.addEventListener("channelError", (event) => {
const errorData = JSON.parse((event as any).data) as ChannelErrorData;

@@ -299,3 +338,3 @@

eventSource.addEventListener('onerror', (event) => {
eventSource.addEventListener("onerror", (event) => {
const messageEvent = event as MessageEvent;

@@ -302,0 +341,0 @@ if (onError) {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc