mirror of
https://github.com/wassname/talk.git
synced 2026-09-10 12:43:11 +08:00
feat: added support for --only flag
Merge pull request #1731 from coralproject/next-watcher-flags Watcher --only Use JSDocs comments (#1727) Merge branch 'next' into prevent-compile-loop-relay Merge pull request #1726 from coralproject/prevent-compile-loop-relay [next] Adapt relay watch config [next] Remove nodemon (#1725) * Remove old nodemon configs * Remove nodemon [next] Jest implementation for React Components (#1733) * Make jest testing work with custom path and css modules * Add first test * feat: added unit tests to ci * fix: updated package-lock.json * Update cssTransform.js * Update cssTransform.js * Fix test in ci Adapt files.exclude (#1736) Permalink ui Adding Copy to clipboard functionality WIP clean request wip progress progress work in progress wip ui functionality Translations :/ wip Merge branch 'permalink' of github.com:coralproject/talk into permalink * 'permalink' of github.com:coralproject/talk: (42 commits) [next] Support server side jest testing (#1747) Update snapshots Add comments Remove precss Move react-responsive to dev deps Remove comment Mobile first approach Support standard css variables, dynamically set spacing-unit Add docs Fully implement Flex and MatchMedia Responsive Components <3 fix: linting fix: adjusted pageInfo Remove obsoloe snapshot Move jsdom to dev deps Mark comments as always returning a value Add comment Fix unit tests Translate, concept for translation and id strings Add aria props ... Adding Attachment and Popover Component merge conflicts progress Any Working Support for refs Ready Merge branch 'permalink' of github.com:coralproject/talk into permalink * 'permalink' of github.com:coralproject/talk: (101 commits) Ready Support for refs Working Any progress merge conflicts Make timeagoFormatter optional More colors Colors Short circuit endless respawn fix: new mongo parser Remove jest from watcher config, as it doesnt run well inside Add jest set Apply suggestions Move react-timeago to dev Upgrade docz Cleanup docz scripts Support watcher sets [next] Support server side jest testing (#1747) Make filter only a pure function ...
This commit is contained in:
@@ -49,14 +49,14 @@ const config = convict({
|
||||
mongodb: {
|
||||
doc: "The MongoDB database to connect to.",
|
||||
format: "mongo-uri",
|
||||
default: "mongodb://localhost/talk",
|
||||
default: "mongodb://127.0.0.1:27017/talk",
|
||||
env: "MONGODB",
|
||||
arg: "mongodb",
|
||||
},
|
||||
redis: {
|
||||
doc: "The Redis database to connect to.",
|
||||
format: "redis-uri",
|
||||
default: "redis://localhost:6379",
|
||||
default: "redis://127.0.0.1:6379",
|
||||
env: "REDIS",
|
||||
arg: "redis",
|
||||
},
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import { getGraphQLProjectConfig } from "graphql-config";
|
||||
import { addResolveFunctionsToSchema, IResolvers } from "graphql-tools";
|
||||
|
||||
export default function loadSchema(projectName: string, resolvers: IResolvers) {
|
||||
// Load the configuration from the provided `.graphqlconfig` file.
|
||||
const config = getGraphQLProjectConfig(__dirname, projectName);
|
||||
|
||||
// Get the GraphQLSchema from the configuration.
|
||||
const schema = config.getSchema();
|
||||
|
||||
// Attach the resolvers to the schema.
|
||||
addResolveFunctionsToSchema({ schema, resolvers });
|
||||
|
||||
return schema;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import loadSchema from "talk-server/graph/common/schema";
|
||||
import { loadSchema } from "talk-common/graphql";
|
||||
import resolvers from "talk-server/graph/management/resolvers";
|
||||
|
||||
export default function getManagementSchema() {
|
||||
|
||||
@@ -2,6 +2,8 @@ import Context from "talk-server/graph/tenant/context";
|
||||
import { Comment, ConnectionInput } from "talk-server/models/comment";
|
||||
|
||||
export default {
|
||||
createdAt: async (comment: Comment, _: any, ctx: Context) =>
|
||||
comment.created_at,
|
||||
author: async (comment: Comment, _: any, ctx: Context) =>
|
||||
ctx.loaders.Users.user.load(comment.author_id),
|
||||
replies: async (comment: Comment, input: ConnectionInput, ctx: Context) =>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import loadSchema from "talk-server/graph/common/schema";
|
||||
import { loadSchema } from "talk-common/graphql";
|
||||
import resolvers from "talk-server/graph/tenant/resolvers";
|
||||
|
||||
export default function getTenantSchema() {
|
||||
|
||||
@@ -202,6 +202,11 @@ type Comment {
|
||||
"""
|
||||
body: String
|
||||
|
||||
"""
|
||||
createdAt is the date in which the comment was created.
|
||||
"""
|
||||
createdAt: Time
|
||||
|
||||
"""
|
||||
author is the User that authored the Comment.
|
||||
"""
|
||||
@@ -232,7 +237,22 @@ type PageInfo {
|
||||
"""
|
||||
Indicates that there are more nodes after this subset.
|
||||
"""
|
||||
hasNextPage: Boolean!
|
||||
hasNextPage: Boolean
|
||||
|
||||
"""
|
||||
Included for legacy Relay reasons. Always set to false.
|
||||
"""
|
||||
hasPreviousPage: Boolean
|
||||
|
||||
"""
|
||||
Included for legacy Relay reasons. Always set to null.
|
||||
"""
|
||||
startCursor: Cursor
|
||||
|
||||
"""
|
||||
Specifies the last node's cursor for forwards pagination.
|
||||
"""
|
||||
endCursor: Cursor
|
||||
}
|
||||
|
||||
"""
|
||||
@@ -302,7 +322,7 @@ type Asset {
|
||||
first: Int = 10
|
||||
orderBy: COMMENT_SORT = CREATED_AT_DESC
|
||||
after: Cursor
|
||||
): CommentsConnection
|
||||
): CommentsConnection!
|
||||
|
||||
"""
|
||||
author is the authors listed in the meta tags for the Asset.
|
||||
|
||||
@@ -2,7 +2,13 @@ import { merge } from "lodash";
|
||||
import { Db } from "mongodb";
|
||||
import { Omit, Sub } from "talk-common/types";
|
||||
import { ActionCounts } from "talk-server/models/actions";
|
||||
import { Connection, Cursor } from "talk-server/models/connection";
|
||||
import {
|
||||
Connection,
|
||||
Cursor,
|
||||
getPageInfo,
|
||||
nodesToEdges,
|
||||
NodeToCursorTransformer,
|
||||
} from "talk-server/models/connection";
|
||||
import Query from "talk-server/models/query";
|
||||
import { TenantResource } from "talk-server/models/tenant";
|
||||
import uuid from "uuid";
|
||||
@@ -134,31 +140,18 @@ export interface ConnectionInput {
|
||||
after?: Cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* nodesToEdge converts a set of nodes and configuration options into a set of
|
||||
* edges.
|
||||
*
|
||||
* @param input connection configuration
|
||||
* @param nodes nodes returned from the query
|
||||
*/
|
||||
function nodesToEdge(input: ConnectionInput, nodes: Comment[]) {
|
||||
let getCursor: (comment: Comment, index: number) => Cursor;
|
||||
function cursorGetterFactory(
|
||||
input: ConnectionInput
|
||||
): NodeToCursorTransformer<Comment> {
|
||||
switch (input.orderBy) {
|
||||
case CommentSort.CREATED_AT_DESC:
|
||||
case CommentSort.CREATED_AT_ASC:
|
||||
getCursor = comment => comment.created_at;
|
||||
break;
|
||||
return comment => comment.created_at;
|
||||
case CommentSort.REPLIES_DESC:
|
||||
case CommentSort.RESPECT_DESC:
|
||||
getCursor = (_, index) =>
|
||||
return (_, index) =>
|
||||
(input.after ? (input.after as number) : 0) + index + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return nodes.map((comment, index) => ({
|
||||
node: comment,
|
||||
cursor: getCursor(comment, index),
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,8 +216,43 @@ export async function retrieveAssetConnection(
|
||||
async function retrieveConnection(
|
||||
input: ConnectionInput,
|
||||
query: Query<Comment>
|
||||
) {
|
||||
): Promise<Readonly<Connection<Readonly<Comment>>>> {
|
||||
// Apply some sorting options.
|
||||
applyInputToQuery(input, query);
|
||||
|
||||
// We load one more than the limit so we can determine if there is
|
||||
// another page of entries. This gets trimmed off below after we've checked to
|
||||
// see if this constitutes another page of edges.
|
||||
query.first(input.first + 1);
|
||||
|
||||
// Get the cursor.
|
||||
const cursor = await query.exec();
|
||||
|
||||
// Get the comments from the cursor.
|
||||
const nodes = await cursor.toArray();
|
||||
|
||||
// Convert the nodes to edges (which will include the extra edge we don't need
|
||||
// if there is more results).
|
||||
const edges = nodesToEdges(nodes, cursorGetterFactory(input));
|
||||
|
||||
// Get the pageInfo for the connection. We will use this to also determine if
|
||||
// we need to trim off the extra edge that we requested by comparing its
|
||||
// hasNextPage parameter.
|
||||
const pageInfo = getPageInfo(input, edges);
|
||||
if (pageInfo.hasNextPage) {
|
||||
// Because this means that we got one more than expected, we should trim off
|
||||
// the extra edge that was retrieved.
|
||||
edges.splice(input.first, 1);
|
||||
}
|
||||
|
||||
// Return the connection.
|
||||
return {
|
||||
edges,
|
||||
pageInfo,
|
||||
};
|
||||
}
|
||||
|
||||
function applyInputToQuery(input: ConnectionInput, query: Query<Comment>) {
|
||||
switch (input.orderBy) {
|
||||
case CommentSort.CREATED_AT_DESC:
|
||||
query.orderBy({ created_at: -1 });
|
||||
@@ -251,37 +279,4 @@ async function retrieveConnection(
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// We load one more than the limit so we can determine if there is
|
||||
// another page of entries.
|
||||
query.first(input.first + 1);
|
||||
|
||||
// Get the cursor.
|
||||
const cursor = await query.exec();
|
||||
|
||||
// Get the comments from the cursor.
|
||||
const nodes = await cursor.toArray();
|
||||
|
||||
// The hasNextPage is always handled the same (ask for one more than we need,
|
||||
// if there is one more, than there is more).
|
||||
let hasNextPage = false;
|
||||
if (input.first >= 0 && nodes.length > input.first) {
|
||||
// There was one more than we expected! Set hasNextPage = true and remove
|
||||
// the last item from the array that we requested.
|
||||
hasNextPage = true;
|
||||
nodes.splice(input.first, 1);
|
||||
}
|
||||
|
||||
// Convert the nodes to edges.
|
||||
const edges = nodesToEdge(input, nodes);
|
||||
|
||||
// Return the connection.
|
||||
const connection: Readonly<Connection<Readonly<Comment>>> = {
|
||||
edges,
|
||||
pageInfo: {
|
||||
hasNextPage,
|
||||
},
|
||||
};
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { getPageInfo } from "./connection";
|
||||
|
||||
it("handles when there is none requested", () => {
|
||||
const pageInfo = getPageInfo({ first: 0 }, []);
|
||||
|
||||
expect(pageInfo).toEqual({
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
startCursor: null,
|
||||
endCursor: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("handles when there is no edges", () => {
|
||||
const pageInfo = getPageInfo({ first: 10 }, []);
|
||||
|
||||
expect(pageInfo).toEqual({
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
startCursor: null,
|
||||
endCursor: null,
|
||||
});
|
||||
});
|
||||
|
||||
it("handles when there is more edges than requested", () => {
|
||||
const pageInfo = getPageInfo({ first: 1 }, [
|
||||
{
|
||||
node: null,
|
||||
cursor: 1,
|
||||
},
|
||||
{
|
||||
node: null,
|
||||
cursor: 2,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(pageInfo).toEqual({
|
||||
hasNextPage: true,
|
||||
hasPreviousPage: false,
|
||||
startCursor: null,
|
||||
endCursor: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it("handles when there is exactly as many edges as requested", () => {
|
||||
const pageInfo = getPageInfo({ first: 1 }, [
|
||||
{
|
||||
node: null,
|
||||
cursor: 1,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(pageInfo).toEqual({
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
startCursor: null,
|
||||
endCursor: 1,
|
||||
});
|
||||
});
|
||||
@@ -6,10 +6,63 @@ export interface Edge<T> {
|
||||
}
|
||||
|
||||
export interface PageInfo {
|
||||
hasNextPage: boolean;
|
||||
hasNextPage?: boolean;
|
||||
hasPreviousPage?: boolean;
|
||||
startCursor?: Cursor;
|
||||
endCursor?: Cursor;
|
||||
}
|
||||
|
||||
export interface Connection<T> {
|
||||
edges: Array<Edge<T>>;
|
||||
pageInfo: PageInfo;
|
||||
}
|
||||
|
||||
export interface PaginationArgs {
|
||||
first: number;
|
||||
}
|
||||
|
||||
export function getPageInfo<T>(args: PaginationArgs, edges: Array<Edge<T>>) {
|
||||
const pageInfo: PageInfo = {
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
startCursor: null,
|
||||
endCursor: null,
|
||||
};
|
||||
|
||||
if (edges.length === 0) {
|
||||
// If there are no edges, then there's nothing to paginate!
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
// The hasNextPage is always handled the same (ask for one more than we need,
|
||||
// if there is one more, than there is more).
|
||||
if (args.first >= 0 && edges.length > args.first) {
|
||||
// There was one more than we expected! Set hasNextPage = true.
|
||||
pageInfo.hasNextPage = true;
|
||||
}
|
||||
|
||||
if (pageInfo.hasNextPage && edges.length > 1) {
|
||||
// There was more than one expected, and there is two entries in the edges
|
||||
// array. We should grab the second last one because the last one will have
|
||||
// to be trimmed off after.
|
||||
pageInfo.endCursor = edges[edges.length - 2].cursor;
|
||||
} else {
|
||||
// There was not more than expected, so we should just grab the last edge to
|
||||
// get the endCursor.
|
||||
pageInfo.endCursor = edges[edges.length - 1].cursor;
|
||||
}
|
||||
|
||||
return pageInfo;
|
||||
}
|
||||
|
||||
export type NodeToCursorTransformer<T> = (node: T, index: number) => Cursor;
|
||||
|
||||
export function nodesToEdges<T>(
|
||||
nodes: T[],
|
||||
transformer: NodeToCursorTransformer<T>
|
||||
): Array<Edge<T>> {
|
||||
return nodes.map((node, index) => ({
|
||||
node,
|
||||
cursor: transformer(node, index),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -8,7 +8,10 @@ import { Config } from "talk-server/config";
|
||||
*/
|
||||
export async function createMongoDB(config: Config): Promise<Db> {
|
||||
// Connect and create a client for MongoDB.
|
||||
const client = await MongoClient.connect(config.get("mongodb"));
|
||||
const client = await MongoClient.connect(
|
||||
config.get("mongodb"),
|
||||
{ useNewUrlParser: true }
|
||||
);
|
||||
|
||||
// Return the database handle, which defaults to the database name provided
|
||||
// in the config connection string.
|
||||
|
||||
Reference in New Issue
Block a user