Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

relay-mongoose

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

relay-mongoose - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

.eslintignore

65

dist/index.js
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {

@@ -63,18 +50,28 @@ __assign = Object.assign || function(t) {

Object.defineProperty(exports, "__esModule", { value: true });
exports.enhancedModel = void 0;
var mongoose_1 = require("mongoose");
exports.EnhancedModel = exports.fromRelayId = void 0;
var mongoose = require("mongoose");
exports.enhancedModel = function (name, schema, collection, skipInit) {
var _a;
var Base = mongoose.models[name] || mongoose_1.model(name, schema, collection, skipInit);
// eslint-disable-next-line
// @ts-ignore
return _a = /** @class */ (function (_super) {
__extends(class_1, _super);
function class_1() {
return _super !== null && _super.apply(this, arguments) || this;
}
return class_1;
}(Base)),
_a.findConnections = function (conditions, paginationArgs, projection) { return __awaiter(void 0, void 0, void 0, function () {
exports.fromRelayId = function (id) {
var original = Buffer.from(id, 'base64').toString('utf-8');
var _a = original.split('.'), modelName = _a[0], objectId = _a[1];
if (objectId === undefined) {
throw new Error('Invalid id string. Should be a base64 encoded string containing model name and object ID concatenated by `.`');
}
return { modelName: modelName, objectId: objectId };
};
var EnhancedModel = /** @class */ (function () {
function EnhancedModel() {
}
Object.defineProperty(EnhancedModel.prototype, "relayId", {
get: function () {
// Ignoring TS errors about `this` access as this is intended paradigm as defined by mongoose documentation:
// https://mongoosejs.com/docs/guide.html#virtuals
// eslint-disable-next-line
// @ts-ignore
return Buffer.from(this.constructor.modelName + "." + this._id.toString()).toString('base64');
},
enumerable: false,
configurable: true
});
EnhancedModel.findConnections = function (conditions, paginationArgs, projection) {
return __awaiter(this, void 0, void 0, function () {
var before, after, first, last, idQuery, query, count, dataQuery, hasNextPage, hasPreviousPage, data, pageInfo;

@@ -87,6 +84,6 @@ return __generator(this, function (_a) {

query = __assign(__assign({}, conditions), (Object.keys(idQuery).length === 0 ? {} : { _id: idQuery }));
return [4 /*yield*/, Base.find(query).countDocuments()];
return [4 /*yield*/, this.find(query).countDocuments()];
case 1:
count = _a.sent();
dataQuery = Base.find(query, projection);
dataQuery = this.find(query, projection);
hasNextPage = false;

@@ -124,4 +121,6 @@ hasPreviousPage = false;

});
}); },
_a;
};
});
};
return EnhancedModel;
}());
exports.EnhancedModel = EnhancedModel;
{
"name": "relay-mongoose",
"version": "0.1.0",
"version": "0.2.0",
"repository": "https://github.com/wadamek65/relay-mongoose.git",

@@ -5,0 +5,0 @@ "author": "wadamek65 <wadamek65@gmail.com>",

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

import { Document, FilterQuery, model, Schema } from 'mongoose';
import { Document, FilterQuery } from 'mongoose';
import * as mongoose from 'mongoose';

@@ -28,4 +28,7 @@

export interface EnhancedModel<T extends Document, QueryHelpers = {}> extends mongoose.Model<T, QueryHelpers> {
prototype: mongoose.Model<T, QueryHelpers>;
export interface EnhancedDocument extends Document {
relayId: string;
}
export interface EnhancedModel<T extends EnhancedDocument, QueryHelpers = {}> extends mongoose.Model<T, QueryHelpers> {
findConnections(

@@ -38,66 +41,82 @@ conditions: FilterQuery<T>,

export const enhancedModel = <T extends Document, QueryHelpers = {}>(name: string, schema?: Schema, collection?: string,
skipInit?: boolean
): EnhancedModel<T, QueryHelpers> => {
const Base: mongoose.Model<T> = mongoose.models[name] || model(name, schema, collection, skipInit);
export const fromRelayId = (id: string): { modelName: string; objectId: string } => {
const original = Buffer.from(id, 'base64').toString('utf-8');
const [modelName, objectId] = original.split('.');
if (objectId === undefined) {
throw new Error(
'Invalid id string. Should be a base64 encoded string containing model name and object ID concatenated by `.`'
);
}
// eslint-disable-next-line
// @ts-ignore
return class extends Base {
static findConnections = async (
conditions: FilterQuery<T>,
paginationArgs: PaginationArgs,
projection?: any | null
): Promise<ConnectionDocuments<T>> => {
const { before, after, first, last } = paginationArgs;
const idQuery = {
...(before !== undefined ? { $lt: mongoose.Types.ObjectId(before) } : {}),
...(after !== undefined ? { $gt: mongoose.Types.ObjectId(after) } : {})
};
return { modelName, objectId };
};
const query = {
...conditions,
...(Object.keys(idQuery).length === 0 ? {} : { _id: idQuery })
};
export class EnhancedModel<T extends EnhancedDocument, QueryHelpers = {}> {
get relayId() {
// Ignoring TS errors about `this` access as this is intended paradigm as defined by mongoose documentation:
// https://mongoosejs.com/docs/guide.html#virtuals
// eslint-disable-next-line
// @ts-ignore
return Buffer.from(`${this.constructor.modelName}.${this._id.toString()}`).toString('base64');
}
const count = await Base.find(query).countDocuments();
const dataQuery = Base.find(query, projection);
static async findConnections<T extends Document>(
conditions: FilterQuery<T>,
paginationArgs: PaginationArgs,
projection?: any | null
): Promise<ConnectionDocuments<T>> {
const { before, after, first, last } = paginationArgs;
const idQuery = {
...(before !== undefined ? { $lt: mongoose.Types.ObjectId(before) } : {}),
...(after !== undefined ? { $gt: mongoose.Types.ObjectId(after) } : {})
};
let hasNextPage = false;
let hasPreviousPage = false;
const query = {
...conditions,
...(Object.keys(idQuery).length === 0 ? {} : { _id: idQuery })
};
if (first !== undefined && first < count) {
dataQuery.limit(first);
hasNextPage = true;
}
// eslint-disable-next-line
// @ts-ignore
const count = await this.find(query).countDocuments();
// eslint-disable-next-line
// @ts-ignore
const dataQuery = this.find(query, projection);
if (last !== undefined && last < count) {
dataQuery.skip(count - last);
hasPreviousPage = true;
if (hasNextPage) {
hasNextPage = false;
}
let hasNextPage = false;
let hasPreviousPage = false;
if (first !== undefined && first < count) {
dataQuery.limit(first);
hasNextPage = true;
}
if (last !== undefined && last < count) {
dataQuery.skip(count - last);
hasPreviousPage = true;
if (hasNextPage) {
hasNextPage = false;
}
}
const data = await dataQuery;
const pageInfo = {
hasNextPage,
hasPreviousPage,
...(data.length > 0
? {
startCursor: data[0].id,
endCursor: data[data.length - 1].id
}
: {})
};
const data = await dataQuery;
const pageInfo = {
hasNextPage,
hasPreviousPage,
...(data.length > 0
? {
startCursor: data[0].id,
endCursor: data[data.length - 1].id
}
: {})
};
return {
edges: data.map(edge => ({
cursor: edge.id,
node: edge
})),
pageInfo
};
return {
edges: data.map(edge => ({
cursor: edge.id,
node: edge
})),
pageInfo
};
};
};
}
}

@@ -5,7 +5,7 @@ import * as chai from 'chai';

import { EnhancedModel, enhancedModel } from '../src';
import { EnhancedDocument, EnhancedModel, fromRelayId } from '../src';
const expect = chai.expect;
export interface TestSchemaInterface extends mongoose.Document {
export interface TestSchemaInterface extends EnhancedDocument {
field: string;

@@ -19,4 +19,3 @@ }

describe('relay-mongoose tests', () => {
let model;
let EnhancedTestModel: EnhancedModel<TestSchemaInterface>;
let TestModel: EnhancedModel<TestSchemaInterface>;
let mongo;

@@ -31,5 +30,6 @@ let docs;

await mongoose.connect(await mongo.getUri());
EnhancedTestModel = enhancedModel<TestSchemaInterface>('test', testSchema);
docs = [...Array(15)].map(() => new EnhancedTestModel({ field: value }));
await EnhancedTestModel.insertMany(docs);
testSchema.loadClass(EnhancedModel);
TestModel = mongoose.model('test', testSchema) as any;
docs = [...Array(15)].map(() => new TestModel({ field: value }));
await TestModel.insertMany(docs);
firstId = docs[0].id;

@@ -47,4 +47,4 @@ lastId = docs[docs.length - 1].id;

const value = 'test';
await new EnhancedTestModel({ field: value }).save();
const result = await EnhancedTestModel.findOne({ field: value });
await new TestModel({ field: value }).save();
const result = await TestModel.findOne({ field: value });
expect(result.field).to.equal(value);

@@ -54,3 +54,3 @@ });

it('should return everything', async () => {
const result = await EnhancedTestModel.findConnections({ field: value }, {});
const result = await TestModel.findConnections({ field: value }, {});
expect(result.edges.length).to.equal(docs.length);

@@ -64,2 +64,29 @@ expect(result.pageInfo.startCursor).to.equal(result.edges[0].cursor).to.equal(firstId);

});
it('should return a custom relay Id', async () => {
const result = await TestModel.findOne({ field: value }, {});
expect(result.relayId).not.to.equal(result.id);
expect(result.relayId)
.to.equal(Buffer.from(`${TestModel.modelName}.${result.id}`).toString('base64'))
.to.equal(Buffer.from(`test.${result.id}`).toString('base64'));
});
it('should decode relayId properly', async () => {
const fakeModelName = 'fakeModel';
const fakeObjectId = 'fakeObjectId';
const { modelName, objectId } = fromRelayId(Buffer.from(`${fakeModelName}.${fakeObjectId}`).toString('base64'));
expect(modelName).to.equal(fakeModelName);
expect(objectId).to.equal(fakeObjectId);
});
it('should throw error when decoding invalid relayId', async () => {
const fakeModelName = 'fakeModel';
try {
fromRelayId(Buffer.from(fakeModelName).toString('base64'));
} catch (e) {
expect(e.toString()).to.equal(
'Error: Invalid id string. Should be a base64 encoded string containing model name and object ID concatenated by `.`'
);
}
});
});

@@ -73,3 +100,3 @@

};
const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(amount);

@@ -89,3 +116,3 @@ expect(result.pageInfo.startCursor).to.equal(result.edges[0].cursor).to.equal(firstId);

};
const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(amount);

@@ -107,3 +134,3 @@ expect(result.pageInfo.startCursor)

const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(beforeIndex - afterIndex - 1);

@@ -122,3 +149,3 @@ expect(result.pageInfo.endCursor).to.equal(docs[beforeIndex - 1].id);

const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(docs.length - amount);

@@ -134,3 +161,3 @@ expect(result.pageInfo.endCursor).to.equal(lastId);

const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(amount);

@@ -146,3 +173,3 @@ expect(result.pageInfo.endCursor).to.equal(docs[amount + amount - 1].id);

const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(amount);

@@ -164,3 +191,3 @@ expect(result.pageInfo.endCursor).to.equal(lastId);

const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(amount);

@@ -178,3 +205,3 @@ expect(result.pageInfo.startCursor).to.equal(docs[0].id);

const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(amount);

@@ -192,3 +219,3 @@ expect(result.pageInfo.endCursor).to.equal(docs[amount - 1].id);

const result = await EnhancedTestModel.findConnections({ field: value }, args);
const result = await TestModel.findConnections({ field: value }, args);
expect(result.edges.length).to.equal(amount);

@@ -195,0 +222,0 @@ expect(result.pageInfo.endCursor).to.equal(docs[beforeIndex - 1].id);

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