Adds Payload SDK package, which can be used to query Payload REST API in
a fully type safe way. Has support for all necessary operations,
including auth, type safe `select`, `populate`, `joins` properties and
simplified file uploading.
Its interface is _very_ similar to the Local API, can't even notice the
difference:
Example:
```ts
import { PayloadSDK } from '@payloadcms/sdk'
import type { Config } from './payload-types'
// Pass your config from generated types as generic
const sdk = new PayloadSDK<Config>({
baseURL: 'https://example.com/api',
})
// Find operation
const posts = await sdk.find({
collection: 'posts',
draft: true,
limit: 10,
locale: 'en',
page: 1,
where: { _status: { equals: 'published' } },
})
// Find by ID operation
const posts = await sdk.findByID({
id,
collection: 'posts',
draft: true,
locale: 'en',
})
// Auth login operation
const result = await sdk.login({
collection: 'users',
data: {
email: 'dev@payloadcms.com',
password: '12345',
},
})
// Create operation
const result = await sdk.create({
collection: 'posts',
data: { text: 'text' },
})
// Create operation with a file
// `file` can be either a Blob | File object or a string URL
const result = await sdk.create({ collection: 'media', file, data: {} })
// Count operation
const result = await sdk.count({ collection: 'posts', where: { id: { equals: post.id } } })
// Update (by ID) operation
const result = await sdk.update({
collection: 'posts',
id: post.id,
data: {
text: 'updated-text',
},
})
// Update (bulk) operation
const result = await sdk.update({
collection: 'posts',
where: {
id: {
equals: post.id,
},
},
data: { text: 'updated-text-bulk' },
})
// Delete (by ID) operation
const result = await sdk.delete({ id: post.id, collection: 'posts' })
// Delete (bulk) operation
const result = await sdk.delete({ where: { id: { equals: post.id } }, collection: 'posts' })
// Find Global operation
const result = await sdk.findGlobal({ slug: 'global' })
// Update Global operation
const result = await sdk.updateGlobal({ slug: 'global', data: { text: 'some-updated-global' } })
// Auth Login operation
const result = await sdk.login({
collection: 'users',
data: { email: 'dev@payloadcms.com', password: '123456' },
})
// Auth Me operation
const result = await sdk.me(
{ collection: 'users' },
{
headers: {
Authorization: `JWT ${user.token}`,
},
},
)
// Auth Refresh Token operation
const result = await sdk.refreshToken(
{ collection: 'users' },
{ headers: { Authorization: `JWT ${user.token}` } },
)
// Auth Forgot Password operation
const result = await sdk.forgotPassword({
collection: 'users',
data: { email: user.email },
})
// Auth Reset Password operation
const result = await sdk.resetPassword({
collection: 'users',
data: { password: '1234567', token: resetPasswordToken },
})
// Find Versions operation
const result = await sdk.findVersions({
collection: 'posts',
where: { parent: { equals: post.id } },
})
// Find Version by ID operation
const result = await sdk.findVersionByID({ collection: 'posts', id: version.id })
// Restore Version operation
const result = await sdk.restoreVersion({
collection: 'posts',
id,
})
// Find Global Versions operation
const result = await sdk.findGlobalVersions({
slug: 'global',
})
// Find Global Version by ID operation
const result = await sdk.findGlobalVersionByID({ id: version.id, slug: 'global' })
// Restore Global Version operation
const result = await sdk.restoreGlobalVersion({
slug: 'global',
id
})
```
Every operation has optional 3rd parameter which is used to add
additional data to the RequestInit object (like headers):
```ts
await sdk.me({
collection: "users"
}, {
// RequestInit object
headers: {
Authorization: `JWT ${token}`
}
})
```
To query custom endpoints, you can use the `request` method, which is
used internally for all other methods:
```ts
await sdk.request({
method: 'POST',
path: '/send-data',
json: {
id: 1,
},
})
```
Custom `fetch` implementation and `baseInit` for shared `RequestInit`
properties:
```ts
const sdk = new PayloadSDK<Config>({
baseInit: { credentials: 'include' },
baseURL: 'https://example.com/api',
fetch: async (url, init) => {
console.log('before req')
const response = await fetch(url, init)
console.log('after req')
return response
},
})
```
97 lines
4.2 KiB
TypeScript
97 lines
4.2 KiB
TypeScript
import fs from 'fs'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const filename = fileURLToPath(import.meta.url)
|
|
const dirname = path.dirname(filename)
|
|
|
|
export const tgzToPkgNameMap = {
|
|
payload: 'payload-*',
|
|
'@payloadcms/admin-bar': 'payloadcms-admin-bar-*',
|
|
'@payloadcms/db-mongodb': 'payloadcms-db-mongodb-*',
|
|
'@payloadcms/db-postgres': 'payloadcms-db-postgres-*',
|
|
'@payloadcms/db-vercel-postgres': 'payloadcms-db-vercel-postgres-*',
|
|
'@payloadcms/db-sqlite': 'payloadcms-db-sqlite-*',
|
|
'@payloadcms/db-d1-sqlite': 'payloadcms-db-d1-sqlite-*',
|
|
'@payloadcms/drizzle': 'payloadcms-drizzle-*',
|
|
'@payloadcms/email-nodemailer': 'payloadcms-email-nodemailer-*',
|
|
'@payloadcms/email-resend': 'payloadcms-email-resend-*',
|
|
'@payloadcms/eslint-config': 'payloadcms-eslint-config-*',
|
|
'@payloadcms/eslint-plugin': 'payloadcms-eslint-plugin-*',
|
|
'@payloadcms/graphql': 'payloadcms-graphql-*',
|
|
'@payloadcms/live-preview': 'payloadcms-live-preview-*',
|
|
'@payloadcms/live-preview-react': 'payloadcms-live-preview-react-*',
|
|
'@payloadcms/next': 'payloadcms-next-*',
|
|
'@payloadcms/payload-cloud': 'payloadcms-payload-cloud-*',
|
|
'@payloadcms/plugin-cloud-storage': 'payloadcms-plugin-cloud-storage-*',
|
|
'@payloadcms/plugin-form-builder': 'payloadcms-plugin-form-builder-*',
|
|
'@payloadcms/plugin-import-export': 'payloadcms-plugin-import-export-*',
|
|
'@payloadcms/plugin-multi-tenant': 'payloadcms-plugin-multi-tenant-*',
|
|
'@payloadcms/plugin-nested-docs': 'payloadcms-plugin-nested-docs-*',
|
|
'@payloadcms/plugin-redirects': 'payloadcms-plugin-redirects-*',
|
|
'@payloadcms/plugin-search': 'payloadcms-plugin-search-*',
|
|
'@payloadcms/plugin-sentry': 'payloadcms-plugin-sentry-*',
|
|
'@payloadcms/plugin-seo': 'payloadcms-plugin-seo-*',
|
|
'@payloadcms/plugin-stripe': 'payloadcms-plugin-stripe-*',
|
|
'@payloadcms/richtext-lexical': 'payloadcms-richtext-lexical-*',
|
|
'@payloadcms/richtext-slate': 'payloadcms-richtext-slate-*',
|
|
'@payloadcms/sdk': 'payloadcms-sdk-*',
|
|
'@payloadcms/storage-azure': 'payloadcms-storage-azure-*',
|
|
'@payloadcms/storage-gcs': 'payloadcms-storage-gcs-*',
|
|
'@payloadcms/storage-s3': 'payloadcms-storage-s3-*',
|
|
'@payloadcms/storage-uploadthing': 'payloadcms-storage-uploadthing-*',
|
|
'@payloadcms/storage-vercel-blob': 'payloadcms-storage-vercel-blob-*',
|
|
'@payloadcms/translations': 'payloadcms-translations-*',
|
|
'@payloadcms/ui': 'payloadcms-ui-*',
|
|
'create-payload-app': 'create-payload-app-*',
|
|
}
|
|
|
|
function findActualTgzName(pattern: string) {
|
|
const packedDir = path.resolve(dirname, 'packed')
|
|
const files = fs.readdirSync(packedDir)
|
|
const matchingFile = files.find((file) => file.startsWith(pattern.replace('*', '')))
|
|
return matchingFile ? `file:packed/${matchingFile}` : null
|
|
}
|
|
|
|
/**
|
|
* This does the following:
|
|
* - installs all packages from test/packed to test/package.json
|
|
*/
|
|
export function setupProd() {
|
|
const packageJsonString = fs.readFileSync(path.resolve(dirname, 'package.json'), 'utf8')
|
|
const packageJson = JSON.parse(packageJsonString)
|
|
|
|
const allDependencies = {}
|
|
// Go through all the dependencies and devDependencies, replace the normal package entry with the tgz entry
|
|
for (const key of ['dependencies', 'devDependencies']) {
|
|
const dependencies = packageJson[key]
|
|
if (dependencies) {
|
|
for (const [packageName, _packageVersion] of Object.entries(dependencies)) {
|
|
if (tgzToPkgNameMap[packageName]) {
|
|
const actualTgzPath = findActualTgzName(tgzToPkgNameMap[packageName])
|
|
if (actualTgzPath) {
|
|
dependencies[packageName] = actualTgzPath
|
|
allDependencies[packageName] = actualTgzPath
|
|
} else {
|
|
console.warn(`Warning: No matching tgz found for ${packageName}`)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// now add them all to overrides and pnpm.overrides as well
|
|
packageJson.pnpm = packageJson.pnpm || {}
|
|
packageJson.pnpm.overrides = packageJson.pnpm.overrides || {}
|
|
packageJson.overrides = packageJson.overrides || {}
|
|
for (const [packageName, packageVersion] of Object.entries(allDependencies)) {
|
|
packageJson.pnpm.overrides[packageName] = packageVersion
|
|
packageJson.overrides[packageName] = packageVersion
|
|
}
|
|
|
|
// write it out
|
|
fs.writeFileSync(path.resolve(dirname, 'package.json'), JSON.stringify(packageJson, null, 2))
|
|
}
|
|
|
|
setupProd()
|