Skip to content

Commit

Permalink
Use the DB list API where appropriate (#5530)
Browse files Browse the repository at this point in the history
  • Loading branch information
timleslie committed Apr 26, 2021
1 parent c286d7f commit 74fed41
Show file tree
Hide file tree
Showing 13 changed files with 59 additions and 59 deletions.
8 changes: 8 additions & 0 deletions .changeset/warm-kiwis-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@keystone-next/example-ecommerce': patch
'@keystone-next/admin-ui': patch
'@keystone-next/auth': patch
'@keystone-next/api-tests-legacy': patch
---

Updated code to use the new DB items API.
6 changes: 2 additions & 4 deletions examples/ecommerce/mutations/addToCart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@ async function addToCart(
console.log(`There are already ${existingCartItem.quantity}, increment by 1!`);
// 3. See if the current item is in their cart
// 4. if itis, increment by 1
return await context.lists.CartItem.updateOne({
return await context.db.lists.CartItem.updateOne({
id: existingCartItem.id,
data: { quantity: existingCartItem.quantity + 1 },
resolveFields: false,
});
}
// 4. if it isnt, create a new cart item!
return await context.lists.CartItem.createOne({
return await context.db.lists.CartItem.createOne({
data: {
product: { connect: { id: productId } },
user: { connect: { id: sesh.itemId } },
},
resolveFields: false,
});
}

Expand Down
3 changes: 1 addition & 2 deletions examples/ecommerce/mutations/checkout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,13 @@ async function checkout(root: any, { token }: Arguments, context: KeystoneContex
});
console.log('gonna create the order');
// 5. Create the order and return it
const order = await context.lists.Order.createOne({
const order = await context.db.lists.Order.createOne({
data: {
total: charge.amount,
charge: charge.id,
items: { create: orderItems },
user: { connect: { id: userId } },
},
resolveFields: false,
});
console.log({ order });
// 6. Clean up any old cart item
Expand Down
7 changes: 3 additions & 4 deletions packages-next/admin-ui/src/system/getAdminMetaSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,9 @@ export function getAdminMetaSchema({
'KeystoneAdminUIFieldMetaItemView.fieldMode cannot be resolved during the build process'
);
}
const item = await context.sudo().lists[rootVal.listKey].findOne({
where: { id: rootVal.itemId },
resolveFields: false,
});
const item = await context
.sudo()
.db.lists[rootVal.listKey].findOne({ where: { id: rootVal.itemId } });
const listConfig = config.lists[rootVal.listKey];
const sessionFunction =
listConfig.fields[rootVal.fieldPath].config.ui?.itemView?.fieldMode ??
Expand Down
11 changes: 4 additions & 7 deletions packages-next/auth/src/gql/getBaseAuthSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ export function getBaseAuthSchema<I extends string, S extends string>({
}

const list = context.keystone.lists[listKey];
const itemAPI = context.sudo().lists[listKey];
const dbItemAPI = context.sudo().db.lists[listKey];
const result = await validateSecret(
list,
identityField,
args[identityField],
secretField,
protectIdentities,
args[secretField],
itemAPI
dbItemAPI
);

if (!result.success) {
Expand All @@ -86,13 +86,10 @@ export function getBaseAuthSchema<I extends string, S extends string>({
},
},
Query: {
async authenticatedItem(root, args, { session, lists }) {
async authenticatedItem(root, args, { session, db }) {
if (typeof session?.itemId === 'string' && typeof session.listKey === 'string') {
try {
return lists[session.listKey].findOne({
where: { id: session.itemId },
resolveFields: false,
});
return db.lists[session.listKey].findOne({ where: { id: session.itemId } });
} catch (e) {
return null;
}
Expand Down
9 changes: 3 additions & 6 deletions packages-next/auth/src/gql/getInitFirstItemSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,14 @@ export function getInitFirstItemSchema({
throw new Error('No session implementation available on context');
}

const itemAPI = context.sudo().lists[listKey];
const count = await itemAPI.count({});
const dbItemAPI = context.sudo().db.lists[listKey];
const count = await dbItemAPI.count({});
if (count !== 0) {
throw new Error('Initial items can only be created when no items exist in that list');
}

// Update system state
const item = await itemAPI.createOne({
data: { ...data, ...itemData },
resolveFields: false,
});
const item = await dbItemAPI.createOne({ data: { ...data, ...itemData } });
const sessionToken = await context.startSession({ listKey, itemId: item.id });
return { item, sessionToken };
},
Expand Down
19 changes: 11 additions & 8 deletions packages-next/auth/src/gql/getMagicAuthLinkSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,16 @@ export function getMagicAuthLinkSchema<I extends string>({
Mutation: {
async [gqlNames.sendItemMagicAuthLink](root: any, args: { [P in I]: string }, context) {
const list = context.keystone.lists[listKey];
const itemAPI = context.sudo().lists[listKey];
const dbItemAPI = context.sudo().db.lists[listKey];
const tokenType = 'magicAuth';
const identity = args[identityField];

const result = await createAuthToken(identityField, protectIdentities, identity, itemAPI);
const result = await createAuthToken(
identityField,
protectIdentities,
identity,
dbItemAPI
);

// Note: `success` can be false with no code
// If protectIdentities === true then result.code will *always* be undefined.
Expand All @@ -79,14 +84,13 @@ export function getMagicAuthLinkSchema<I extends string>({
if (result.success) {
// Save the token and related info back to the item
const { token, itemId } = result;
await itemAPI.updateOne({
await dbItemAPI.updateOne({
id: `${itemId}`,
data: {
[`${tokenType}Token`]: token,
[`${tokenType}IssuedAt`]: new Date().toISOString(),
[`${tokenType}RedeemedAt`]: null,
},
resolveFields: false,
});

await magicAuthLink.sendToken({ itemId, identity, token, context });
Expand All @@ -103,7 +107,7 @@ export function getMagicAuthLinkSchema<I extends string>({
}

const list = context.keystone.lists[listKey];
const itemAPI = context.sudo().lists[listKey];
const dbItemAPI = context.sudo().db.lists[listKey];
const tokenType = 'magicAuth';
const result = await validateAuthToken(
tokenType,
Expand All @@ -113,7 +117,7 @@ export function getMagicAuthLinkSchema<I extends string>({
protectIdentities,
magicAuthLink.tokensValidForMins,
args.token,
itemAPI
dbItemAPI
);

if (!result.success) {
Expand All @@ -128,10 +132,9 @@ export function getMagicAuthLinkSchema<I extends string>({
}
// Update system state
// Save the token and related info back to the item
await itemAPI.updateOne({
await dbItemAPI.updateOne({
id: result.item.id,
data: { [`${tokenType}RedeemedAt`]: new Date().toISOString() },
resolveFields: false,
});

const sessionToken = await context.startSession({ listKey, itemId: result.item.id });
Expand Down
26 changes: 14 additions & 12 deletions packages-next/auth/src/gql/getPasswordResetSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,16 @@ export function getPasswordResetSchema<I extends string, S extends string>({
Mutation: {
async [gqlNames.sendItemPasswordResetLink](root: any, args: { [P in I]: string }, context) {
const list = context.keystone.lists[listKey];
const itemAPI = context.sudo().lists[listKey];
const dbItemAPI = context.sudo().db.lists[listKey];
const tokenType = 'passwordReset';
const identity = args[identityField];

const result = await createAuthToken(identityField, protectIdentities, identity, itemAPI);
const result = await createAuthToken(
identityField,
protectIdentities,
identity,
dbItemAPI
);

// Note: `success` can be false with no code
// If protectIdentities === true then result.code will *always* be undefined.
Expand All @@ -84,14 +89,13 @@ export function getPasswordResetSchema<I extends string, S extends string>({
if (result.success) {
// Save the token and related info back to the item
const { token, itemId } = result;
await itemAPI.updateOne({
await dbItemAPI.updateOne({
id: `${itemId}`,
data: {
[`${tokenType}Token`]: token,
[`${tokenType}IssuedAt`]: new Date().toISOString(),
[`${tokenType}RedeemedAt`]: null,
},
resolveFields: false,
});

await passwordResetLink.sendToken({ itemId, identity, token, context });
Expand All @@ -104,7 +108,7 @@ export function getPasswordResetSchema<I extends string, S extends string>({
context
) {
const list = context.keystone.lists[listKey];
const itemAPI = context.sudo().lists[listKey];
const dbItemAPI = context.sudo().db.lists[listKey];
const tokenType = 'passwordReset';
const result = await validateAuthToken(
tokenType,
Expand All @@ -114,7 +118,7 @@ export function getPasswordResetSchema<I extends string, S extends string>({
protectIdentities,
passwordResetLink.tokensValidForMins,
args.token,
itemAPI
dbItemAPI
);

if (!result.success) {
Expand All @@ -133,19 +137,17 @@ export function getPasswordResetSchema<I extends string, S extends string>({
// Update system state
const itemId = result.item.id;
// Save the token and related info back to the item
await itemAPI.updateOne({
await dbItemAPI.updateOne({
id: itemId,
data: { [`${tokenType}RedeemedAt`]: new Date().toISOString() },
resolveFields: false,
});

// Save the provided secret. Do this as a separate step as password validation
// may fail, in which case we still want to mark the token as redeemed
// (NB: Is this *really* what we want? -TL)
await itemAPI.updateOne({
await dbItemAPI.updateOne({
id: itemId,
data: { [secretField]: args[secretField] },
resolveFields: false,
});

return null;
Expand All @@ -158,7 +160,7 @@ export function getPasswordResetSchema<I extends string, S extends string>({
context
) {
const list = context.keystone.lists[listKey];
const itemAPI = context.sudo().lists[listKey];
const dbItemAPI = context.sudo().db.lists[listKey];
const tokenType = 'passwordReset';
const result = await validateAuthToken(
tokenType,
Expand All @@ -168,7 +170,7 @@ export function getPasswordResetSchema<I extends string, S extends string>({
protectIdentities,
passwordResetLink.tokensValidForMins,
args.token,
itemAPI
dbItemAPI
);

if (!result.success && result.code) {
Expand Down
6 changes: 3 additions & 3 deletions packages-next/auth/src/lib/createAuthToken.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { randomBytes } from 'crypto';
import type { KeystoneListsAPI } from '@keystone-next/types';
import type { KeystoneDbAPI } from '@keystone-next/types';
import { AuthTokenRequestErrorCode } from '../types';
import { findMatchingIdentity } from './findMatchingIdentity';

Expand All @@ -16,12 +16,12 @@ export async function createAuthToken(
identityField: string,
protectIdentities: boolean,
identity: string,
itemAPI: KeystoneListsAPI<any>[string]
dbItemAPI: KeystoneDbAPI<any>[string]
): Promise<
| { success: false; code?: AuthTokenRequestErrorCode }
| { success: true; itemId: string | number; token: string }
> {
const match = await findMatchingIdentity(identityField, identity, itemAPI);
const match = await findMatchingIdentity(identityField, identity, dbItemAPI);
// Identity failures with helpful errors (unless it would violate our protectIdentities config)
if (match.success) {
return { success: true, itemId: match.item.id, token: generateToken(20) };
Expand Down
9 changes: 3 additions & 6 deletions packages-next/auth/src/lib/findMatchingIdentity.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import type { KeystoneListsAPI } from '@keystone-next/types';
import type { KeystoneDbAPI } from '@keystone-next/types';

import { AuthTokenRequestErrorCode } from '../types';

export async function findMatchingIdentity(
identityField: string,
identity: string,
itemAPI: KeystoneListsAPI<any>[string]
dbItemAPI: KeystoneDbAPI<any>[string]
): Promise<
| { success: false; code: AuthTokenRequestErrorCode }
| { success: true; item: { id: any; [prop: string]: any } }
> {
const items = await itemAPI.findMany({
where: { [identityField]: identity },
resolveFields: false,
});
const items = await dbItemAPI.findMany({ where: { [identityField]: identity } });

// Identity failures with helpful errors
let code: AuthTokenRequestErrorCode | undefined;
Expand Down
6 changes: 3 additions & 3 deletions packages-next/auth/src/lib/validateAuthToken.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { KeystoneListsAPI } from '@keystone-next/types';
import type { KeystoneDbAPI } from '@keystone-next/types';
import { AuthTokenRedemptionErrorCode } from '../types';
import { validateSecret } from './validateSecret';

Expand All @@ -17,7 +17,7 @@ export async function validateAuthToken(
protectIdentities: boolean,
tokenValidMins: number | undefined,
token: string,
itemAPI: KeystoneListsAPI<any>[string]
dbItemAPI: KeystoneDbAPI<any>[string]
): Promise<
| { success: false; code: AuthTokenRedemptionErrorCode }
| { success: true; item: { id: any; [prop: string]: any } }
Expand All @@ -29,7 +29,7 @@ export async function validateAuthToken(
`${tokenType}Token`,
protectIdentities,
token,
itemAPI
dbItemAPI
);
if (!result.success) {
// Rewrite error codes
Expand Down
6 changes: 3 additions & 3 deletions packages-next/auth/src/lib/validateSecret.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { KeystoneListsAPI } from '@keystone-next/types';
import type { KeystoneDbAPI } from '@keystone-next/types';
import { PasswordAuthErrorCode } from '../types';
import { findMatchingIdentity } from './findMatchingIdentity';

Expand All @@ -9,12 +9,12 @@ export async function validateSecret(
secretField: string,
protectIdentities: boolean,
secret: string,
itemAPI: KeystoneListsAPI<any>[string]
dbItemAPI: KeystoneDbAPI<any>[string]
): Promise<
| { success: false; code: PasswordAuthErrorCode }
| { success: true; item: { id: any; [prop: string]: any } }
> {
const match = await findMatchingIdentity(identityField, identity, itemAPI);
const match = await findMatchingIdentity(identityField, identity, dbItemAPI);
// Identity failures with helpful errors
let code: PasswordAuthErrorCode | undefined;
if (!match.success) {
Expand Down
2 changes: 1 addition & 1 deletion tests/api-tests/new-interfaces.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ multiAdapterRunners().map(({ runner, provider }) =>
test(
'Smoke test',
runner(setupKeystone, async ({ context }) => {
const users = await context.lists.User.findMany({ resolveFields: false });
const users = await context.db.lists.User.findMany({});
expect(users).toEqual([]);
})
);
Expand Down

1 comment on commit 74fed41

@vercel
Copy link

@vercel vercel bot commented on 74fed41 Apr 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.