Added designers
This commit is contained in:
Generated
+15
@@ -2684,6 +2684,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"graphql-scalars": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/graphql-scalars/-/graphql-scalars-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-31bBDnHdBapb2wknLCjNzTSjKfVEtm+0HxI7DKM7jQ4Uipk1o1aMUCYCkYunmRDdgQaI03u1MD5KutLf7yHnvw==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "~2.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"graphql-subscriptions": {
|
"graphql-subscriptions": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"datasource-sql": "^1.4.0",
|
"datasource-sql": "^1.4.0",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"graphql": "^15.5.0",
|
"graphql": "^15.5.0",
|
||||||
|
"graphql-scalars": "^1.9.0",
|
||||||
"knex-stringcase": "^1.4.5",
|
"knex-stringcase": "^1.4.5",
|
||||||
"nodemon": "^2.0.7",
|
"nodemon": "^2.0.7",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
|
|||||||
+61
-34
@@ -20,44 +20,63 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
order(id: 588274) {
|
product(id: 42280) {
|
||||||
id
|
id
|
||||||
|
inserted
|
||||||
|
updated
|
||||||
|
visible
|
||||||
|
browsable
|
||||||
|
designerId
|
||||||
|
designer {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
path
|
||||||
|
}
|
||||||
|
printProducts {
|
||||||
|
group
|
||||||
|
id
|
||||||
|
updated
|
||||||
|
}
|
||||||
|
blacklisting {
|
||||||
|
group
|
||||||
|
id
|
||||||
|
marketId
|
||||||
|
updated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
orders(
|
||||||
|
filter: { limit: 1, dates: { from: "2021-03-01", to: "2021-04-30" } }
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
marketObject {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
vat
|
||||||
|
currency
|
||||||
|
priceAdjustment
|
||||||
|
}
|
||||||
rows {
|
rows {
|
||||||
id
|
id
|
||||||
}
|
order {
|
||||||
billingInformation {
|
|
||||||
email
|
|
||||||
phone
|
|
||||||
address {
|
|
||||||
id
|
id
|
||||||
firstname
|
|
||||||
lastname
|
|
||||||
recipientName
|
|
||||||
companyname
|
|
||||||
address1
|
|
||||||
address2
|
|
||||||
countryCode
|
|
||||||
city
|
|
||||||
zipcode
|
|
||||||
stateCountyOrRegion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
deliveryInformation {
|
|
||||||
email
|
|
||||||
phone
|
|
||||||
address {
|
|
||||||
id
|
|
||||||
firstname
|
|
||||||
lastname
|
|
||||||
recipientName
|
|
||||||
companyname
|
|
||||||
address1
|
|
||||||
address2
|
|
||||||
countryCode
|
|
||||||
city
|
|
||||||
zipcode
|
|
||||||
stateCountyOrRegion
|
|
||||||
}
|
}
|
||||||
|
inserted
|
||||||
|
orderId
|
||||||
|
productId
|
||||||
|
productGroup
|
||||||
|
artNo
|
||||||
|
path
|
||||||
|
name
|
||||||
|
price
|
||||||
|
designerId
|
||||||
|
commissionAmount
|
||||||
|
status
|
||||||
|
pwintyImageId
|
||||||
|
frameColor
|
||||||
|
pwintySku
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +96,7 @@
|
|||||||
order {
|
order {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
insertedDate
|
inserted
|
||||||
orderId
|
orderId
|
||||||
productId
|
productId
|
||||||
productGroup
|
productGroup
|
||||||
@@ -94,3 +113,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
designers(limit: 10) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,10 @@ export class BaseSQLDataSource extends SQLDataSource {
|
|||||||
this.cache = config.cache || new InMemoryLRUCache();
|
this.cache = config.cache || new InMemoryLRUCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSQLDate(date: Date): string {
|
||||||
|
return date.toISOString().split('T')[0];
|
||||||
|
}
|
||||||
|
|
||||||
async cacheQuery(ttl = 5, query) {
|
async cacheQuery(ttl = 5, query) {
|
||||||
const cacheKey = crypto
|
const cacheKey = crypto
|
||||||
.createHash('sha1')
|
.createHash('sha1')
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { BaseSQLDataSource } from './BaseSQLDataSource';
|
||||||
|
import { Designer } from './designer-types';
|
||||||
|
import { Maybe } from './types';
|
||||||
|
|
||||||
|
const MINUTE = 60;
|
||||||
|
export class DesignerAPI extends BaseSQLDataSource {
|
||||||
|
constructor(config) {
|
||||||
|
super(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDesignerById(id: number): Promise<Designer> {
|
||||||
|
return await this.knex
|
||||||
|
.select('*')
|
||||||
|
.from('designers')
|
||||||
|
.where('designerid', id)
|
||||||
|
.first()
|
||||||
|
.cache(MINUTE)
|
||||||
|
.then((row) => {
|
||||||
|
return {
|
||||||
|
...row,
|
||||||
|
id: row.designerid,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDesigners(limit: Maybe<number>): Promise<Array<Designer>> {
|
||||||
|
limit = limit ?? 100;
|
||||||
|
return await this.knex
|
||||||
|
.select('*')
|
||||||
|
.from('designers')
|
||||||
|
.limit(limit)
|
||||||
|
.cache(MINUTE)
|
||||||
|
.then((rows) => {
|
||||||
|
return rows.map((row) => {
|
||||||
|
return {
|
||||||
|
...row,
|
||||||
|
id: row.designerid,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export interface Designer {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { SQLDataSource } from 'datasource-sql';
|
||||||
|
|
||||||
import { BaseSQLDataSource } from './BaseSQLDataSource';
|
import { BaseSQLDataSource } from './BaseSQLDataSource';
|
||||||
import { camelcase } from 'stringcase';
|
import { camelcase } from 'stringcase';
|
||||||
import {
|
import {
|
||||||
@@ -7,11 +9,10 @@ import {
|
|||||||
Order,
|
Order,
|
||||||
OrderRow,
|
OrderRow,
|
||||||
} from './order-types';
|
} from './order-types';
|
||||||
import { Maybe } from './types';
|
import { GeneralInput, Maybe } from './types';
|
||||||
|
|
||||||
const MINUTE = 60;
|
const MINUTE = 60;
|
||||||
export class OrderAPI extends BaseSQLDataSource {
|
export class OrderAPI extends BaseSQLDataSource {
|
||||||
cache: any;
|
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
@@ -65,19 +66,31 @@ export class OrderAPI extends BaseSQLDataSource {
|
|||||||
|
|
||||||
getDeliveryInformation(row): ContactInformation {
|
getDeliveryInformation(row): ContactInformation {
|
||||||
return {
|
return {
|
||||||
email: 'niklas.fondberg@photowall.se',
|
email: 'niklas.fondberg@photowall.se', // TODO: fix hardcoded
|
||||||
phone: '+46761386397',
|
phone: '+46761386397',
|
||||||
addressId: row.deliveryAddressId,
|
addressId: row.deliveryAddressId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrders(): Promise<Array<Order>> {
|
async getOrders(input: Maybe<GeneralInput>): Promise<Array<Order>> {
|
||||||
return await this.knex
|
let query = this.knex.select('*').from('orders');
|
||||||
.select('*')
|
// .where('inserted', '>=', '2021-03-01T00:00:00Z')
|
||||||
.from('orders')
|
|
||||||
.where('inserted', '>=', '2021-03-01T00:00:00Z')
|
if (input?.dates?.from) {
|
||||||
.cache(MINUTE)
|
query = query.where('inserted', '>=', input.dates.from);
|
||||||
.then((rows) =>
|
}
|
||||||
|
|
||||||
|
if (input?.dates?.to) {
|
||||||
|
query = query.where('inserted', '<=', input.dates.to);
|
||||||
|
}
|
||||||
|
query = query.orderBy('inserted', 'ASC');
|
||||||
|
|
||||||
|
if (input?.limit) {
|
||||||
|
query = query.limit(input?.limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(query.toString());
|
||||||
|
return await query.cache(MINUTE).then((rows) =>
|
||||||
rows.map((row) => {
|
rows.map((row) => {
|
||||||
row.billingInformation = this.getBillingInformation(row);
|
row.billingInformation = this.getBillingInformation(row);
|
||||||
row.deliveryInformation = this.getDeliveryInformation(row);
|
row.deliveryInformation = this.getDeliveryInformation(row);
|
||||||
@@ -86,7 +99,7 @@ export class OrderAPI extends BaseSQLDataSource {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrder(id: number): Promise<Order> {
|
async getOrderById(id: number): Promise<Order> {
|
||||||
return await this.knex
|
return await this.knex
|
||||||
.select('*')
|
.select('*')
|
||||||
.from('orders')
|
.from('orders')
|
||||||
@@ -100,34 +113,35 @@ export class OrderAPI extends BaseSQLDataSource {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getOrderRows(orderId: number): Promise<Array<OrderRow>> {
|
async getOrderRowFieldMapping(): Promise<any> {
|
||||||
|
// const fields = await this.knex.select('*').from('order-row_fields');
|
||||||
const fieldsRes = await this.cacheQuery(
|
const fieldsRes = await this.cacheQuery(
|
||||||
120,
|
60,
|
||||||
this.knex
|
this.knex
|
||||||
.raw('SELECT * from "order-row_fields"')
|
.raw('SELECT * from "order-row_fields"')
|
||||||
.then((data) => data.rows),
|
.then((data) => data.rows),
|
||||||
);
|
);
|
||||||
|
|
||||||
const fields = fieldsRes.reduce((obj, item) => {
|
return fieldsRes.reduce((obj, item) => {
|
||||||
obj[item.fieldid] = item.name;
|
obj[item.fieldid] = item.name;
|
||||||
return obj;
|
return obj;
|
||||||
}, {});
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
const rows = await this.knex
|
/**
|
||||||
.raw('SELECT * FROM "order-rows" WHERE orderid = ?', orderId)
|
* Gets the row details
|
||||||
.then((data) => data.rows);
|
*/
|
||||||
|
async getOrderRowDetailsForRowId(rowId: number): Promise<any> {
|
||||||
let orderRows = [];
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
|
||||||
const rowId = rows[i].rowid;
|
|
||||||
const details = await this.knex
|
const details = await this.knex
|
||||||
.raw('SELECT * FROM "order-rows_details" WHERE rowid = ?', rowId)
|
.raw('SELECT * FROM "order-rows_details" WHERE rowid = ?', rowId)
|
||||||
.then((data) => data.rows);
|
.then((data) => data.rows);
|
||||||
|
|
||||||
// Skip empty order rows
|
// Skip empty order rows
|
||||||
if (!details.length) {
|
if (!details.length) {
|
||||||
continue;
|
return null;
|
||||||
}
|
}
|
||||||
|
const fields = await this.getOrderRowFieldMapping();
|
||||||
|
|
||||||
const orderRow = details.reduce((obj, item) => {
|
const orderRow = details.reduce((obj, item) => {
|
||||||
obj[camelcase(fields[item.fieldid])] = item.value;
|
obj[camelcase(fields[item.fieldid])] = item.value;
|
||||||
return obj;
|
return obj;
|
||||||
@@ -136,54 +150,62 @@ export class OrderAPI extends BaseSQLDataSource {
|
|||||||
if ('group' in orderRow) {
|
if ('group' in orderRow) {
|
||||||
orderRow['productGroup'] = orderRow['group'];
|
orderRow['productGroup'] = orderRow['group'];
|
||||||
}
|
}
|
||||||
|
return orderRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes input from order-rows query and gets the row details
|
||||||
|
*/
|
||||||
|
async getOrderRows(rows: any): Promise<Array<OrderRow>> {
|
||||||
|
let orderRows = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < rows.length; i++) {
|
||||||
|
const rowId = rows[i].rowid;
|
||||||
|
const orderRow = await this.getOrderRowDetailsForRowId(rowId);
|
||||||
|
if (!orderRow) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// take some data from order-rows results
|
||||||
orderRow['id'] = rowId;
|
orderRow['id'] = rowId;
|
||||||
orderRow['orderId'] = orderId;
|
orderRow['orderId'] = rows[i].orderid;
|
||||||
|
orderRow['inserted'] = rows[i].inserted;
|
||||||
|
|
||||||
orderRows.push(orderRow);
|
orderRows.push(orderRow);
|
||||||
}
|
}
|
||||||
return orderRows;
|
return orderRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getOrderRowsByOrderId(orderId: number): Promise<Array<OrderRow>> {
|
||||||
|
const rows = await this.knex
|
||||||
|
.raw('SELECT * FROM "order-rows" WHERE orderid = ?', orderId)
|
||||||
|
.then((data) => data.rows);
|
||||||
|
|
||||||
|
return await this.getOrderRows(rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOrderRowsByDesignerId(
|
||||||
|
designerId: number,
|
||||||
|
input: Maybe<GeneralInput>,
|
||||||
|
): Promise<Array<OrderRow>> {
|
||||||
|
const query = /* sql */ `
|
||||||
|
SELECT orderdetails.*, "order-rows".orderid
|
||||||
|
FROM "order-rows_details" orderdetails
|
||||||
|
JOIN "order-rows" ON "order-rows".rowid = orderdetails.rowid
|
||||||
|
WHERE orderdetails.fieldid = 105
|
||||||
|
AND orderdetails.value = ?
|
||||||
|
AND orderdetails.inserted >= ?
|
||||||
|
AND orderdetails.inserted <= ?
|
||||||
|
ORDER BY orderdetails.inserted ASC
|
||||||
|
${input?.limit ? `LIMIT ${input.limit}` : ''}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const from = input?.dates?.from ? input.dates.from : new Date('2000-01-01');
|
||||||
|
const to = input?.dates?.to ? input.dates.to : new Date();
|
||||||
|
|
||||||
|
const rows = await this.knex
|
||||||
|
.raw(query, [designerId, this.getSQLDate(from), this.getSQLDate(to)])
|
||||||
|
.then((data) => data.rows);
|
||||||
|
return await this.getOrderRows(rows);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* row
|
|
||||||
{
|
|
||||||
printId: '73963',
|
|
||||||
inserted: 2021-02-04T10:11:41.093Z,
|
|
||||||
productId: '54192',
|
|
||||||
group: 'photo-wallpaper',
|
|
||||||
type: 'scaling',
|
|
||||||
artNo: 'e50075',
|
|
||||||
path: 'flora-hysterica-4',
|
|
||||||
name: 'Flora Hysterica 4',
|
|
||||||
price: '587.092480',
|
|
||||||
width: '640',
|
|
||||||
height: '260',
|
|
||||||
x: '0.000000',
|
|
||||||
y: '0.135133',
|
|
||||||
weight: '1',
|
|
||||||
designer: 'martin-bergstrom',
|
|
||||||
designerId: '201',
|
|
||||||
commission: '0',
|
|
||||||
commissionResale: '0',
|
|
||||||
status: 'print',
|
|
||||||
process: 'true',
|
|
||||||
vat: '1.210000',
|
|
||||||
commissionAmount: '0.000000',
|
|
||||||
framed: '0',
|
|
||||||
mirrored: '0',
|
|
||||||
edge: '0',
|
|
||||||
imageprocessed: 'true',
|
|
||||||
imageprocessingrejected: 'false',
|
|
||||||
resolution: '150',
|
|
||||||
imagedonotprint: 'false',
|
|
||||||
material: 'premium-wallpaper',
|
|
||||||
discountType: '%',
|
|
||||||
discountValue: '25',
|
|
||||||
measureUnit: 'cm',
|
|
||||||
displayWidth: '640',
|
|
||||||
displayHeight: '260',
|
|
||||||
designerPath: 'martin-bergstrom'
|
|
||||||
},
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { DateInput } from './types';
|
||||||
|
|
||||||
export interface Market {
|
export interface Market {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@@ -45,11 +45,12 @@ export class ProductAPI extends SQLDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getPrintProducts(row: any): Array<PrintProduct> {
|
getPrintProducts(row: any): Array<PrintProduct> {
|
||||||
if (!row.printProducts) {
|
if (!row.printproducts) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return row.printProducts.map((pp: any) => {
|
return row.printproducts.map((pp: any) => {
|
||||||
pp.group = ProductGroup[pp.groupId];
|
pp.group = ProductGroup[pp.groupId];
|
||||||
|
pp.id = pp.printId;
|
||||||
return pp;
|
return pp;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -66,6 +67,7 @@ export class ProductAPI extends SQLDataSource {
|
|||||||
data.rows.map((row) => {
|
data.rows.map((row) => {
|
||||||
row.blacklisting = this.getBlacklisting(row);
|
row.blacklisting = this.getBlacklisting(row);
|
||||||
row.printProducts = this.getPrintProducts(row);
|
row.printProducts = this.getPrintProducts(row);
|
||||||
|
row.designerId = row.designerid;
|
||||||
return row;
|
return row;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -76,8 +78,10 @@ export class ProductAPI extends SQLDataSource {
|
|||||||
|
|
||||||
const res = await this.knex.raw(query).then((data) =>
|
const res = await this.knex.raw(query).then((data) =>
|
||||||
data.rows.map((row) => {
|
data.rows.map((row) => {
|
||||||
|
console.log(row);
|
||||||
row.blacklisting = this.getBlacklisting(row);
|
row.blacklisting = this.getBlacklisting(row);
|
||||||
row.printProducts = this.getPrintProducts(row);
|
row.printProducts = this.getPrintProducts(row);
|
||||||
|
row.designerId = row.designerid;
|
||||||
return row;
|
return row;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ SELECT products.productid as id,
|
|||||||
"product-printproducts".updated
|
"product-printproducts".updated
|
||||||
)
|
)
|
||||||
) FROM "product-printproducts" WHERE "product-printproducts".productid = products.productid
|
) FROM "product-printproducts" WHERE "product-printproducts".productid = products.productid
|
||||||
) AS printProducts,
|
) AS printproducts,
|
||||||
( SELECT json_agg(
|
( SELECT json_agg(
|
||||||
json_build_object(
|
json_build_object(
|
||||||
'id',
|
'id',
|
||||||
|
|||||||
@@ -1 +1,15 @@
|
|||||||
export type Maybe<T> = T | undefined;
|
export type Maybe<T> = T | undefined;
|
||||||
|
|
||||||
|
export interface DateInput {
|
||||||
|
from: Date;
|
||||||
|
to: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GeneralInput {
|
||||||
|
dates: DateInput;
|
||||||
|
limit: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterInput {
|
||||||
|
filter: GeneralInput;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,13 +8,18 @@ import { typeDefs } from './schema';
|
|||||||
import resolvers from './resolvers';
|
import resolvers from './resolvers';
|
||||||
import { OrderAPI } from './datasources/order-api';
|
import { OrderAPI } from './datasources/order-api';
|
||||||
import { ProductAPI } from './datasources/product-api';
|
import { ProductAPI } from './datasources/product-api';
|
||||||
|
import { DesignerAPI } from './datasources/designer-api';
|
||||||
|
|
||||||
const knexConfig = knexStringcase(dbConfig);
|
const knexConfig = knexStringcase(dbConfig);
|
||||||
|
|
||||||
|
// TODO: Try with this to see if - tables don't get converted
|
||||||
|
// delete knexConfig.appWrapIdentifier;
|
||||||
|
|
||||||
// set up any dataSources our resolvers need
|
// set up any dataSources our resolvers need
|
||||||
const dataSources = () => ({
|
const dataSources = () => ({
|
||||||
orderApi: new OrderAPI(knexConfig),
|
orderApi: new OrderAPI(knexConfig),
|
||||||
productApi: new ProductAPI(knexConfig),
|
productApi: new ProductAPI(knexConfig),
|
||||||
|
designerApi: new DesignerAPI(knexConfig),
|
||||||
});
|
});
|
||||||
|
|
||||||
const context = async ({ req }) => {
|
const context = async ({ req }) => {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import { GraphQLScalarType } from 'graphql';
|
|||||||
import { Kind } from 'graphql/language';
|
import { Kind } from 'graphql/language';
|
||||||
|
|
||||||
// possible switch to https://github.com/Urigo/graphql-scalars
|
// possible switch to https://github.com/Urigo/graphql-scalars
|
||||||
export const DateTimeScalar = new GraphQLScalarType({
|
const DateTimeScalar = new GraphQLScalarType({
|
||||||
name: 'DateTime',
|
name: 'DateTime',
|
||||||
description: 'Date custom scalar type',
|
description: 'Date time custom scalar type',
|
||||||
parseValue(value) {
|
parseValue(value) {
|
||||||
return new Date(value); // value from the client
|
return new Date(value); // value from the client
|
||||||
},
|
},
|
||||||
@@ -18,3 +18,26 @@ export const DateTimeScalar = new GraphQLScalarType({
|
|||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const DateScalar = new GraphQLScalarType({
|
||||||
|
name: 'DateTime',
|
||||||
|
description: 'Date custom scalar type',
|
||||||
|
parseValue(value) {
|
||||||
|
console.log('FROM CLIENT:', value);
|
||||||
|
return new Date(value); // value from the client
|
||||||
|
},
|
||||||
|
serialize(value) {
|
||||||
|
return new Date(value).toISOString().split('T')[0]; // value sent to the client
|
||||||
|
},
|
||||||
|
parseLiteral(ast) {
|
||||||
|
if (ast.kind === Kind.INT) {
|
||||||
|
return parseInt(ast.value, 10); // ast value is always in string format
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const CustomTypes = {
|
||||||
|
DateTime: DateTimeScalar,
|
||||||
|
Date: DateScalar,
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { IResolverObject } from 'graphql-tools';
|
||||||
|
import { DesignerAPI } from '../datasources/designer-api';
|
||||||
|
import { OrderAPI } from '../datasources/order-api';
|
||||||
|
import { FilterInput } from '../datasources/types';
|
||||||
|
|
||||||
|
const Designer: IResolverObject = {
|
||||||
|
async orderRows({ id }, args: FilterInput, { dataSources }) {
|
||||||
|
return (<OrderAPI>dataSources.orderApi).getOrderRowsByDesignerId(
|
||||||
|
id,
|
||||||
|
args.filter,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getDesigners(_, { limit }, { dataSources }) {
|
||||||
|
return (<DesignerAPI>dataSources.designerApi).getDesigners(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDesigner(_, { id }, { dataSources }) {
|
||||||
|
return (<DesignerAPI>dataSources.designerApi).getDesignerById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const designerTypeDefs = { Designer };
|
||||||
|
|
||||||
|
export const designerQueryTypeDefs = {
|
||||||
|
designers: getDesigners,
|
||||||
|
designer: getDesigner,
|
||||||
|
};
|
||||||
+10
-4
@@ -1,12 +1,18 @@
|
|||||||
import { orderQueryTypeDefs, orderTypeDefs } from './orders-resolver';
|
import { orderQueryTypeDefs, orderTypeDefs } from './orders-resolver';
|
||||||
import { productQueryTypeDefs, productTypeDefs } from './products-resolver';
|
import { productQueryTypeDefs, productTypeDefs } from './products-resolver';
|
||||||
import { DateTimeScalar } from './datetime-type';
|
import { designerQueryTypeDefs, designerTypeDefs } from './designers-resolver';
|
||||||
|
import { DateTimeResolver, DateResolver } from 'graphql-scalars';
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Query: { ...orderQueryTypeDefs, ...productQueryTypeDefs },
|
Query: {
|
||||||
DateTime: DateTimeScalar,
|
...orderQueryTypeDefs,
|
||||||
|
...productQueryTypeDefs,
|
||||||
|
...designerQueryTypeDefs,
|
||||||
|
},
|
||||||
...orderTypeDefs,
|
...orderTypeDefs,
|
||||||
...productTypeDefs,
|
...productTypeDefs,
|
||||||
|
...designerTypeDefs,
|
||||||
|
DateTime: DateTimeResolver,
|
||||||
|
Date: DateResolver,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default resolvers;
|
export default resolvers;
|
||||||
|
|||||||
@@ -1,33 +1,35 @@
|
|||||||
import { IResolverObject } from 'graphql-tools';
|
import { IResolverObject } from 'graphql-tools';
|
||||||
|
import { OrderAPI } from '../datasources/order-api';
|
||||||
|
import { FilterInput } from '../datasources/types';
|
||||||
|
|
||||||
const ContactInformation: IResolverObject = {
|
const ContactInformation: IResolverObject = {
|
||||||
// (parent, args, ctx, info)
|
// (parent, args, ctx, info)
|
||||||
async address({ addressId }, args, { dataSources }) {
|
async address({ addressId }, args, { dataSources }) {
|
||||||
return dataSources.orderApi.getAddress(addressId);
|
return (<OrderAPI>dataSources.orderApi).getAddress(addressId);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const Order: IResolverObject = {
|
const Order: IResolverObject = {
|
||||||
async rows({ id }, args, { dataSources }) {
|
async rows({ id }, args, { dataSources }) {
|
||||||
return dataSources.orderApi.getOrderRows(id);
|
return (<OrderAPI>dataSources.orderApi).getOrderRowsByOrderId(id);
|
||||||
},
|
},
|
||||||
async marketObject({ market }, args, { dataSources }) {
|
async marketObject({ market }, args, { dataSources }) {
|
||||||
return dataSources.orderApi.getMarketByName(market);
|
return (<OrderAPI>dataSources.orderApi).getMarketByName(market);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const OrderRow: IResolverObject = {
|
const OrderRow: IResolverObject = {
|
||||||
async order(parent, args, { dataSources }) {
|
async order(parent, args, { dataSources }) {
|
||||||
return dataSources.orderApi.getOrder(parent.orderId);
|
return (<OrderAPI>dataSources.orderApi).getOrderById(parent.orderId);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getOrders(_, __, { dataSources }) {
|
async function getOrders(_, args: FilterInput, { dataSources }) {
|
||||||
return dataSources.orderApi.getOrders();
|
return (<OrderAPI>dataSources.orderApi).getOrders(args.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getOrder(_, { id }, { dataSources }) {
|
async function getOrder(_, { id }, { dataSources }) {
|
||||||
return dataSources.orderApi.getOrder(id);
|
return (<OrderAPI>dataSources.orderApi).getOrderById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const orderTypeDefs = {
|
export const orderTypeDefs = {
|
||||||
|
|||||||
@@ -1,24 +1,33 @@
|
|||||||
// (parent, args, ctx, info)
|
// (parent, args, ctx, info)
|
||||||
import { IResolverObject } from 'graphql-tools';
|
import { IResolverObject } from 'graphql-tools';
|
||||||
|
import { OrderAPI } from '../datasources/order-api';
|
||||||
|
import { ProductAPI } from '../datasources/product-api';
|
||||||
|
|
||||||
const ProductBlacklist: IResolverObject = {
|
const ProductBlacklist: IResolverObject = {
|
||||||
async market(parent, args, { dataSources }) {
|
async market(parent, args, { dataSources }) {
|
||||||
return dataSources.orderApi.getMarketById(parent.marketId);
|
return (<OrderAPI>dataSources.orderApi).getMarketById(parent.marketId);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const Product: IResolverObject = {
|
const Product: IResolverObject = {
|
||||||
async categories({ id }, args, { dataSources }) {
|
async categories({ id }, args, { dataSources }) {
|
||||||
return dataSources.productApi.getCategories(id);
|
return (<ProductAPI>dataSources.productApi).getCategories(id);
|
||||||
|
},
|
||||||
|
async designer({ designerId }, args, { dataSources }) {
|
||||||
|
return dataSources.designerApi.getDesignerById(designerId);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getProducts(_, { limit, visible, browsable }, { dataSources }) {
|
async function getProducts(_, { limit, visible, browsable }, { dataSources }) {
|
||||||
return dataSources.productApi.getProducts(limit, visible, browsable);
|
return (<ProductAPI>dataSources.productApi).getProducts(
|
||||||
|
limit,
|
||||||
|
visible,
|
||||||
|
browsable,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getProduct(_, { id }, { dataSources }) {
|
async function getProduct(_, { id }, { dataSources }) {
|
||||||
return dataSources.productApi.getProduct(id);
|
return (<ProductAPI>dataSources.productApi).getProduct(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const productTypeDefs = {
|
export const productTypeDefs = {
|
||||||
|
|||||||
+23
-17
@@ -2,12 +2,25 @@ import { gql } from 'apollo-server';
|
|||||||
|
|
||||||
const typeDefs = gql`
|
const typeDefs = gql`
|
||||||
scalar DateTime
|
scalar DateTime
|
||||||
|
scalar Date
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
orders: [Order]
|
orders(filter: FilterInput): [Order]
|
||||||
order(id: ID!): Order
|
order(id: ID!): Order
|
||||||
products(limit: Int, visible: Boolean, browsable: Boolean): [Product]
|
products(limit: Int, visible: Boolean, browsable: Boolean): [Product]
|
||||||
product(id: Int!): Product
|
product(id: Int!): Product
|
||||||
|
designers(limit: Int): [Designer]
|
||||||
|
designer(id: Int!): Designer
|
||||||
|
}
|
||||||
|
|
||||||
|
input DateInput {
|
||||||
|
from: Date
|
||||||
|
to: Date
|
||||||
|
}
|
||||||
|
|
||||||
|
input FilterInput {
|
||||||
|
dates: DateInput
|
||||||
|
limit: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
type Market {
|
type Market {
|
||||||
@@ -125,6 +138,8 @@ const typeDefs = gql`
|
|||||||
printProducts: [PrintProduct]
|
printProducts: [PrintProduct]
|
||||||
blacklisting: [ProductBlacklist]
|
blacklisting: [ProductBlacklist]
|
||||||
categories: [Category]
|
categories: [Category]
|
||||||
|
designerId: Int
|
||||||
|
designer: Designer
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ProductGroup {
|
enum ProductGroup {
|
||||||
@@ -154,22 +169,13 @@ const typeDefs = gql`
|
|||||||
inserted: DateTime!
|
inserted: DateTime!
|
||||||
updated: DateTime
|
updated: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Designer {
|
||||||
|
id: ID!
|
||||||
|
name: String
|
||||||
|
path: String
|
||||||
|
orderRows(filter: FilterInput): [OrderRow]
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export { typeDefs };
|
export { typeDefs };
|
||||||
/**
|
|
||||||
type Designer {
|
|
||||||
id: ID!
|
|
||||||
name: String
|
|
||||||
orderRows(fromDate: Date, toDate: Date): [OrderRow]
|
|
||||||
}
|
|
||||||
|
|
||||||
type Product {
|
|
||||||
designer: Designer
|
|
||||||
}
|
|
||||||
|
|
||||||
type Query {
|
|
||||||
designer(id: Int!): Designer
|
|
||||||
designers: [Designer]
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|||||||
Reference in New Issue
Block a user