feat: adds new Cloudflare D1 SQLite adapter, R2 storage adapter and Cloudflare template (#12537)
This feat adds support for - [D1 Cloudflare SQLite](https://developers.cloudflare.com/d1/) - R2 storage directly (previously it was via S3 SDK) - Cloudflare 1-click deploy template --------- Co-authored-by: Paul Popus <paul@payloadcms.com>
This commit is contained in:
@@ -278,3 +278,35 @@ sqliteAdapter({
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
## D1 Database
|
||||
|
||||
<Banner type="warning">
|
||||
This adapter is currently in beta as it is new and could be subject to changes
|
||||
which may be considered breaking
|
||||
</Banner>
|
||||
|
||||
We also provide a separate adapter to connect to [Cloudflare D1](https://developers.cloudflare.com/d1/), which is a serverless SQLite database.
|
||||
|
||||
To use it, install the package `@payloadcms/db-d1-sqlite` and configure it as follows:
|
||||
|
||||
```ts
|
||||
import { sqliteD1Adapter } from '@payloadcms/db-d1-sqlite'
|
||||
|
||||
export default buildConfig({
|
||||
// Your config goes here
|
||||
collections: [
|
||||
// Collections go here
|
||||
],
|
||||
// Configure the D1 adapter here
|
||||
db: sqliteD1Adapter({
|
||||
// D1-specific arguments go here.
|
||||
// `binding` is required and should match the D1 database binding name in your Cloudflare Worker environment.
|
||||
binding: cloudflare.env.D1,
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
It inherits the options from the SQLite adapter above with the exception of the connection options in favour of the `binding`.
|
||||
|
||||
You can see our [Cloudflare D1 template](https://github.com/payloadcms/payload/tree/main/templates/with-cloudflare-d1) for a full example of how to set this up.
|
||||
|
||||
@@ -15,6 +15,7 @@ Payload offers additional storage adapters to handle file uploads. These adapter
|
||||
| Azure | [`@payloadcms/storage-azure`](https://github.com/payloadcms/payload/tree/main/packages/storage-azure) |
|
||||
| Google Cloud Storage | [`@payloadcms/storage-gcs`](https://github.com/payloadcms/payload/tree/main/packages/storage-gcs) |
|
||||
| Uploadthing | [`@payloadcms/storage-uploadthing`](https://github.com/payloadcms/payload/tree/main/packages/storage-uploadthing) |
|
||||
| R2 | [`@payloadcms/storage-r2`](https://github.com/payloadcms/payload/tree/main/packages/storage-r2) |
|
||||
|
||||
## Vercel Blob Storage
|
||||
|
||||
@@ -277,6 +278,43 @@ export default buildConfig({
|
||||
| `defaultKeyType` | Default key type for file operations | `fileKey` |
|
||||
| `clientUploads` | Do uploads directly on the client to bypass limits on Vercel. | |
|
||||
|
||||
## R2 Storage
|
||||
|
||||
<Banner type="warning">
|
||||
**Note**: The R2 Storage Adapter is in **beta** as some aspects of it may
|
||||
change on any minor releases.
|
||||
</Banner>
|
||||
|
||||
[`@payloadcms/storage-r2`](https://www.npmjs.com/package/@payloadcms/storage-r2)
|
||||
|
||||
Use this adapter to store uploads in a Cloudflare R2 bucket via the Cloudflare Workers environment. If you're trying to connect to R2 using the S3 API then you should use the [S3](#s3-storage) adapter instead.
|
||||
|
||||
### Installation#r2-installation
|
||||
|
||||
```sh
|
||||
pnpm add @payloadcms/storage-r2
|
||||
```
|
||||
|
||||
### Usage#r2-usage
|
||||
|
||||
- Configure the `collections` object to specify which collections should use r2. The slug _must_ match one of your existing collection slugs and be an `upload` type.
|
||||
- Pass in the R2 bucket binding to the `bucket` option, this should be done in the environment where Payload is running (e.g. Cloudflare Worker).
|
||||
- You can conditionally datamine whether or not to enable the plugin with the `enabled` option.
|
||||
|
||||
```ts
|
||||
export default buildConfig({
|
||||
collections: [Media],
|
||||
plugins: [
|
||||
r2Storage({
|
||||
collections: {
|
||||
media: true,
|
||||
},
|
||||
bucket: cloudflare.env.R2,
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
## Custom Storage Adapters
|
||||
|
||||
If you need to create a custom storage adapter, you can use the [`@payloadcms/plugin-cloud-storage`](https://www.npmjs.com/package/@payloadcms/plugin-cloud-storage) package. This package is used internally by the storage adapters mentioned above.
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"build:core": "turbo build --filter \"!@payloadcms/plugin-*\" --filter \"!@payloadcms/storage-*\" --filter \"!blank\" --filter \"!website\"",
|
||||
"build:core:force": "pnpm clean:build && pnpm build:core --no-cache --force",
|
||||
"build:create-payload-app": "turbo build --filter create-payload-app",
|
||||
"build:db-d1-sqlite": "turbo build --filter \"@payloadcms/db-d1-sqlite\"",
|
||||
"build:db-mongodb": "turbo build --filter \"@payloadcms/db-mongodb\"",
|
||||
"build:db-postgres": "turbo build --filter \"@payloadcms/db-postgres\"",
|
||||
"build:db-sqlite": "turbo build --filter \"@payloadcms/db-sqlite\"",
|
||||
|
||||
1
packages/db-d1-sqlite/.gitignore
vendored
Normal file
1
packages/db-d1-sqlite/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/migrations
|
||||
10
packages/db-d1-sqlite/.prettierignore
Normal file
10
packages/db-d1-sqlite/.prettierignore
Normal file
@@ -0,0 +1,10 @@
|
||||
.tmp
|
||||
**/.git
|
||||
**/.hg
|
||||
**/.pnp.*
|
||||
**/.svn
|
||||
**/.yarn/**
|
||||
**/build
|
||||
**/dist/**
|
||||
**/node_modules
|
||||
**/temp
|
||||
15
packages/db-d1-sqlite/.swcrc
Normal file
15
packages/db-d1-sqlite/.swcrc
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/swcrc",
|
||||
"sourceMaps": true,
|
||||
"jsc": {
|
||||
"target": "esnext",
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true,
|
||||
"dts": true
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
}
|
||||
}
|
||||
22
packages/db-d1-sqlite/LICENSE.md
Normal file
22
packages/db-d1-sqlite/LICENSE.md
Normal file
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018-2025 Payload CMS, Inc. <info@payloadcms.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
33
packages/db-d1-sqlite/README.md
Normal file
33
packages/db-d1-sqlite/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Payload D1 SQLite Adapter
|
||||
|
||||
Official D1 SQLite adapter for [Payload](https://payloadcms.com).
|
||||
|
||||
- [Main Repository](https://github.com/payloadcms/payload)
|
||||
- [Payload Docs](https://payloadcms.com/docs)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @payloadcms/db-d1-sqlite
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { sqliteD1Adapter } from '@payloadcms/db-d1-sqlite'
|
||||
|
||||
export default buildConfig({
|
||||
// Your config goes here
|
||||
collections: [
|
||||
// Collections go here
|
||||
],
|
||||
// Configure the D1 adapter here
|
||||
db: sqliteD1Adapter({
|
||||
// D1-specific arguments go here.
|
||||
// `binding` is required and should match the D1 database binding name in your Cloudflare Worker environment.
|
||||
binding: cloudflare.env.D1,
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
More detailed usage can be found in the [Payload Docs](https://payloadcms.com/docs/database/sqlite).
|
||||
38
packages/db-d1-sqlite/bundle.js
Normal file
38
packages/db-d1-sqlite/bundle.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import * as esbuild from 'esbuild'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
import { commonjs } from '@hyrious/esbuild-plugin-commonjs'
|
||||
|
||||
async function build() {
|
||||
const resultServer = await esbuild.build({
|
||||
entryPoints: ['src/index.ts'],
|
||||
bundle: true,
|
||||
platform: 'node',
|
||||
format: 'esm',
|
||||
outfile: 'dist/index.js',
|
||||
splitting: false,
|
||||
external: [
|
||||
'*.scss',
|
||||
'*.css',
|
||||
'drizzle-kit',
|
||||
'libsql',
|
||||
'pg',
|
||||
'@payloadcms/translations',
|
||||
'@payloadcms/drizzle',
|
||||
'payload',
|
||||
'payload/*',
|
||||
],
|
||||
minify: true,
|
||||
metafile: true,
|
||||
tsconfig: path.resolve(dirname, './tsconfig.json'),
|
||||
plugins: [commonjs()],
|
||||
sourcemap: true,
|
||||
})
|
||||
console.log('db-sqlite bundled successfully')
|
||||
|
||||
fs.writeFileSync('meta_server.json', JSON.stringify(resultServer.metafile))
|
||||
}
|
||||
await build()
|
||||
134
packages/db-d1-sqlite/package.json
Normal file
134
packages/db-d1-sqlite/package.json
Normal file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"name": "@payloadcms/db-d1-sqlite",
|
||||
"version": "3.57.0",
|
||||
"description": "The officially supported D1 SQLite database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/payloadcms/payload.git",
|
||||
"directory": "packages/db-d1-sqlite"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Payload <dev@payloadcms.com> (https://payloadcms.com)",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Payload",
|
||||
"email": "info@payloadcms.com",
|
||||
"url": "https://payloadcms.com"
|
||||
}
|
||||
],
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./src/index.ts",
|
||||
"require": "./src/index.ts",
|
||||
"types": "./src/index.ts"
|
||||
},
|
||||
"./types": {
|
||||
"import": "./src/exports/types-deprecated.ts",
|
||||
"require": "./src/exports/types-deprecated.ts",
|
||||
"types": "./src/exports/types-deprecated.ts"
|
||||
},
|
||||
"./migration-utils": {
|
||||
"import": "./src/exports/migration-utils.ts",
|
||||
"require": "./src/exports/migration-utils.ts",
|
||||
"types": "./src/exports/migration-utils.ts"
|
||||
},
|
||||
"./drizzle": {
|
||||
"import": "./src/drizzle-proxy/index.ts",
|
||||
"types": "./src/drizzle-proxy/index.ts",
|
||||
"default": "./src/drizzle-proxy/index.ts"
|
||||
},
|
||||
"./drizzle/sqlite-core": {
|
||||
"import": "./src/drizzle-proxy/sqlite-core.ts",
|
||||
"types": "./src/drizzle-proxy/sqlite-core.ts",
|
||||
"default": "./src/drizzle-proxy/sqlite-core.ts"
|
||||
},
|
||||
"./drizzle/d1": {
|
||||
"import": "./src/drizzle-proxy/d1.ts",
|
||||
"types": "./src/drizzle-proxy/d1.ts",
|
||||
"default": "./src/drizzle-proxy/d1.ts"
|
||||
},
|
||||
"./drizzle/relations": {
|
||||
"import": "./src/drizzle-proxy/relations.ts",
|
||||
"types": "./src/drizzle-proxy/relations.ts",
|
||||
"default": "./src/drizzle-proxy/relations.ts"
|
||||
}
|
||||
},
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"mock.js"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm build:swc && pnpm build:types",
|
||||
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
||||
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
||||
"clean": "rimraf -g {dist,*.tsbuildinfo}",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"prepack": "pnpm clean && pnpm turbo build",
|
||||
"prepublishOnly": "pnpm clean && pnpm turbo build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@payloadcms/drizzle": "workspace:*",
|
||||
"console-table-printer": "2.12.1",
|
||||
"drizzle-kit": "0.31.4",
|
||||
"drizzle-orm": "0.44.2",
|
||||
"prompts": "2.4.2",
|
||||
"to-snake-case": "1.0.0",
|
||||
"uuid": "9.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@payloadcms/eslint-config": "workspace:*",
|
||||
"@types/pg": "8.10.2",
|
||||
"@types/to-snake-case": "1.0.0",
|
||||
"@types/uuid": "10.0.0",
|
||||
"payload": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"payload": "workspace:*"
|
||||
},
|
||||
"publishConfig": {
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"./types": {
|
||||
"import": "./dist/exports/types-deprecated.js",
|
||||
"require": "./dist/exports/types-deprecated.js",
|
||||
"types": "./dist/exports/types-deprecated.d.ts"
|
||||
},
|
||||
"./migration-utils": {
|
||||
"import": "./dist/exports/migration-utils.js",
|
||||
"require": "./dist/exports/migration-utils.js",
|
||||
"types": "./dist/exports/migration-utils.d.ts"
|
||||
},
|
||||
"./drizzle": {
|
||||
"import": "./dist/drizzle-proxy/index.js",
|
||||
"types": "./dist/drizzle-proxy/index.d.ts",
|
||||
"default": "./dist/drizzle-proxy/index.js"
|
||||
},
|
||||
"./drizzle/sqlite-core": {
|
||||
"import": "./dist/drizzle-proxy/sqlite-core.js",
|
||||
"types": "./dist/drizzle-proxy/sqlite-core.d.ts",
|
||||
"default": "./dist/drizzle-proxy/sqlite-core.js"
|
||||
},
|
||||
"./drizzle/d1": {
|
||||
"import": "./dist/drizzle-proxy/d1.js",
|
||||
"types": "./dist/drizzle-proxy/d1.d.ts",
|
||||
"default": "./dist/drizzle-proxy/d1.js"
|
||||
},
|
||||
"./drizzle/relations": {
|
||||
"import": "./dist/drizzle-proxy/relations.js",
|
||||
"types": "./dist/drizzle-proxy/relations.d.ts",
|
||||
"default": "./dist/drizzle-proxy/relations.js"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
}
|
||||
61
packages/db-d1-sqlite/src/connect.ts
Normal file
61
packages/db-d1-sqlite/src/connect.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import type { DrizzleAdapter } from '@payloadcms/drizzle'
|
||||
import type { Connect, Migration } from 'payload'
|
||||
|
||||
import { pushDevSchema } from '@payloadcms/drizzle'
|
||||
import { drizzle } from 'drizzle-orm/d1'
|
||||
|
||||
import type { SQLiteD1Adapter } from './types.js'
|
||||
|
||||
export const connect: Connect = async function connect(
|
||||
this: SQLiteD1Adapter,
|
||||
options = {
|
||||
hotReload: false,
|
||||
},
|
||||
) {
|
||||
const { hotReload } = options
|
||||
|
||||
this.schema = {
|
||||
...this.tables,
|
||||
...this.relations,
|
||||
}
|
||||
|
||||
try {
|
||||
const logger = this.logger || false
|
||||
|
||||
this.drizzle = drizzle(this.binding, { logger, schema: this.schema })
|
||||
this.client = this.drizzle.$client as any
|
||||
|
||||
if (!hotReload) {
|
||||
if (process.env.PAYLOAD_DROP_DATABASE === 'true') {
|
||||
this.payload.logger.info(`---- DROPPING TABLES ----`)
|
||||
await this.dropDatabase({ adapter: this })
|
||||
this.payload.logger.info('---- DROPPED TABLES ----')
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
this.payload.logger.error({ err, msg: `Error: cannot connect to SQLite: ${message}` })
|
||||
if (typeof this.rejectInitializing === 'function') {
|
||||
this.rejectInitializing()
|
||||
}
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Only push schema if not in production
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
process.env.PAYLOAD_MIGRATING !== 'true' &&
|
||||
this.push !== false
|
||||
) {
|
||||
await pushDevSchema(this as unknown as DrizzleAdapter)
|
||||
}
|
||||
|
||||
if (typeof this.resolveInitializing === 'function') {
|
||||
this.resolveInitializing()
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === 'production' && this.prodMigrations) {
|
||||
await this.migrate({ migrations: this.prodMigrations as Migration[] })
|
||||
}
|
||||
}
|
||||
1
packages/db-d1-sqlite/src/drizzle-proxy/d1.ts
Normal file
1
packages/db-d1-sqlite/src/drizzle-proxy/d1.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from 'drizzle-orm/d1'
|
||||
1
packages/db-d1-sqlite/src/drizzle-proxy/index.ts
Normal file
1
packages/db-d1-sqlite/src/drizzle-proxy/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from 'drizzle-orm'
|
||||
1
packages/db-d1-sqlite/src/drizzle-proxy/relations.ts
Normal file
1
packages/db-d1-sqlite/src/drizzle-proxy/relations.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from 'drizzle-orm/relations'
|
||||
1
packages/db-d1-sqlite/src/drizzle-proxy/sqlite-core.ts
Normal file
1
packages/db-d1-sqlite/src/drizzle-proxy/sqlite-core.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from 'drizzle-orm/sqlite-core'
|
||||
67
packages/db-d1-sqlite/src/execute.ts
Normal file
67
packages/db-d1-sqlite/src/execute.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { Execute } from '@payloadcms/drizzle'
|
||||
import type { SQLiteRaw } from 'drizzle-orm/sqlite-core/query-builders/raw'
|
||||
|
||||
import { sql } from 'drizzle-orm'
|
||||
|
||||
interface D1Meta {
|
||||
changed_db: boolean
|
||||
changes: number
|
||||
duration: number
|
||||
last_row_id: number
|
||||
rows_read: number
|
||||
rows_written: number
|
||||
/**
|
||||
* True if-and-only-if the database instance that executed the query was the primary.
|
||||
*/
|
||||
served_by_primary?: boolean
|
||||
/**
|
||||
* The region of the database instance that executed the query.
|
||||
*/
|
||||
served_by_region?: string
|
||||
size_after: number
|
||||
timings?: {
|
||||
/**
|
||||
* The duration of the SQL query execution by the database instance. It doesn't include any network time.
|
||||
*/
|
||||
sql_duration_ms: number
|
||||
}
|
||||
}
|
||||
|
||||
interface D1Response {
|
||||
error?: never
|
||||
meta: D1Meta & Record<string, unknown>
|
||||
success: true
|
||||
}
|
||||
|
||||
type D1Result<T = unknown> = {
|
||||
results: T[]
|
||||
} & D1Response
|
||||
|
||||
export const execute: Execute<any> = function execute({ db, drizzle, raw, sql: statement }) {
|
||||
const executeFrom: any = (db ?? drizzle)!
|
||||
const mapToLibSql = (query: SQLiteRaw<D1Result<unknown>>): any => {
|
||||
const execute = query.execute
|
||||
query.execute = async () => {
|
||||
const result: D1Result = await execute()
|
||||
const resultLibSQL = {
|
||||
columns: undefined,
|
||||
columnTypes: undefined,
|
||||
lastInsertRowid: BigInt(result.meta.last_row_id),
|
||||
rows: result.results as any[],
|
||||
rowsAffected: result.meta.rows_written,
|
||||
}
|
||||
|
||||
return Object.assign(result, resultLibSQL)
|
||||
}
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
if (raw) {
|
||||
const result = mapToLibSql(executeFrom.run(sql.raw(raw)))
|
||||
return result
|
||||
} else {
|
||||
const result = mapToLibSql(executeFrom.run(statement))
|
||||
return result
|
||||
}
|
||||
}
|
||||
79
packages/db-d1-sqlite/src/exports/types-deprecated.ts
Normal file
79
packages/db-d1-sqlite/src/exports/types-deprecated.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import type {
|
||||
Args as _Args,
|
||||
CountDistinct as _CountDistinct,
|
||||
DeleteWhere as _DeleteWhere,
|
||||
DropDatabase as _DropDatabase,
|
||||
Execute as _Execute,
|
||||
GeneratedDatabaseSchema as _GeneratedDatabaseSchema,
|
||||
GenericColumns as _GenericColumns,
|
||||
GenericRelation as _GenericRelation,
|
||||
GenericTable as _GenericTable,
|
||||
IDType as _IDType,
|
||||
Insert as _Insert,
|
||||
MigrateDownArgs as _MigrateDownArgs,
|
||||
MigrateUpArgs as _MigrateUpArgs,
|
||||
SQLiteD1Adapter as _SQLiteAdapter,
|
||||
SQLiteSchemaHook as _SQLiteSchemaHook,
|
||||
} from '../types.js'
|
||||
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type SQLiteAdapter = _SQLiteAdapter
|
||||
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type Args = _Args
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type CountDistinct = _CountDistinct
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type DeleteWhere = _DeleteWhere
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type DropDatabase = _DropDatabase
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type Execute<T> = _Execute<T>
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type GeneratedDatabaseSchema = _GeneratedDatabaseSchema
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type GenericColumns = _GenericColumns
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type GenericRelation = _GenericRelation
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type GenericTable = _GenericTable
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type IDType = _IDType
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type Insert = _Insert
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type MigrateDownArgs = _MigrateDownArgs
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type MigrateUpArgs = _MigrateUpArgs
|
||||
/**
|
||||
* @deprecated - import from `@payloadcms/db-sqlite` instead
|
||||
*/
|
||||
export type SQLiteSchemaHook = _SQLiteSchemaHook
|
||||
223
packages/db-d1-sqlite/src/index.ts
Normal file
223
packages/db-d1-sqlite/src/index.ts
Normal file
@@ -0,0 +1,223 @@
|
||||
import type { Operators } from '@payloadcms/drizzle'
|
||||
import type { DatabaseAdapterObj, Payload } from 'payload'
|
||||
|
||||
import {
|
||||
beginTransaction,
|
||||
buildCreateMigration,
|
||||
commitTransaction,
|
||||
count,
|
||||
countGlobalVersions,
|
||||
countVersions,
|
||||
create,
|
||||
createGlobal,
|
||||
createGlobalVersion,
|
||||
createSchemaGenerator,
|
||||
createVersion,
|
||||
deleteMany,
|
||||
deleteOne,
|
||||
deleteVersions,
|
||||
destroy,
|
||||
find,
|
||||
findGlobal,
|
||||
findGlobalVersions,
|
||||
findMigrationDir,
|
||||
findOne,
|
||||
findVersions,
|
||||
migrate,
|
||||
migrateDown,
|
||||
migrateFresh,
|
||||
migrateRefresh,
|
||||
migrateReset,
|
||||
migrateStatus,
|
||||
operatorMap,
|
||||
queryDrafts,
|
||||
rollbackTransaction,
|
||||
updateGlobal,
|
||||
updateGlobalVersion,
|
||||
updateJobs,
|
||||
updateMany,
|
||||
updateOne,
|
||||
updateVersion,
|
||||
} from '@payloadcms/drizzle'
|
||||
import {
|
||||
columnToCodeConverter,
|
||||
convertPathToJSONTraversal,
|
||||
countDistinct,
|
||||
createJSONQuery,
|
||||
defaultDrizzleSnapshot,
|
||||
deleteWhere,
|
||||
dropDatabase,
|
||||
init,
|
||||
insert,
|
||||
requireDrizzleKit,
|
||||
} from '@payloadcms/drizzle/sqlite'
|
||||
import { like, notLike } from 'drizzle-orm'
|
||||
import { createDatabaseAdapter, defaultBeginTransaction } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Args, SQLiteD1Adapter } from './types.js'
|
||||
|
||||
import { connect } from './connect.js'
|
||||
import { execute } from './execute.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
|
||||
export function sqliteD1Adapter(args: Args): DatabaseAdapterObj<SQLiteD1Adapter> {
|
||||
const sqliteIDType = args.idType || 'number'
|
||||
const payloadIDType = sqliteIDType === 'uuid' ? 'text' : 'number'
|
||||
const allowIDOnCreate = args.allowIDOnCreate ?? false
|
||||
|
||||
function adapter({ payload }: { payload: Payload }) {
|
||||
const migrationDir = findMigrationDir(args.migrationDir)
|
||||
let resolveInitializing: () => void = () => {}
|
||||
let rejectInitializing: () => void = () => {}
|
||||
|
||||
const initializing = new Promise<void>((res, rej) => {
|
||||
resolveInitializing = res
|
||||
rejectInitializing = rej
|
||||
})
|
||||
|
||||
// sqlite's like operator is case-insensitive, so we overwrite the DrizzleAdapter operators to not use ilike
|
||||
const operators = {
|
||||
...operatorMap,
|
||||
contains: like,
|
||||
like,
|
||||
not_like: notLike,
|
||||
} as unknown as Operators
|
||||
|
||||
return createDatabaseAdapter<SQLiteD1Adapter>({
|
||||
name: 'sqlite',
|
||||
afterSchemaInit: args.afterSchemaInit ?? [],
|
||||
allowIDOnCreate,
|
||||
autoIncrement: args.autoIncrement ?? false,
|
||||
beforeSchemaInit: args.beforeSchemaInit ?? [],
|
||||
binding: args.binding,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
client: undefined,
|
||||
defaultDrizzleSnapshot,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
drizzle: undefined,
|
||||
features: {
|
||||
json: true,
|
||||
},
|
||||
fieldConstraints: {},
|
||||
generateSchema: createSchemaGenerator({
|
||||
columnToCodeConverter,
|
||||
corePackageSuffix: 'sqlite-core',
|
||||
defaultOutputFile: args.generateSchemaOutputFile,
|
||||
tableImport: 'sqliteTable',
|
||||
}),
|
||||
idType: sqliteIDType,
|
||||
initializing,
|
||||
localesSuffix: args.localesSuffix || '_locales',
|
||||
logger: args.logger,
|
||||
operators,
|
||||
prodMigrations: args.prodMigrations,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
push: args.push,
|
||||
rawRelations: {},
|
||||
rawTables: {},
|
||||
relations: {},
|
||||
relationshipsSuffix: args.relationshipsSuffix || '_rels',
|
||||
schema: {},
|
||||
schemaName: args.schemaName,
|
||||
sessions: {},
|
||||
tableNameMap: new Map<string, string>(),
|
||||
tables: {},
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
execute,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
transactionOptions: args.transactionOptions || undefined,
|
||||
updateJobs,
|
||||
updateMany,
|
||||
versionsSuffix: args.versionsSuffix || '_v',
|
||||
// DatabaseAdapter
|
||||
beginTransaction: args.transactionOptions ? beginTransaction : defaultBeginTransaction(),
|
||||
commitTransaction,
|
||||
connect,
|
||||
convertPathToJSONTraversal,
|
||||
count,
|
||||
countDistinct,
|
||||
countGlobalVersions,
|
||||
countVersions,
|
||||
create,
|
||||
createGlobal,
|
||||
createGlobalVersion,
|
||||
createJSONQuery,
|
||||
createMigration: buildCreateMigration({
|
||||
executeMethod: 'run',
|
||||
filename,
|
||||
sanitizeStatements({ sqlExecute, statements }) {
|
||||
return statements
|
||||
.map((statement) => `${sqlExecute}${statement?.replaceAll('`', '\\`')}\`)`)
|
||||
.join('\n')
|
||||
},
|
||||
}),
|
||||
createVersion,
|
||||
defaultIDType: payloadIDType,
|
||||
deleteMany,
|
||||
deleteOne,
|
||||
deleteVersions,
|
||||
deleteWhere,
|
||||
destroy,
|
||||
dropDatabase,
|
||||
find,
|
||||
findGlobal,
|
||||
findGlobalVersions,
|
||||
findOne,
|
||||
findVersions,
|
||||
indexes: new Set<string>(),
|
||||
init,
|
||||
insert,
|
||||
migrate,
|
||||
migrateDown,
|
||||
migrateFresh,
|
||||
migrateRefresh,
|
||||
migrateReset,
|
||||
migrateStatus,
|
||||
migrationDir,
|
||||
packageName: '@payloadcms/db-d1-sqlite',
|
||||
payload,
|
||||
queryDrafts,
|
||||
rejectInitializing,
|
||||
requireDrizzleKit,
|
||||
resolveInitializing,
|
||||
rollbackTransaction,
|
||||
updateGlobal,
|
||||
updateGlobalVersion,
|
||||
updateOne,
|
||||
updateVersion,
|
||||
upsert: updateOne,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'd1-sqlite',
|
||||
allowIDOnCreate,
|
||||
defaultIDType: payloadIDType,
|
||||
init: adapter,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo deprecate /types subpath export in 4.0
|
||||
*/
|
||||
export type {
|
||||
Args as SQLiteAdapterArgs,
|
||||
CountDistinct,
|
||||
DeleteWhere,
|
||||
DropDatabase,
|
||||
Execute,
|
||||
GeneratedDatabaseSchema,
|
||||
GenericColumns,
|
||||
GenericRelation,
|
||||
GenericTable,
|
||||
IDType,
|
||||
Insert,
|
||||
MigrateDownArgs,
|
||||
MigrateUpArgs,
|
||||
SQLiteD1Adapter as SQLiteAdapter,
|
||||
SQLiteSchemaHook,
|
||||
} from './types.js'
|
||||
|
||||
export { sql } from 'drizzle-orm'
|
||||
199
packages/db-d1-sqlite/src/types.ts
Normal file
199
packages/db-d1-sqlite/src/types.ts
Normal file
@@ -0,0 +1,199 @@
|
||||
import type { ResultSet } from '@libsql/client'
|
||||
import type { BuildQueryJoinAliases, DrizzleAdapter, extendDrizzleTable } from '@payloadcms/drizzle'
|
||||
import type { BaseSQLiteAdapter, BaseSQLiteArgs } from '@payloadcms/drizzle/sqlite'
|
||||
import type { DrizzleConfig, Relation, Relations, SQL } from 'drizzle-orm'
|
||||
import type { AnyD1Database, DrizzleD1Database } from 'drizzle-orm/d1'
|
||||
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
||||
import type {
|
||||
AnySQLiteColumn,
|
||||
SQLiteInsertOnConflictDoUpdateConfig,
|
||||
SQLiteTableWithColumns,
|
||||
SQLiteTransactionConfig,
|
||||
} from 'drizzle-orm/sqlite-core'
|
||||
import type { SQLiteRaw } from 'drizzle-orm/sqlite-core/query-builders/raw'
|
||||
import type { Payload, PayloadRequest } from 'payload'
|
||||
|
||||
type SQLiteSchema = {
|
||||
relations: Record<string, GenericRelation>
|
||||
tables: Record<string, SQLiteTableWithColumns<any>>
|
||||
}
|
||||
|
||||
type SQLiteSchemaHookArgs = {
|
||||
extendTable: typeof extendDrizzleTable
|
||||
schema: SQLiteSchema
|
||||
}
|
||||
|
||||
export type SQLiteSchemaHook = (args: SQLiteSchemaHookArgs) => Promise<SQLiteSchema> | SQLiteSchema
|
||||
|
||||
export type Args = {
|
||||
binding: AnyD1Database
|
||||
} & BaseSQLiteArgs
|
||||
|
||||
export type GenericColumns = {
|
||||
[x: string]: AnySQLiteColumn
|
||||
}
|
||||
|
||||
export type GenericTable = SQLiteTableWithColumns<{
|
||||
columns: GenericColumns
|
||||
dialect: string
|
||||
name: string
|
||||
schema: string
|
||||
}>
|
||||
|
||||
export type GenericRelation = Relations<string, Record<string, Relation<string>>>
|
||||
|
||||
export type CountDistinct = (args: {
|
||||
db: LibSQLDatabase
|
||||
joins: BuildQueryJoinAliases
|
||||
tableName: string
|
||||
where: SQL
|
||||
}) => Promise<number>
|
||||
|
||||
export type DeleteWhere = (args: {
|
||||
db: LibSQLDatabase
|
||||
tableName: string
|
||||
where: SQL
|
||||
}) => Promise<void>
|
||||
|
||||
export type DropDatabase = (args: { adapter: SQLiteD1Adapter }) => Promise<void>
|
||||
|
||||
export type Execute<T> = (args: {
|
||||
db?: LibSQLDatabase
|
||||
drizzle?: LibSQLDatabase
|
||||
raw?: string
|
||||
sql?: SQL<unknown>
|
||||
}) => SQLiteRaw<Promise<T>> | SQLiteRaw<ResultSet>
|
||||
|
||||
export type Insert = (args: {
|
||||
db: LibSQLDatabase
|
||||
onConflictDoUpdate?: SQLiteInsertOnConflictDoUpdateConfig<any>
|
||||
tableName: string
|
||||
values: Record<string, unknown> | Record<string, unknown>[]
|
||||
}) => Promise<Record<string, unknown>[]>
|
||||
|
||||
// Explicitly omit drizzle property for complete override in SQLiteAdapter, required in ts 5.5
|
||||
type SQLiteDrizzleAdapter = Omit<
|
||||
DrizzleAdapter,
|
||||
| 'countDistinct'
|
||||
| 'deleteWhere'
|
||||
| 'drizzle'
|
||||
| 'dropDatabase'
|
||||
| 'execute'
|
||||
| 'idType'
|
||||
| 'insert'
|
||||
| 'operators'
|
||||
| 'relations'
|
||||
>
|
||||
|
||||
export interface GeneratedDatabaseSchema {
|
||||
schemaUntyped: Record<string, unknown>
|
||||
}
|
||||
|
||||
type ResolveSchemaType<T> = 'schema' extends keyof T
|
||||
? T['schema']
|
||||
: GeneratedDatabaseSchema['schemaUntyped']
|
||||
|
||||
type Drizzle = { $client: AnyD1Database } & DrizzleD1Database<Record<string, any>>
|
||||
|
||||
export type SQLiteD1Adapter = {
|
||||
binding: Args['binding']
|
||||
client: AnyD1Database
|
||||
drizzle: Drizzle
|
||||
} & BaseSQLiteAdapter &
|
||||
SQLiteDrizzleAdapter
|
||||
|
||||
export type IDType = 'integer' | 'numeric' | 'text'
|
||||
|
||||
export type MigrateUpArgs = {
|
||||
/**
|
||||
* The SQLite Drizzle instance that you can use to execute SQL directly within the current transaction.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateUpArgs, sql } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
* const { rows: posts } = await db.run(sql`SELECT * FROM posts`)
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
db: Drizzle
|
||||
/**
|
||||
* The Payload instance that you can use to execute Local API methods
|
||||
* To use the current transaction you must pass `req` to arguments
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateUpArgs } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
* const posts = await payload.find({ collection: 'posts', req })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
payload: Payload
|
||||
/**
|
||||
* The `PayloadRequest` object that contains the current transaction
|
||||
*/
|
||||
req: PayloadRequest
|
||||
}
|
||||
export type MigrateDownArgs = {
|
||||
/**
|
||||
* The SQLite Drizzle instance that you can use to execute SQL directly within the current transaction.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateDownArgs, sql } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
* const { rows: posts } = await db.run(sql`SELECT * FROM posts`)
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
db: Drizzle
|
||||
/**
|
||||
* The Payload instance that you can use to execute Local API methods
|
||||
* To use the current transaction you must pass `req` to arguments
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateDownArgs } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
* const posts = await payload.find({ collection: 'posts', req })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
payload: Payload
|
||||
/**
|
||||
* The `PayloadRequest` object that contains the current transaction
|
||||
*/
|
||||
req: PayloadRequest
|
||||
}
|
||||
|
||||
declare module 'payload' {
|
||||
export interface DatabaseAdapter
|
||||
extends Omit<Args, 'idType' | 'logger' | 'migrationDir' | 'pool'>,
|
||||
DrizzleAdapter {
|
||||
beginTransaction: (options?: SQLiteTransactionConfig) => Promise<null | number | string>
|
||||
drizzle: Drizzle
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
* Used for returning properly formed errors from unique fields
|
||||
*/
|
||||
fieldConstraints: Record<string, Record<string, string>>
|
||||
idType: Args['idType']
|
||||
initializing: Promise<void>
|
||||
localesSuffix?: string
|
||||
logger: DrizzleConfig['logger']
|
||||
prodMigrations?: {
|
||||
down: (args: MigrateDownArgs) => Promise<void>
|
||||
name: string
|
||||
up: (args: MigrateUpArgs) => Promise<void>
|
||||
}[]
|
||||
push: boolean
|
||||
rejectInitializing: () => void
|
||||
relationshipsSuffix?: string
|
||||
resolveInitializing: () => void
|
||||
schema: Record<string, GenericRelation | GenericTable>
|
||||
tableNameMap: Map<string, string>
|
||||
transactionOptions: SQLiteTransactionConfig
|
||||
versionsSuffix?: string
|
||||
}
|
||||
}
|
||||
14
packages/db-d1-sqlite/tsconfig.json
Normal file
14
packages/db-d1-sqlite/tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"references": [
|
||||
{
|
||||
"path": "../payload"
|
||||
},
|
||||
{
|
||||
"path": "../translations"
|
||||
},
|
||||
{
|
||||
"path": "../drizzle"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -180,8 +180,6 @@ export function postgresAdapter(args: Args): DatabaseAdapterObj<PostgresAdapter>
|
||||
find,
|
||||
findGlobal,
|
||||
findGlobalVersions,
|
||||
updateJobs,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
findOne,
|
||||
findVersions,
|
||||
indexes: new Set<string>(),
|
||||
@@ -199,6 +197,7 @@ export function postgresAdapter(args: Args): DatabaseAdapterObj<PostgresAdapter>
|
||||
queryDrafts,
|
||||
rawRelations: {},
|
||||
rawTables: {},
|
||||
updateJobs,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
rejectInitializing,
|
||||
requireDrizzleKit,
|
||||
|
||||
@@ -41,24 +41,26 @@ import {
|
||||
updateVersion,
|
||||
upsert,
|
||||
} from '@payloadcms/drizzle'
|
||||
import {
|
||||
columnToCodeConverter,
|
||||
convertPathToJSONTraversal,
|
||||
countDistinct,
|
||||
createJSONQuery,
|
||||
defaultDrizzleSnapshot,
|
||||
deleteWhere,
|
||||
dropDatabase,
|
||||
execute,
|
||||
init,
|
||||
insert,
|
||||
requireDrizzleKit,
|
||||
} from '@payloadcms/drizzle/sqlite'
|
||||
import { like, notLike } from 'drizzle-orm'
|
||||
import { createDatabaseAdapter, defaultBeginTransaction } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Args, SQLiteAdapter } from './types.js'
|
||||
|
||||
import { columnToCodeConverter } from './columnToCodeConverter.js'
|
||||
import { connect } from './connect.js'
|
||||
import { countDistinct } from './countDistinct.js'
|
||||
import { convertPathToJSONTraversal } from './createJSONQuery/convertPathToJSONTraversal.js'
|
||||
import { createJSONQuery } from './createJSONQuery/index.js'
|
||||
import { defaultDrizzleSnapshot } from './defaultSnapshot.js'
|
||||
import { deleteWhere } from './deleteWhere.js'
|
||||
import { dropDatabase } from './dropDatabase.js'
|
||||
import { execute } from './execute.js'
|
||||
import { init } from './init.js'
|
||||
import { insert } from './insert.js'
|
||||
import { requireDrizzleKit } from './requireDrizzleKit.js'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
|
||||
@@ -69,8 +71,8 @@ export function sqliteAdapter(args: Args): DatabaseAdapterObj<SQLiteAdapter> {
|
||||
|
||||
function adapter({ payload }: { payload: Payload }) {
|
||||
const migrationDir = findMigrationDir(args.migrationDir)
|
||||
let resolveInitializing
|
||||
let rejectInitializing
|
||||
let resolveInitializing: () => void = () => {}
|
||||
let rejectInitializing: () => void = () => {}
|
||||
|
||||
const initializing = new Promise<void>((res, rej) => {
|
||||
resolveInitializing = res
|
||||
@@ -131,7 +133,6 @@ export function sqliteAdapter(args: Args): DatabaseAdapterObj<SQLiteAdapter> {
|
||||
updateJobs,
|
||||
updateMany,
|
||||
versionsSuffix: args.versionsSuffix || '_v',
|
||||
|
||||
// DatabaseAdapter
|
||||
beginTransaction: args.transactionOptions ? beginTransaction : defaultBeginTransaction(),
|
||||
commitTransaction,
|
||||
@@ -166,7 +167,6 @@ export function sqliteAdapter(args: Args): DatabaseAdapterObj<SQLiteAdapter> {
|
||||
find,
|
||||
findGlobal,
|
||||
findGlobalVersions,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
findOne,
|
||||
findVersions,
|
||||
indexes: new Set<string>(),
|
||||
@@ -182,10 +182,8 @@ export function sqliteAdapter(args: Args): DatabaseAdapterObj<SQLiteAdapter> {
|
||||
packageName: '@payloadcms/db-sqlite',
|
||||
payload,
|
||||
queryDrafts,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
rejectInitializing,
|
||||
requireDrizzleKit,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
resolveInitializing,
|
||||
rollbackTransaction,
|
||||
updateGlobal,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Client, Config, ResultSet } from '@libsql/client'
|
||||
import type { extendDrizzleTable, Operators } from '@payloadcms/drizzle'
|
||||
import type { BaseSQLiteAdapter, BaseSQLiteArgs } from '@payloadcms/drizzle/sqlite'
|
||||
import type { BuildQueryJoinAliases, DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { DrizzleConfig, Relation, Relations, SQL } from 'drizzle-orm'
|
||||
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
||||
@@ -56,23 +57,7 @@ export type Args = {
|
||||
*/
|
||||
blocksAsJSON?: boolean
|
||||
client: Config
|
||||
/** Generated schema from payload generate:db-schema file path */
|
||||
generateSchemaOutputFile?: string
|
||||
idType?: 'number' | 'uuid'
|
||||
localesSuffix?: string
|
||||
logger?: DrizzleConfig['logger']
|
||||
migrationDir?: string
|
||||
prodMigrations?: {
|
||||
down: (args: MigrateDownArgs) => Promise<void>
|
||||
name: string
|
||||
up: (args: MigrateUpArgs) => Promise<void>
|
||||
}[]
|
||||
push?: boolean
|
||||
relationshipsSuffix?: string
|
||||
schemaName?: string
|
||||
transactionOptions?: false | SQLiteTransactionConfig
|
||||
versionsSuffix?: string
|
||||
}
|
||||
} & BaseSQLiteArgs
|
||||
|
||||
export type GenericColumns = {
|
||||
[x: string]: AnySQLiteColumn
|
||||
@@ -142,45 +127,11 @@ type ResolveSchemaType<T> = 'schema' extends keyof T
|
||||
type Drizzle = { $client: Client } & LibSQLDatabase<ResolveSchemaType<GeneratedDatabaseSchema>>
|
||||
|
||||
export type SQLiteAdapter = {
|
||||
afterSchemaInit: SQLiteSchemaHook[]
|
||||
autoIncrement: boolean
|
||||
beforeSchemaInit: SQLiteSchemaHook[]
|
||||
client: Client
|
||||
clientConfig: Args['client']
|
||||
countDistinct: CountDistinct
|
||||
defaultDrizzleSnapshot: any
|
||||
deleteWhere: DeleteWhere
|
||||
drizzle: Drizzle
|
||||
dropDatabase: DropDatabase
|
||||
execute: Execute<unknown>
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
* Used for returning properly formed errors from unique fields
|
||||
*/
|
||||
fieldConstraints: Record<string, Record<string, string>>
|
||||
idType: Args['idType']
|
||||
initializing: Promise<void>
|
||||
insert: Insert
|
||||
localesSuffix?: string
|
||||
logger: DrizzleConfig['logger']
|
||||
operators: Operators
|
||||
prodMigrations?: {
|
||||
down: (args: MigrateDownArgs) => Promise<void>
|
||||
name: string
|
||||
up: (args: MigrateUpArgs) => Promise<void>
|
||||
}[]
|
||||
push: boolean
|
||||
rejectInitializing: () => void
|
||||
relations: Record<string, GenericRelation>
|
||||
relationshipsSuffix?: string
|
||||
resolveInitializing: () => void
|
||||
schema: Record<string, GenericRelation | GenericTable>
|
||||
schemaName?: Args['schemaName']
|
||||
tableNameMap: Map<string, string>
|
||||
tables: Record<string, GenericTable>
|
||||
transactionOptions: SQLiteTransactionConfig
|
||||
versionsSuffix?: string
|
||||
} & SQLiteDrizzleAdapter
|
||||
} & BaseSQLiteAdapter &
|
||||
SQLiteDrizzleAdapter
|
||||
|
||||
export type IDType = 'integer' | 'numeric' | 'text'
|
||||
|
||||
|
||||
@@ -178,8 +178,6 @@ export function vercelPostgresAdapter(args: Args = {}): DatabaseAdapterObj<Verce
|
||||
findDistinct,
|
||||
findGlobal,
|
||||
findGlobalVersions,
|
||||
readReplicaOptions: args.readReplicas,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
findOne,
|
||||
findVersions,
|
||||
init,
|
||||
@@ -194,6 +192,7 @@ export function vercelPostgresAdapter(args: Args = {}): DatabaseAdapterObj<Verce
|
||||
packageName: '@payloadcms/db-vercel-postgres',
|
||||
payload,
|
||||
queryDrafts,
|
||||
readReplicaOptions: args.readReplicas,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
rejectInitializing,
|
||||
requireDrizzleKit,
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
"types": "./src/exports/postgres.ts",
|
||||
"default": "./src/exports/postgres.ts"
|
||||
},
|
||||
"./sqlite": {
|
||||
"import": "./src/exports/sqlite.ts",
|
||||
"types": "./src/exports/sqlite.ts",
|
||||
"default": "./src/exports/sqlite.ts"
|
||||
},
|
||||
"./types": {
|
||||
"import": "./src/exports/types-deprecated.ts",
|
||||
"types": "./src/exports/types-deprecated.ts",
|
||||
@@ -82,6 +87,11 @@
|
||||
"types": "./dist/exports/postgres.d.ts",
|
||||
"default": "./dist/exports/postgres.js"
|
||||
},
|
||||
"./sqlite": {
|
||||
"import": "./dist/exports/sqlite.js",
|
||||
"types": "./dist/exports/sqlite.d.ts",
|
||||
"default": "./dist/exports/sqlite.js"
|
||||
},
|
||||
"./types": {
|
||||
"import": "./dist/exports/types-deprecated.js",
|
||||
"types": "./dist/exports/types-deprecated.d.ts",
|
||||
|
||||
@@ -23,7 +23,7 @@ export async function createGlobalVersion<T extends TypeWithID>(
|
||||
updatedAt,
|
||||
versionData,
|
||||
}: CreateGlobalVersionArgs,
|
||||
) {
|
||||
): Promise<TypeWithVersion<T>> {
|
||||
const db = await getTransaction(this, req)
|
||||
const global = this.payload.globals.config.find(({ slug }) => slug === globalSlug)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function createVersion<T extends TypeWithID>(
|
||||
updatedAt,
|
||||
versionData,
|
||||
}: CreateVersionArgs<T>,
|
||||
) {
|
||||
): Promise<TypeWithVersion<T>> {
|
||||
const db = await getTransaction(this, req)
|
||||
const collection = this.payload.collections[collectionSlug].config
|
||||
const defaultTableName = toSnakeCase(collection.slug)
|
||||
|
||||
12
packages/drizzle/src/exports/sqlite.ts
Normal file
12
packages/drizzle/src/exports/sqlite.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export { columnToCodeConverter } from '../sqlite/columnToCodeConverter.js'
|
||||
export { countDistinct } from '../sqlite/countDistinct.js'
|
||||
export { convertPathToJSONTraversal } from '../sqlite/createJSONQuery/convertPathToJSONTraversal.js'
|
||||
export { createJSONQuery } from '../sqlite/createJSONQuery/index.js'
|
||||
export { defaultDrizzleSnapshot } from '../sqlite/defaultSnapshot.js'
|
||||
export { deleteWhere } from '../sqlite/deleteWhere.js'
|
||||
export { dropDatabase } from '../sqlite/dropDatabase.js'
|
||||
export { execute } from '../sqlite/execute.js'
|
||||
export { init } from '../sqlite/init.js'
|
||||
export { insert } from '../sqlite/insert.js'
|
||||
export { requireDrizzleKit } from '../sqlite/requireDrizzleKit.js'
|
||||
export * from '../sqlite/types.js'
|
||||
@@ -9,7 +9,7 @@ import { findMany } from './find/findMany.js'
|
||||
export async function findOne<T extends TypeWithID>(
|
||||
this: DrizzleAdapter,
|
||||
{ collection, draftsEnabled, joins, locale, req, select, where }: FindOneArgs,
|
||||
): Promise<T> {
|
||||
): Promise<null | T> {
|
||||
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
|
||||
|
||||
const tableName = this.tableNameMap.get(toSnakeCase(collectionConfig.slug))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ColumnToCodeConverter } from '@payloadcms/drizzle/types'
|
||||
import type { ColumnToCodeConverter } from '../types.js'
|
||||
|
||||
export const columnToCodeConverter: ColumnToCodeConverter = ({
|
||||
adapter,
|
||||
@@ -2,10 +2,10 @@ import type { SQLiteSelect } from 'drizzle-orm/sqlite-core'
|
||||
|
||||
import { count, sql } from 'drizzle-orm'
|
||||
|
||||
import type { CountDistinct, SQLiteAdapter } from './types.js'
|
||||
import type { BaseSQLiteAdapter, CountDistinct } from './types.js'
|
||||
|
||||
export const countDistinct: CountDistinct = async function countDistinct(
|
||||
this: SQLiteAdapter,
|
||||
this: BaseSQLiteAdapter,
|
||||
{ column, db, joins, tableName, where },
|
||||
) {
|
||||
// When we don't have any joins - use a simple COUNT(*) query.
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { CreateJSONQueryArgs } from '@payloadcms/drizzle/types'
|
||||
import type { CreateJSONQueryArgs } from '../../types.js'
|
||||
|
||||
type FromArrayArgs = {
|
||||
isRoot?: true
|
||||
@@ -122,7 +122,7 @@ export const createJSONQuery = ({
|
||||
return sql
|
||||
}
|
||||
|
||||
if (treatAsArray?.includes(pathSegments[1]!) && table) {
|
||||
if (treatAsArray?.includes(pathSegments[1]) && table) {
|
||||
return fromArray({
|
||||
operator,
|
||||
pathSegments,
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { DeleteWhere, SQLiteAdapter } from './types.js'
|
||||
import type { BaseSQLiteAdapter, DeleteWhere } from './types.js'
|
||||
|
||||
export const deleteWhere: DeleteWhere = async function (
|
||||
// Here 'this' is not a parameter. See:
|
||||
// https://www.typescriptlang.org/docs/handbook/2/classes.html#this-parameters
|
||||
this: SQLiteAdapter,
|
||||
this: BaseSQLiteAdapter,
|
||||
{ db, tableName, where },
|
||||
) {
|
||||
const table = this.tables[tableName]
|
||||
@@ -1,15 +1,15 @@
|
||||
import type { Row } from '@libsql/client'
|
||||
|
||||
import type { DropDatabase, SQLiteAdapter } from './types.js'
|
||||
import type { BaseSQLiteAdapter, DropDatabase } from './types.js'
|
||||
|
||||
const getTables = (adapter: SQLiteAdapter) => {
|
||||
const getTables = (adapter: BaseSQLiteAdapter) => {
|
||||
return adapter.client.execute(`SELECT name
|
||||
FROM sqlite_master
|
||||
WHERE type = 'table'
|
||||
AND name NOT LIKE 'sqlite_%';`)
|
||||
}
|
||||
|
||||
const dropTables = (adapter: SQLiteAdapter, rows: Row[]) => {
|
||||
const dropTables = (adapter: BaseSQLiteAdapter, rows: Row[]) => {
|
||||
const multi = `
|
||||
PRAGMA foreign_keys = OFF;\n
|
||||
${rows.map(({ name }) => `DROP TABLE IF EXISTS ${name as string}`).join(';\n ')};\n
|
||||
@@ -3,13 +3,13 @@ import { sql } from 'drizzle-orm'
|
||||
import type { Execute } from './types.js'
|
||||
|
||||
export const execute: Execute<any> = function execute({ db, drizzle, raw, sql: statement }) {
|
||||
const executeFrom = (db ?? drizzle)!
|
||||
const executeFrom = (db ?? drizzle)
|
||||
|
||||
if (raw) {
|
||||
const result = executeFrom.run(sql.raw(raw))
|
||||
return result
|
||||
} else {
|
||||
const result = executeFrom.run(statement!)
|
||||
const result = executeFrom.run(statement)
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
import type { DrizzleAdapter } from '@payloadcms/drizzle/types'
|
||||
import type { Init } from 'payload'
|
||||
|
||||
import { buildDrizzleRelations, buildRawSchema, executeSchemaHooks } from '@payloadcms/drizzle'
|
||||
|
||||
import type { SQLiteAdapter } from './types.js'
|
||||
import type { DrizzleAdapter } from '../types.js'
|
||||
import type { BaseSQLiteAdapter } from './types.js'
|
||||
|
||||
import { buildDrizzleRelations } from '../schema/buildDrizzleRelations.js'
|
||||
import { buildRawSchema } from '../schema/buildRawSchema.js'
|
||||
import { executeSchemaHooks } from '../utilities/executeSchemaHooks.js'
|
||||
import { buildDrizzleTable } from './schema/buildDrizzleTable.js'
|
||||
import { setColumnID } from './schema/setColumnID.js'
|
||||
|
||||
export const init: Init = async function init(this: SQLiteAdapter) {
|
||||
export const init: Init = async function init(this: BaseSQLiteAdapter) {
|
||||
let locales: string[] | undefined
|
||||
|
||||
this.rawRelations = {}
|
||||
@@ -28,7 +29,7 @@ export const init: Init = async function init(this: SQLiteAdapter) {
|
||||
await executeSchemaHooks({ type: 'beforeSchemaInit', adapter: this })
|
||||
|
||||
for (const tableName in this.rawTables) {
|
||||
buildDrizzleTable({ adapter, locales: locales!, rawTable: this.rawTables[tableName]! })
|
||||
buildDrizzleTable({ adapter, locales, rawTable: this.rawTables[tableName] })
|
||||
}
|
||||
|
||||
buildDrizzleRelations({
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Insert, SQLiteAdapter } from './types.js'
|
||||
import type { BaseSQLiteAdapter, Insert } from './types.js'
|
||||
|
||||
export const insert: Insert = async function (
|
||||
// Here 'this' is not a parameter. See:
|
||||
// https://www.typescriptlang.org/docs/handbook/2/classes.html#this-parameters
|
||||
this: SQLiteAdapter,
|
||||
this: BaseSQLiteAdapter,
|
||||
{ db, onConflictDoUpdate, tableName, values },
|
||||
): Promise<Record<string, unknown>[]> {
|
||||
const table = this.tables[tableName]
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { RequireDrizzleKit } from '@payloadcms/drizzle/types'
|
||||
|
||||
import { createRequire } from 'module'
|
||||
|
||||
import type { RequireDrizzleKit } from '../types.js'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
|
||||
export const requireDrizzleKit: RequireDrizzleKit = () => {
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { BuildDrizzleTable, RawColumn } from '@payloadcms/drizzle/types'
|
||||
import type { ForeignKeyBuilder, IndexBuilder } from 'drizzle-orm/sqlite-core'
|
||||
|
||||
import { sql } from 'drizzle-orm'
|
||||
@@ -13,6 +12,8 @@ import {
|
||||
} from 'drizzle-orm/sqlite-core'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
import type { BuildDrizzleTable, RawColumn } from '../../types.js'
|
||||
|
||||
const rawColumnBuilderMap: Partial<Record<RawColumn['type'], any>> = {
|
||||
integer,
|
||||
numeric,
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { SetColumnID } from '@payloadcms/drizzle/types'
|
||||
|
||||
import type { SQLiteAdapter } from '../types.js'
|
||||
import type { SetColumnID } from '../../types.js'
|
||||
import type { BaseSQLiteAdapter } from '../types.js'
|
||||
|
||||
export const setColumnID: SetColumnID = ({ adapter, columns, fields }) => {
|
||||
const idField = fields.find((field) => field.name === 'id')
|
||||
@@ -38,7 +37,7 @@ export const setColumnID: SetColumnID = ({ adapter, columns, fields }) => {
|
||||
columns.id = {
|
||||
name: 'id',
|
||||
type: 'integer',
|
||||
autoIncrement: (adapter as unknown as SQLiteAdapter).autoIncrement,
|
||||
autoIncrement: (adapter as unknown as BaseSQLiteAdapter).autoIncrement,
|
||||
primaryKey: true,
|
||||
}
|
||||
|
||||
244
packages/drizzle/src/sqlite/types.ts
Normal file
244
packages/drizzle/src/sqlite/types.ts
Normal file
@@ -0,0 +1,244 @@
|
||||
import type { Client, ResultSet } from '@libsql/client'
|
||||
import type { DrizzleConfig, Relation, Relations, SQL } from 'drizzle-orm'
|
||||
import type { DrizzleD1Database } from 'drizzle-orm/d1'
|
||||
import type { LibSQLDatabase } from 'drizzle-orm/libsql'
|
||||
import type {
|
||||
AnySQLiteColumn,
|
||||
SQLiteColumn,
|
||||
SQLiteInsertOnConflictDoUpdateConfig,
|
||||
SQLiteTableWithColumns,
|
||||
SQLiteTransactionConfig,
|
||||
} from 'drizzle-orm/sqlite-core'
|
||||
import type { SQLiteRaw } from 'drizzle-orm/sqlite-core/query-builders/raw'
|
||||
import type { Payload, PayloadRequest } from 'payload'
|
||||
|
||||
import type { Operators } from '../queries/operatorMap.js'
|
||||
import type { BuildQueryJoinAliases, DrizzleAdapter } from '../types.js'
|
||||
import type { extendDrizzleTable } from '../utilities/extendDrizzleTable.js'
|
||||
|
||||
type SQLiteSchema = {
|
||||
relations: Record<string, GenericRelation>
|
||||
tables: Record<string, SQLiteTableWithColumns<any>>
|
||||
}
|
||||
|
||||
type SQLiteSchemaHookArgs = {
|
||||
extendTable: typeof extendDrizzleTable
|
||||
schema: SQLiteSchema
|
||||
}
|
||||
|
||||
export type SQLiteSchemaHook = (args: SQLiteSchemaHookArgs) => Promise<SQLiteSchema> | SQLiteSchema
|
||||
|
||||
export type BaseSQLiteArgs = {
|
||||
/**
|
||||
* Transform the schema after it's built.
|
||||
* You can use it to customize the schema with features that aren't supported by Payload.
|
||||
* Examples may include: composite indices, generated columns, vectors
|
||||
*/
|
||||
afterSchemaInit?: SQLiteSchemaHook[]
|
||||
/**
|
||||
* Enable this flag if you want to thread your own ID to create operation data, for example:
|
||||
* ```ts
|
||||
* // doc created with id 1
|
||||
* const doc = await payload.create({ collection: 'posts', data: {id: 1, title: "my title"}})
|
||||
* ```
|
||||
*/
|
||||
allowIDOnCreate?: boolean
|
||||
/**
|
||||
* Enable [AUTOINCREMENT](https://www.sqlite.org/autoinc.html) for Primary Keys.
|
||||
* This ensures that the same ID cannot be reused from previously deleted rows.
|
||||
*/
|
||||
autoIncrement?: boolean
|
||||
/**
|
||||
* Transform the schema before it's built.
|
||||
* You can use it to preserve an existing database schema and if there are any collissions Payload will override them.
|
||||
* To generate Drizzle schema from the database, see [Drizzle Kit introspection](https://orm.drizzle.team/kit-docs/commands#introspect--pull)
|
||||
*/
|
||||
beforeSchemaInit?: SQLiteSchemaHook[]
|
||||
/** Generated schema from payload generate:db-schema file path */
|
||||
generateSchemaOutputFile?: string
|
||||
idType?: 'number' | 'uuid'
|
||||
localesSuffix?: string
|
||||
logger?: DrizzleConfig['logger']
|
||||
migrationDir?: string
|
||||
prodMigrations?: {
|
||||
down: (args: MigrateDownArgs) => Promise<void>
|
||||
name: string
|
||||
up: (args: MigrateUpArgs) => Promise<void>
|
||||
}[]
|
||||
push?: boolean
|
||||
relationshipsSuffix?: string
|
||||
schemaName?: string
|
||||
transactionOptions?: false | SQLiteTransactionConfig
|
||||
versionsSuffix?: string
|
||||
}
|
||||
|
||||
export type GenericColumns = {
|
||||
[x: string]: AnySQLiteColumn
|
||||
}
|
||||
|
||||
export type GenericTable = SQLiteTableWithColumns<{
|
||||
columns: GenericColumns
|
||||
dialect: string
|
||||
name: string
|
||||
schema: string
|
||||
}>
|
||||
|
||||
export type GenericRelation = Relations<string, Record<string, Relation<string>>>
|
||||
|
||||
export type CountDistinct = (args: {
|
||||
column?: SQLiteColumn<any>
|
||||
db: LibSQLDatabase
|
||||
joins: BuildQueryJoinAliases
|
||||
tableName: string
|
||||
where: SQL
|
||||
}) => Promise<number>
|
||||
|
||||
export type DeleteWhere = (args: {
|
||||
db: LibSQLDatabase
|
||||
tableName: string
|
||||
where: SQL
|
||||
}) => Promise<void>
|
||||
|
||||
export type DropDatabase = (args: { adapter: BaseSQLiteAdapter }) => Promise<void>
|
||||
|
||||
export type Execute<T> = (args: {
|
||||
db?: DrizzleD1Database | LibSQLDatabase
|
||||
drizzle?: DrizzleD1Database | LibSQLDatabase
|
||||
raw?: string
|
||||
sql?: SQL<unknown>
|
||||
}) => SQLiteRaw<Promise<T>> | SQLiteRaw<ResultSet>
|
||||
|
||||
export type Insert = (args: {
|
||||
db: LibSQLDatabase
|
||||
onConflictDoUpdate?: SQLiteInsertOnConflictDoUpdateConfig<any>
|
||||
tableName: string
|
||||
values: Record<string, unknown> | Record<string, unknown>[]
|
||||
}) => Promise<Record<string, unknown>[]>
|
||||
|
||||
// Explicitly omit drizzle property for complete override in SQLiteAdapter, required in ts 5.5
|
||||
type SQLiteDrizzleAdapter = Omit<
|
||||
DrizzleAdapter,
|
||||
| 'countDistinct'
|
||||
| 'deleteWhere'
|
||||
| 'drizzle'
|
||||
| 'dropDatabase'
|
||||
| 'execute'
|
||||
| 'idType'
|
||||
| 'insert'
|
||||
| 'operators'
|
||||
| 'relations'
|
||||
>
|
||||
|
||||
export interface GeneratedDatabaseSchema {
|
||||
schemaUntyped: Record<string, unknown>
|
||||
}
|
||||
|
||||
type ResolveSchemaType<T> = 'schema' extends keyof T
|
||||
? T['schema']
|
||||
: GeneratedDatabaseSchema['schemaUntyped']
|
||||
|
||||
type Drizzle = { $client: Client } & LibSQLDatabase<ResolveSchemaType<GeneratedDatabaseSchema>>
|
||||
|
||||
export type BaseSQLiteAdapter = {
|
||||
afterSchemaInit: SQLiteSchemaHook[]
|
||||
autoIncrement: boolean
|
||||
beforeSchemaInit: SQLiteSchemaHook[]
|
||||
client: Client
|
||||
countDistinct: CountDistinct
|
||||
defaultDrizzleSnapshot: any
|
||||
deleteWhere: DeleteWhere
|
||||
dropDatabase: DropDatabase
|
||||
execute: Execute<unknown>
|
||||
/**
|
||||
* An object keyed on each table, with a key value pair where the constraint name is the key, followed by the dot-notation field name
|
||||
* Used for returning properly formed errors from unique fields
|
||||
*/
|
||||
fieldConstraints: Record<string, Record<string, string>>
|
||||
idType: BaseSQLiteArgs['idType']
|
||||
initializing: Promise<void>
|
||||
insert: Insert
|
||||
localesSuffix?: string
|
||||
logger: DrizzleConfig['logger']
|
||||
operators: Operators
|
||||
prodMigrations?: {
|
||||
down: (args: MigrateDownArgs) => Promise<void>
|
||||
name: string
|
||||
up: (args: MigrateUpArgs) => Promise<void>
|
||||
}[]
|
||||
push: boolean
|
||||
rejectInitializing: () => void
|
||||
relations: Record<string, GenericRelation>
|
||||
relationshipsSuffix?: string
|
||||
resolveInitializing: () => void
|
||||
schema: Record<string, GenericRelation | GenericTable>
|
||||
schemaName?: BaseSQLiteArgs['schemaName']
|
||||
tableNameMap: Map<string, string>
|
||||
tables: Record<string, GenericTable>
|
||||
transactionOptions: SQLiteTransactionConfig
|
||||
versionsSuffix?: string
|
||||
} & SQLiteDrizzleAdapter
|
||||
|
||||
export type IDType = 'integer' | 'numeric' | 'text'
|
||||
|
||||
export type MigrateUpArgs = {
|
||||
/**
|
||||
* The SQLite Drizzle instance that you can use to execute SQL directly within the current transaction.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateUpArgs, sql } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
* const { rows: posts } = await db.run(sql`SELECT * FROM posts`)
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
db: Drizzle
|
||||
/**
|
||||
* The Payload instance that you can use to execute Local API methods
|
||||
* To use the current transaction you must pass `req` to arguments
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateUpArgs } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
* const posts = await payload.find({ collection: 'posts', req })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
payload: Payload
|
||||
/**
|
||||
* The `PayloadRequest` object that contains the current transaction
|
||||
*/
|
||||
req: PayloadRequest
|
||||
}
|
||||
export type MigrateDownArgs = {
|
||||
/**
|
||||
* The SQLite Drizzle instance that you can use to execute SQL directly within the current transaction.
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateDownArgs, sql } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
* const { rows: posts } = await db.run(sql`SELECT * FROM posts`)
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
db: Drizzle
|
||||
/**
|
||||
* The Payload instance that you can use to execute Local API methods
|
||||
* To use the current transaction you must pass `req` to arguments
|
||||
* @example
|
||||
* ```ts
|
||||
* import { type MigrateDownArgs } from '@payloadcms/db-sqlite'
|
||||
*
|
||||
* export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
* const posts = await payload.find({ collection: 'posts', req })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
payload: Payload
|
||||
/**
|
||||
* The `PayloadRequest` object that contains the current transaction
|
||||
*/
|
||||
req: PayloadRequest
|
||||
}
|
||||
@@ -26,7 +26,7 @@ export async function updateGlobalVersion<T extends TypeWithID>(
|
||||
versionData,
|
||||
where: whereArg,
|
||||
}: UpdateGlobalVersionArgs<T>,
|
||||
) {
|
||||
): Promise<TypeWithVersion<T>> {
|
||||
const db = await getTransaction(this, req)
|
||||
const globalConfig: SanitizedGlobalConfig = this.payload.globals.config.find(
|
||||
({ slug }) => slug === global,
|
||||
|
||||
@@ -26,7 +26,7 @@ export async function updateVersion<T extends TypeWithID>(
|
||||
versionData,
|
||||
where: whereArg,
|
||||
}: UpdateVersionArgs<T>,
|
||||
) {
|
||||
): Promise<TypeWithVersion<T>> {
|
||||
const db = await getTransaction(this, req)
|
||||
const collectionConfig: SanitizedCollectionConfig = this.payload.collections[collection].config
|
||||
const whereToUse = whereArg || { id: { equals: id } }
|
||||
|
||||
@@ -116,19 +116,20 @@ export const buildCreateMigration = ({
|
||||
fs.writeFileSync(`${filePath}.json`, JSON.stringify(drizzleJsonAfter, null, 2))
|
||||
}
|
||||
|
||||
const data = getMigrationTemplate({
|
||||
downSQL: downSQL || ` // Migration code`,
|
||||
imports,
|
||||
packageName: payload.db.packageName,
|
||||
upSQL: upSQL || ` // Migration code`,
|
||||
})
|
||||
|
||||
const fullPath = `${filePath}.ts`
|
||||
|
||||
// write migration
|
||||
fs.writeFileSync(
|
||||
`${filePath}.ts`,
|
||||
getMigrationTemplate({
|
||||
downSQL: downSQL || ` // Migration code`,
|
||||
imports,
|
||||
packageName: payload.db.packageName,
|
||||
upSQL: upSQL || ` // Migration code`,
|
||||
}),
|
||||
)
|
||||
fs.writeFileSync(fullPath, data)
|
||||
|
||||
writeMigrationIndex({ migrationsDir: payload.db.migrationDir })
|
||||
|
||||
payload.logger.info({ msg: `Migration created at ${filePath}.ts` })
|
||||
payload.logger.info({ msg: `Migration created at ${fullPath}` })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ export const rootEslintConfig = [
|
||||
'../db-postgres/relationships-v2-v3.mjs',
|
||||
'../db-postgres/scripts/renamePredefinedMigrations.ts',
|
||||
'../db-sqlite/bundle.js',
|
||||
'../db-d1-sqlite/bundle.js',
|
||||
'../db-vercel-postgres/relationships-v2-v3.mjs',
|
||||
'../db-vercel-postgres/scripts/renamePredefinedMigrations.ts',
|
||||
'../plugin-cloud-storage/azure.d.ts',
|
||||
|
||||
10
packages/storage-r2/.prettierignore
Normal file
10
packages/storage-r2/.prettierignore
Normal file
@@ -0,0 +1,10 @@
|
||||
.tmp
|
||||
**/.git
|
||||
**/.hg
|
||||
**/.pnp.*
|
||||
**/.svn
|
||||
**/.yarn/**
|
||||
**/build
|
||||
**/dist/**
|
||||
**/node_modules
|
||||
**/temp
|
||||
15
packages/storage-r2/.swcrc
Normal file
15
packages/storage-r2/.swcrc
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/swcrc",
|
||||
"sourceMaps": true,
|
||||
"jsc": {
|
||||
"target": "esnext",
|
||||
"parser": {
|
||||
"syntax": "typescript",
|
||||
"tsx": true,
|
||||
"dts": true
|
||||
}
|
||||
},
|
||||
"module": {
|
||||
"type": "es6"
|
||||
}
|
||||
}
|
||||
22
packages/storage-r2/LICENSE.md
Normal file
22
packages/storage-r2/LICENSE.md
Normal file
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018-2025 Payload CMS, Inc. <info@payloadcms.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
77
packages/storage-r2/package.json
Normal file
77
packages/storage-r2/package.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "@payloadcms/storage-r2",
|
||||
"version": "3.48.0",
|
||||
"description": "Payload storage adapter for Cloudflare R2",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/payloadcms/payload.git",
|
||||
"directory": "packages/storage-r2"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": "Payload <dev@payloadcms.com> (https://payloadcms.com)",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Payload",
|
||||
"email": "info@payloadcms.com",
|
||||
"url": "https://payloadcms.com"
|
||||
}
|
||||
],
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"default": "./src/index.ts"
|
||||
},
|
||||
"./client": {
|
||||
"import": "./src/exports/client.ts",
|
||||
"types": "./src/exports/client.ts",
|
||||
"default": "./src/exports/client.ts"
|
||||
}
|
||||
},
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "pnpm build:types && pnpm build:swc",
|
||||
"build:clean": "find . \\( -type d \\( -name build -o -name dist -o -name .cache \\) -o -type f -name tsconfig.tsbuildinfo \\) -exec rm -rf {} + && pnpm build",
|
||||
"build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
|
||||
"build:types": "tsc --emitDeclarationOnly --outDir dist",
|
||||
"clean": "rimraf -g {dist,*.tsbuildinfo}",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"prepublishOnly": "pnpm clean && pnpm turbo build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@payloadcms/plugin-cloud-storage": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"payload": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"payload": "workspace:*"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.20.2 || >=20.9.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
},
|
||||
"./client": {
|
||||
"import": "./dist/exports/client.js",
|
||||
"types": "./dist/exports/client.d.ts",
|
||||
"default": "./dist/exports/client.js"
|
||||
}
|
||||
},
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
}
|
||||
15
packages/storage-r2/src/handleDelete.ts
Normal file
15
packages/storage-r2/src/handleDelete.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { HandleDelete } from '@payloadcms/plugin-cloud-storage/types'
|
||||
|
||||
import path from 'path'
|
||||
|
||||
import type { R2Bucket } from './types.js'
|
||||
|
||||
interface Args {
|
||||
bucket: R2Bucket
|
||||
}
|
||||
|
||||
export const getHandleDelete = ({ bucket }: Args): HandleDelete => {
|
||||
return async ({ doc: { prefix = '' }, filename }) => {
|
||||
await bucket.delete(path.posix.join(prefix, filename))
|
||||
}
|
||||
}
|
||||
21
packages/storage-r2/src/handleUpload.ts
Normal file
21
packages/storage-r2/src/handleUpload.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import type { HandleUpload } from '@payloadcms/plugin-cloud-storage/types'
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import path from 'path'
|
||||
|
||||
import type { R2Bucket } from './types.js'
|
||||
|
||||
interface Args {
|
||||
bucket: R2Bucket
|
||||
collection: CollectionConfig
|
||||
prefix?: string
|
||||
}
|
||||
|
||||
export const getHandleUpload = ({ bucket, prefix = '' }: Args): HandleUpload => {
|
||||
return async ({ data, file }) => {
|
||||
// Read more: https://github.com/cloudflare/workers-sdk/issues/6047#issuecomment-2691217843
|
||||
const buffer = process.env.NODE_ENV === 'development' ? new Blob([file.buffer]) : file.buffer
|
||||
await bucket.put(path.posix.join(prefix, file.filename), buffer)
|
||||
return data
|
||||
}
|
||||
}
|
||||
89
packages/storage-r2/src/index.ts
Normal file
89
packages/storage-r2/src/index.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import type {
|
||||
Adapter,
|
||||
PluginOptions as CloudStoragePluginOptions,
|
||||
CollectionOptions,
|
||||
GeneratedAdapter,
|
||||
} from '@payloadcms/plugin-cloud-storage/types'
|
||||
import type { Config, Plugin, UploadCollectionSlug } from 'payload'
|
||||
|
||||
import { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage'
|
||||
|
||||
import type { R2Bucket } from './types.js'
|
||||
|
||||
import { getHandleDelete } from './handleDelete.js'
|
||||
import { getHandleUpload } from './handleUpload.js'
|
||||
import { getHandler } from './staticHandler.js'
|
||||
|
||||
export interface R2StorageOptions {
|
||||
bucket: R2Bucket
|
||||
/**
|
||||
* Collection options to apply the R2 adapter to.
|
||||
*/
|
||||
collections: Partial<Record<UploadCollectionSlug, Omit<CollectionOptions, 'adapter'> | true>>
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
type R2StoragePlugin = (r2StorageArgs: R2StorageOptions) => Plugin
|
||||
|
||||
export const r2Storage: R2StoragePlugin =
|
||||
(r2StorageOptions) =>
|
||||
(incomingConfig: Config): Config => {
|
||||
const adapter = r2StorageInternal(r2StorageOptions)
|
||||
|
||||
const isPluginDisabled = r2StorageOptions.enabled === false
|
||||
|
||||
if (isPluginDisabled) {
|
||||
return incomingConfig
|
||||
}
|
||||
|
||||
// Add adapter to each collection option object
|
||||
const collectionsWithAdapter: CloudStoragePluginOptions['collections'] = Object.entries(
|
||||
r2StorageOptions.collections,
|
||||
).reduce(
|
||||
(acc, [slug, collOptions]) => ({
|
||||
...acc,
|
||||
[slug]: {
|
||||
...(collOptions === true ? {} : collOptions),
|
||||
adapter,
|
||||
},
|
||||
}),
|
||||
{} as Record<string, CollectionOptions>,
|
||||
)
|
||||
|
||||
// Set disableLocalStorage: true for collections specified in the plugin options
|
||||
const config = {
|
||||
...incomingConfig,
|
||||
collections: (incomingConfig.collections || []).map((collection) => {
|
||||
if (!collectionsWithAdapter[collection.slug]) {
|
||||
return collection
|
||||
}
|
||||
|
||||
return {
|
||||
...collection,
|
||||
upload: {
|
||||
...(typeof collection.upload === 'object' ? collection.upload : {}),
|
||||
disableLocalStorage: true,
|
||||
},
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
return cloudStoragePlugin({
|
||||
collections: collectionsWithAdapter,
|
||||
})(config)
|
||||
}
|
||||
|
||||
function r2StorageInternal({ bucket }: R2StorageOptions): Adapter {
|
||||
return ({ collection, prefix }): GeneratedAdapter => {
|
||||
return {
|
||||
name: 'r2',
|
||||
handleDelete: getHandleDelete({ bucket }),
|
||||
handleUpload: getHandleUpload({
|
||||
bucket,
|
||||
collection,
|
||||
prefix,
|
||||
}),
|
||||
staticHandler: getHandler({ bucket, collection }),
|
||||
}
|
||||
}
|
||||
}
|
||||
36
packages/storage-r2/src/staticHandler.ts
Normal file
36
packages/storage-r2/src/staticHandler.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { StaticHandler } from '@payloadcms/plugin-cloud-storage/types'
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import path from 'path'
|
||||
|
||||
import type { R2Bucket } from './types.js'
|
||||
|
||||
interface Args {
|
||||
bucket: R2Bucket
|
||||
collection: CollectionConfig
|
||||
prefix?: string
|
||||
}
|
||||
|
||||
const isMiniflare = process.env.NODE_ENV === 'development'
|
||||
|
||||
export const getHandler = ({ bucket, prefix = '' }: Args): StaticHandler => {
|
||||
return async (req, { params: { filename } }) => {
|
||||
// Due to https://github.com/cloudflare/workers-sdk/issues/6047
|
||||
// We cannot send a Headers instance to Miniflare
|
||||
const obj = await bucket?.get(path.posix.join(prefix, filename), {
|
||||
range: isMiniflare ? undefined : req.headers,
|
||||
})
|
||||
if (obj?.body == undefined) {
|
||||
return new Response(null, { status: 404 })
|
||||
}
|
||||
|
||||
const headers = new Headers()
|
||||
if (!isMiniflare) {
|
||||
obj.writeHttpMetadata(headers)
|
||||
}
|
||||
|
||||
return obj.etag === (req.headers.get('etag') || req.headers.get('if-none-match'))
|
||||
? new Response(null, { headers, status: 304 })
|
||||
: new Response(obj.body, { headers, status: 200 })
|
||||
}
|
||||
}
|
||||
26
packages/storage-r2/src/types.ts
Normal file
26
packages/storage-r2/src/types.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
export interface R2Bucket {
|
||||
createMultipartUpload(key: string, options?: any): Promise<any>
|
||||
delete(keys: string | string[]): Promise<void>
|
||||
get(
|
||||
key: string,
|
||||
options: {
|
||||
onlyIf: any | Headers
|
||||
} & any,
|
||||
): Promise<any | null>
|
||||
get(key: string, options?: any): Promise<any | null>
|
||||
head(key: string): Promise<any>
|
||||
list(options?: any): Promise<any>
|
||||
put(
|
||||
key: string,
|
||||
value: ArrayBuffer | ArrayBufferView | Blob | null | ReadableStream | string,
|
||||
options?: {
|
||||
onlyIf: any
|
||||
} & any,
|
||||
): Promise<any | null>
|
||||
put(
|
||||
key: string,
|
||||
value: ArrayBuffer | ArrayBufferView | Blob | null | ReadableStream | string,
|
||||
options?: any,
|
||||
): Promise<any>
|
||||
resumeMultipartUpload(key: string, uploadId: string): any
|
||||
}
|
||||
15
packages/storage-r2/tsconfig.json
Normal file
15
packages/storage-r2/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"composite": true, // Make sure typescript knows that this module depends on their references
|
||||
"noEmit": false /* Do not emit outputs. */,
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
||||
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
||||
// Do not include DOM and DOM.Iterable as this is a server-only package.
|
||||
"lib": ["ES2022"],
|
||||
},
|
||||
"exclude": ["dist", "node_modules"],
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.d.ts", "src/**/*.json"],
|
||||
"references": [{ "path": "../payload" }, { "path": "../plugin-cloud-storage" }]
|
||||
}
|
||||
252
pnpm-lock.yaml
generated
252
pnpm-lock.yaml
generated
@@ -101,7 +101,7 @@ importers:
|
||||
version: 0.31.4
|
||||
drizzle-orm:
|
||||
specifier: 0.44.2
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8))(@opentelemetry/api@1.9.0)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3)
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3)
|
||||
escape-html:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3
|
||||
@@ -270,6 +270,46 @@ importers:
|
||||
specifier: 22.15.30
|
||||
version: 22.15.30
|
||||
|
||||
packages/db-d1-sqlite:
|
||||
dependencies:
|
||||
'@payloadcms/drizzle':
|
||||
specifier: workspace:*
|
||||
version: link:../drizzle
|
||||
console-table-printer:
|
||||
specifier: 2.12.1
|
||||
version: 2.12.1
|
||||
drizzle-kit:
|
||||
specifier: 0.31.4
|
||||
version: 0.31.4
|
||||
drizzle-orm:
|
||||
specifier: 0.44.2
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3)
|
||||
prompts:
|
||||
specifier: 2.4.2
|
||||
version: 2.4.2
|
||||
to-snake-case:
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
uuid:
|
||||
specifier: 9.0.0
|
||||
version: 9.0.0
|
||||
devDependencies:
|
||||
'@payloadcms/eslint-config':
|
||||
specifier: workspace:*
|
||||
version: link:../eslint-config
|
||||
'@types/pg':
|
||||
specifier: 8.10.2
|
||||
version: 8.10.2
|
||||
'@types/to-snake-case':
|
||||
specifier: 1.0.0
|
||||
version: 1.0.0
|
||||
'@types/uuid':
|
||||
specifier: 10.0.0
|
||||
version: 10.0.0
|
||||
payload:
|
||||
specifier: workspace:*
|
||||
version: link:../payload
|
||||
|
||||
packages/db-mongodb:
|
||||
dependencies:
|
||||
mongoose:
|
||||
@@ -323,7 +363,7 @@ importers:
|
||||
version: 0.31.4
|
||||
drizzle-orm:
|
||||
specifier: 0.44.2
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3)
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3)
|
||||
pg:
|
||||
specifier: 8.16.3
|
||||
version: 8.16.3
|
||||
@@ -369,7 +409,7 @@ importers:
|
||||
version: 0.31.4
|
||||
drizzle-orm:
|
||||
specifier: 0.44.2
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3)
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3)
|
||||
prompts:
|
||||
specifier: 2.4.2
|
||||
version: 2.4.2
|
||||
@@ -412,7 +452,7 @@ importers:
|
||||
version: 0.31.4
|
||||
drizzle-orm:
|
||||
specifier: 0.44.2
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3)
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3)
|
||||
pg:
|
||||
specifier: 8.16.3
|
||||
version: 8.16.3
|
||||
@@ -455,7 +495,7 @@ importers:
|
||||
version: 2.0.3
|
||||
drizzle-orm:
|
||||
specifier: 0.44.2
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3)
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3)
|
||||
prompts:
|
||||
specifier: 2.4.2
|
||||
version: 2.4.2
|
||||
@@ -1473,6 +1513,16 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../payload
|
||||
|
||||
packages/storage-r2:
|
||||
dependencies:
|
||||
'@payloadcms/plugin-cloud-storage':
|
||||
specifier: workspace:*
|
||||
version: link:../plugin-cloud-storage
|
||||
devDependencies:
|
||||
payload:
|
||||
specifier: workspace:*
|
||||
version: link:../payload
|
||||
|
||||
packages/storage-s3:
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3':
|
||||
@@ -1941,12 +1991,21 @@ importers:
|
||||
'@date-fns/tz':
|
||||
specifier: 1.2.0
|
||||
version: 1.2.0
|
||||
'@miniflare/d1':
|
||||
specifier: 2.14.4
|
||||
version: 2.14.4
|
||||
'@miniflare/shared':
|
||||
specifier: 2.14.4
|
||||
version: 2.14.4
|
||||
'@next/env':
|
||||
specifier: 15.4.4
|
||||
version: 15.4.4
|
||||
'@payloadcms/admin-bar':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/admin-bar
|
||||
'@payloadcms/db-d1-sqlite':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/db-d1-sqlite
|
||||
'@payloadcms/db-mongodb':
|
||||
specifier: workspace:*
|
||||
version: link:../packages/db-mongodb
|
||||
@@ -2064,6 +2123,9 @@ importers:
|
||||
babel-plugin-react-compiler:
|
||||
specifier: 19.1.0-rc.3
|
||||
version: 19.1.0-rc.3
|
||||
better-sqlite3:
|
||||
specifier: 11.10.0
|
||||
version: 11.10.0
|
||||
comment-json:
|
||||
specifier: ^4.2.3
|
||||
version: 4.2.5
|
||||
@@ -2084,7 +2146,7 @@ importers:
|
||||
version: 0.31.4
|
||||
drizzle-orm:
|
||||
specifier: 0.44.2
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8))(@opentelemetry/api@1.9.0)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3)
|
||||
version: 0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3)
|
||||
escape-html:
|
||||
specifier: 1.0.3
|
||||
version: 1.0.3
|
||||
@@ -4025,6 +4087,9 @@ packages:
|
||||
cjs-module-lexer:
|
||||
optional: true
|
||||
|
||||
'@iarna/toml@2.2.5':
|
||||
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
@@ -4611,6 +4676,31 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@miniflare/core@2.14.4':
|
||||
resolution: {integrity: sha512-FMmZcC1f54YpF4pDWPtdQPIO8NXfgUxCoR9uyrhxKJdZu7M6n8QKopPVNuaxR40jcsdxb7yKoQoFWnHfzJD9GQ==}
|
||||
engines: {node: '>=16.13'}
|
||||
deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4
|
||||
|
||||
'@miniflare/d1@2.14.4':
|
||||
resolution: {integrity: sha512-pMBVq9XWxTDdm+RRCkfXZP+bREjPg1JC8s8C0JTovA9OGmLQXqGTnFxIaS9vf1d8k3uSUGhDzPTzHr0/AUW1gA==}
|
||||
engines: {node: '>=16.7'}
|
||||
deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4
|
||||
|
||||
'@miniflare/queues@2.14.4':
|
||||
resolution: {integrity: sha512-aXQ5Ik8Iq1KGMBzGenmd6Js/jJgqyYvjom95/N9GptCGpiVWE5F0XqC1SL5rCwURbHN+aWY191o8XOFyY2nCUA==}
|
||||
engines: {node: '>=16.7'}
|
||||
deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4
|
||||
|
||||
'@miniflare/shared@2.14.4':
|
||||
resolution: {integrity: sha512-upl4RSB3hyCnITOFmRZjJj4A72GmkVrtfZTilkdq5Qe5TTlzsjVeDJp7AuNUM9bM8vswRo+N5jOiot6O4PVwwQ==}
|
||||
engines: {node: '>=16.13'}
|
||||
deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4
|
||||
|
||||
'@miniflare/watcher@2.14.4':
|
||||
resolution: {integrity: sha512-PYn05ET2USfBAeXF6NZfWl0O32KVyE8ncQ/ngysrh3hoIV7l3qGGH7ubeFx+D8VWQ682qYhwGygUzQv2j1tGGg==}
|
||||
engines: {node: '>=16.13'}
|
||||
deprecated: Miniflare v2 is no longer supported. Please upgrade to Miniflare v4
|
||||
|
||||
'@monaco-editor/loader@1.5.0':
|
||||
resolution: {integrity: sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==}
|
||||
|
||||
@@ -6243,6 +6333,9 @@ packages:
|
||||
'@types/babel__traverse@7.20.6':
|
||||
resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
|
||||
|
||||
'@types/better-sqlite3@7.6.13':
|
||||
resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==}
|
||||
|
||||
'@types/busboy@1.5.4':
|
||||
resolution: {integrity: sha512-kG7WrUuAKK0NoyxfQHsVE6j1m01s6kMma64E+OZenQABMQyTJop1DumUWcLwAQ2JzpefU7PDYoRDKl8uZosFjw==}
|
||||
|
||||
@@ -7121,6 +7214,9 @@ packages:
|
||||
base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
resolution: {integrity: sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==}
|
||||
|
||||
bignumber.js@9.1.2:
|
||||
resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==}
|
||||
|
||||
@@ -7136,6 +7232,9 @@ packages:
|
||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
bindings@1.5.0:
|
||||
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
||||
|
||||
birecord@0.1.1:
|
||||
resolution: {integrity: sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==}
|
||||
|
||||
@@ -7203,6 +7302,9 @@ packages:
|
||||
resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==}
|
||||
engines: {node: '>=6.14.2'}
|
||||
|
||||
builtins@5.1.0:
|
||||
resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==}
|
||||
|
||||
bundle-name@4.1.0:
|
||||
resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -8349,6 +8451,10 @@ packages:
|
||||
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
execa@6.1.0:
|
||||
resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
execa@8.0.1:
|
||||
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
|
||||
engines: {node: '>=16.17'}
|
||||
@@ -8470,6 +8576,9 @@ packages:
|
||||
resolution: {integrity: sha512-mROwiKLZf/Kwa/2Rol+OOZQn1eyTkPB3ZTwC0ExY6OLFCbgxHYZvBm7xI77NvfZFMKBsmuXfmLJnD4eEftEhrA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||
|
||||
filename-reserved-regex@3.0.0:
|
||||
resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
@@ -8912,6 +9021,10 @@ packages:
|
||||
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
||||
engines: {node: '>=10.17.0'}
|
||||
|
||||
human-signals@3.0.1:
|
||||
resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
|
||||
human-signals@5.0.0:
|
||||
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
|
||||
engines: {node: '>=16.17.0'}
|
||||
@@ -9560,6 +9673,10 @@ packages:
|
||||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
kleur@4.1.5:
|
||||
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
language-subtag-registry@0.3.23:
|
||||
resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==}
|
||||
|
||||
@@ -10161,6 +10278,9 @@ packages:
|
||||
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
|
||||
npx-import@1.1.4:
|
||||
resolution: {integrity: sha512-3ShymTWOgqGyNlh5lMJAejLuIv3W1K3fbI5Ewc6YErZU3Sp0PqsNs8UIU1O8z5+KVl/Du5ag56Gza9vdorGEoA==}
|
||||
|
||||
nwsapi@2.2.20:
|
||||
resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==}
|
||||
|
||||
@@ -10325,6 +10445,9 @@ packages:
|
||||
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
parse-package-name@1.0.0:
|
||||
resolution: {integrity: sha512-kBeTUtcj+SkyfaW4+KBe0HtsloBJ/mKTPoxpVdA57GZiPerREsUWJOhVj9anXweFiJkm5y8FG1sxFZkZ0SN6wg==}
|
||||
|
||||
parse-passwd@1.0.0:
|
||||
resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -11224,6 +11347,9 @@ packages:
|
||||
server-only@0.0.1:
|
||||
resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
|
||||
|
||||
set-cookie-parser@2.7.1:
|
||||
resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
|
||||
|
||||
set-function-length@1.2.2:
|
||||
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -12146,6 +12272,9 @@ packages:
|
||||
uri-js@4.4.1:
|
||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||
|
||||
urlpattern-polyfill@4.0.3:
|
||||
resolution: {integrity: sha512-DOE84vZT2fEcl9gqCUTcnAw5ZY5Id55ikUcziSUntuEFL3pRvavg5kwDmTEUJkeCHInTlV/HexFomgYnzO5kdQ==}
|
||||
|
||||
use-callback-ref@1.3.3:
|
||||
resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -12217,6 +12346,10 @@ packages:
|
||||
validate-npm-package-license@3.0.4:
|
||||
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
|
||||
|
||||
validate-npm-package-name@4.0.0:
|
||||
resolution: {integrity: sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
|
||||
varint@6.0.0:
|
||||
resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
|
||||
|
||||
@@ -13487,7 +13620,7 @@ snapshots:
|
||||
'@babel/core': 7.27.3
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
debug: 4.3.7
|
||||
debug: 4.4.1
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.8
|
||||
transitivePeerDependencies:
|
||||
@@ -13498,7 +13631,7 @@ snapshots:
|
||||
'@babel/core': 7.27.3
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
debug: 4.3.7
|
||||
debug: 4.4.1
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.8
|
||||
transitivePeerDependencies:
|
||||
@@ -14953,6 +15086,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
cjs-module-lexer: 1.4.1
|
||||
|
||||
'@iarna/toml@2.2.5': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||
@@ -15620,6 +15755,39 @@ snapshots:
|
||||
'@libsql/win32-x64-msvc@0.4.7':
|
||||
optional: true
|
||||
|
||||
'@miniflare/core@2.14.4':
|
||||
dependencies:
|
||||
'@iarna/toml': 2.2.5
|
||||
'@miniflare/queues': 2.14.4
|
||||
'@miniflare/shared': 2.14.4
|
||||
'@miniflare/watcher': 2.14.4
|
||||
busboy: 1.6.0
|
||||
dotenv: 16.4.7
|
||||
kleur: 4.1.5
|
||||
set-cookie-parser: 2.7.1
|
||||
undici: 5.28.4
|
||||
urlpattern-polyfill: 4.0.3
|
||||
|
||||
'@miniflare/d1@2.14.4':
|
||||
dependencies:
|
||||
'@miniflare/core': 2.14.4
|
||||
'@miniflare/shared': 2.14.4
|
||||
|
||||
'@miniflare/queues@2.14.4':
|
||||
dependencies:
|
||||
'@miniflare/shared': 2.14.4
|
||||
|
||||
'@miniflare/shared@2.14.4':
|
||||
dependencies:
|
||||
'@types/better-sqlite3': 7.6.13
|
||||
kleur: 4.1.5
|
||||
npx-import: 1.1.4
|
||||
picomatch: 2.3.1
|
||||
|
||||
'@miniflare/watcher@2.14.4':
|
||||
dependencies:
|
||||
'@miniflare/shared': 2.14.4
|
||||
|
||||
'@monaco-editor/loader@1.5.0':
|
||||
dependencies:
|
||||
state-local: 1.0.7
|
||||
@@ -17446,6 +17614,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@babel/types': 7.27.3
|
||||
|
||||
'@types/better-sqlite3@7.6.13':
|
||||
dependencies:
|
||||
'@types/node': 22.5.4
|
||||
|
||||
'@types/busboy@1.5.4':
|
||||
dependencies:
|
||||
'@types/node': 22.15.30
|
||||
@@ -17748,7 +17920,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.14.0
|
||||
'@typescript-eslint/visitor-keys': 8.14.0
|
||||
debug: 4.3.7
|
||||
debug: 4.4.1
|
||||
fast-glob: 3.3.2
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.5
|
||||
@@ -18545,6 +18717,11 @@ snapshots:
|
||||
|
||||
base64-js@1.5.1: {}
|
||||
|
||||
better-sqlite3@11.10.0:
|
||||
dependencies:
|
||||
bindings: 1.5.0
|
||||
prebuild-install: 7.1.2
|
||||
|
||||
bignumber.js@9.1.2: {}
|
||||
|
||||
bin-version-check@5.1.0:
|
||||
@@ -18560,6 +18737,10 @@ snapshots:
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
bindings@1.5.0:
|
||||
dependencies:
|
||||
file-uri-to-path: 1.0.0
|
||||
|
||||
birecord@0.1.1: {}
|
||||
|
||||
bl@4.1.0:
|
||||
@@ -18635,6 +18816,10 @@ snapshots:
|
||||
dependencies:
|
||||
node-gyp-build: 4.8.2
|
||||
|
||||
builtins@5.1.0:
|
||||
dependencies:
|
||||
semver: 7.7.1
|
||||
|
||||
bundle-name@4.1.0:
|
||||
dependencies:
|
||||
run-applescript: 7.0.0
|
||||
@@ -19190,21 +19375,25 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
drizzle-orm@0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3):
|
||||
drizzle-orm@0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.10.2)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3):
|
||||
optionalDependencies:
|
||||
'@libsql/client': 0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@types/better-sqlite3': 7.6.13
|
||||
'@types/pg': 8.10.2
|
||||
'@vercel/postgres': 0.9.0
|
||||
better-sqlite3: 11.10.0
|
||||
gel: 2.0.1
|
||||
pg: 8.16.3
|
||||
|
||||
drizzle-orm@0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8))(@opentelemetry/api@1.9.0)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(gel@2.0.1)(pg@8.16.3):
|
||||
drizzle-orm@0.44.2(@libsql/client@0.14.0(bufferutil@4.0.8))(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.11.6)(@vercel/postgres@0.9.0)(better-sqlite3@11.10.0)(gel@2.0.1)(pg@8.16.3):
|
||||
optionalDependencies:
|
||||
'@libsql/client': 0.14.0(bufferutil@4.0.8)(utf-8-validate@6.0.5)
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@types/better-sqlite3': 7.6.13
|
||||
'@types/pg': 8.11.6
|
||||
'@vercel/postgres': 0.9.0
|
||||
better-sqlite3: 11.10.0
|
||||
gel: 2.0.1
|
||||
pg: 8.16.3
|
||||
|
||||
@@ -19995,6 +20184,18 @@ snapshots:
|
||||
signal-exit: 3.0.7
|
||||
strip-final-newline: 2.0.0
|
||||
|
||||
execa@6.1.0:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
get-stream: 6.0.1
|
||||
human-signals: 3.0.1
|
||||
is-stream: 3.0.0
|
||||
merge-stream: 2.0.0
|
||||
npm-run-path: 5.3.0
|
||||
onetime: 6.0.0
|
||||
signal-exit: 3.0.7
|
||||
strip-final-newline: 3.0.0
|
||||
|
||||
execa@8.0.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.5
|
||||
@@ -20117,6 +20318,8 @@ snapshots:
|
||||
token-types: 6.0.0
|
||||
uint8array-extras: 1.4.0
|
||||
|
||||
file-uri-to-path@1.0.0: {}
|
||||
|
||||
filename-reserved-regex@3.0.0: {}
|
||||
|
||||
filenamify@6.0.0:
|
||||
@@ -20597,7 +20800,7 @@ snapshots:
|
||||
http-proxy-agent@7.0.2:
|
||||
dependencies:
|
||||
agent-base: 7.1.1
|
||||
debug: 4.3.7
|
||||
debug: 4.4.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -20618,7 +20821,7 @@ snapshots:
|
||||
https-proxy-agent@7.0.5:
|
||||
dependencies:
|
||||
agent-base: 7.1.1
|
||||
debug: 4.3.7
|
||||
debug: 4.4.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -20631,6 +20834,8 @@ snapshots:
|
||||
|
||||
human-signals@2.1.0: {}
|
||||
|
||||
human-signals@3.0.1: {}
|
||||
|
||||
human-signals@5.0.0: {}
|
||||
|
||||
husky@9.0.11: {}
|
||||
@@ -21455,6 +21660,8 @@ snapshots:
|
||||
|
||||
kleur@3.0.3: {}
|
||||
|
||||
kleur@4.1.5: {}
|
||||
|
||||
language-subtag-registry@0.3.23: {}
|
||||
|
||||
language-tags@1.0.9:
|
||||
@@ -22063,7 +22270,7 @@ snapshots:
|
||||
|
||||
new-find-package-json@2.0.0:
|
||||
dependencies:
|
||||
debug: 4.3.7
|
||||
debug: 4.4.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -22248,6 +22455,13 @@ snapshots:
|
||||
dependencies:
|
||||
path-key: 4.0.0
|
||||
|
||||
npx-import@1.1.4:
|
||||
dependencies:
|
||||
execa: 6.1.0
|
||||
parse-package-name: 1.0.0
|
||||
semver: 7.7.1
|
||||
validate-npm-package-name: 4.0.0
|
||||
|
||||
nwsapi@2.2.20: {}
|
||||
|
||||
nypm@0.3.12:
|
||||
@@ -22449,6 +22663,8 @@ snapshots:
|
||||
json-parse-even-better-errors: 2.3.1
|
||||
lines-and-columns: 1.2.4
|
||||
|
||||
parse-package-name@1.0.0: {}
|
||||
|
||||
parse-passwd@1.0.0: {}
|
||||
|
||||
parse5@7.3.0:
|
||||
@@ -23344,6 +23560,8 @@ snapshots:
|
||||
|
||||
server-only@0.0.1: {}
|
||||
|
||||
set-cookie-parser@2.7.1: {}
|
||||
|
||||
set-function-length@1.2.2:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
@@ -24481,6 +24699,8 @@ snapshots:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
urlpattern-polyfill@4.0.3: {}
|
||||
|
||||
use-callback-ref@1.3.3(@types/react@19.1.8)(react@19.1.1):
|
||||
dependencies:
|
||||
react: 19.1.1
|
||||
@@ -24536,6 +24756,10 @@ snapshots:
|
||||
spdx-correct: 3.2.0
|
||||
spdx-expression-parse: 3.0.1
|
||||
|
||||
validate-npm-package-name@4.0.0:
|
||||
dependencies:
|
||||
builtins: 5.1.0
|
||||
|
||||
varint@6.0.0: {}
|
||||
|
||||
vfile-message@4.0.2:
|
||||
|
||||
1
templates/with-cloudflare-d1/.env.example
Normal file
1
templates/with-cloudflare-d1/.env.example
Normal file
@@ -0,0 +1 @@
|
||||
PAYLOAD_SECRET=THISISYOURSECRET
|
||||
54
templates/with-cloudflare-d1/.gitignore
vendored
Normal file
54
templates/with-cloudflare-d1/.gitignore
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.yarn/install-state.gz
|
||||
|
||||
/.idea/*
|
||||
!/.idea/runConfigurations
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env*.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
.env
|
||||
|
||||
/media
|
||||
|
||||
# Playwright
|
||||
node_modules/
|
||||
/test-results/
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
|
||||
# OpenNext
|
||||
.open-next
|
||||
.wrangler
|
||||
1
templates/with-cloudflare-d1/.npmrc
Normal file
1
templates/with-cloudflare-d1/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
legacy-peer-deps=true
|
||||
6
templates/with-cloudflare-d1/.prettierrc.json
Normal file
6
templates/with-cloudflare-d1/.prettierrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"semi": false
|
||||
}
|
||||
3
templates/with-cloudflare-d1/.vscode/extensions.json
vendored
Normal file
3
templates/with-cloudflare-d1/.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
|
||||
}
|
||||
24
templates/with-cloudflare-d1/.vscode/launch.json
vendored
Normal file
24
templates/with-cloudflare-d1/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Next.js: debug full stack",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/next/dist/bin/next",
|
||||
"runtimeArgs": ["--inspect"],
|
||||
"skipFiles": ["<node_internals>/**"],
|
||||
"serverReadyAction": {
|
||||
"action": "debugWithChrome",
|
||||
"killOnServerStop": true,
|
||||
"pattern": "- Local:.+(https?://.+)",
|
||||
"uriFormat": "%s",
|
||||
"webRoot": "${workspaceFolder}"
|
||||
},
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
||||
40
templates/with-cloudflare-d1/.vscode/settings.json
vendored
Normal file
40
templates/with-cloudflare-d1/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"npm.packageManager": "pnpm",
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"editor.formatOnSaveMode": "file",
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"[javascript][typescript][typescriptreact]": {
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
}
|
||||
}
|
||||
}
|
||||
1
templates/with-cloudflare-d1/.yarnrc
Normal file
1
templates/with-cloudflare-d1/.yarnrc
Normal file
@@ -0,0 +1 @@
|
||||
--install.ignore-engines true
|
||||
99
templates/with-cloudflare-d1/README.md
Normal file
99
templates/with-cloudflare-d1/README.md
Normal file
@@ -0,0 +1,99 @@
|
||||
# Payload Cloudflare Template
|
||||
|
||||
[](https://deploy.workers.cloudflare.com/?url=https://github.com/payloadcms/payload/tree/feat/add-d1-adapter/templates/with-cloudflare-d1)
|
||||
|
||||
This template comes configured with the bare minimum to get started on anything you need.
|
||||
|
||||
## Quick start
|
||||
|
||||
This template can be deployed directly to Cloudflare Workers by clicking the button to take you to the setup screen.
|
||||
|
||||
From there you can connect your code to a git provider such Github or Gitlab, name your Workers, D1 Database and R2 Bucket as well as attach any additional environment variables or services you need.
|
||||
|
||||
## Quick Start - local setup
|
||||
|
||||
To spin up this template locally, follow these steps:
|
||||
|
||||
### Clone
|
||||
|
||||
After you click the `Deploy` button above, you'll want to have standalone copy of this repo on your machine. Cloudflare will connect your app to a git provider such as Github and you can access your code from there.
|
||||
|
||||
### Local Development
|
||||
|
||||
## How it works
|
||||
|
||||
Out of the box, using [`Wrangler`](https://developers.cloudflare.com/workers/wrangler/) will automatically create local bindings for you to connect to the remote services and it can even create a local mock of the services you're using with Cloudflare.
|
||||
|
||||
We've pre-configured Payload for you with the following:
|
||||
|
||||
### Collections
|
||||
|
||||
See the [Collections](https://payloadcms.com/docs/configuration/collections) docs for details on how to extend this functionality.
|
||||
|
||||
- #### Users (Authentication)
|
||||
|
||||
Users are auth-enabled collections that have access to the admin panel.
|
||||
|
||||
For additional help, see the official [Auth Example](https://github.com/payloadcms/payload/tree/main/examples/auth) or the [Authentication](https://payloadcms.com/docs/authentication/overview#authentication-overview) docs.
|
||||
|
||||
- #### Media
|
||||
|
||||
This is the uploads enabled collection.
|
||||
|
||||
### Image Storage (R2)
|
||||
|
||||
Images will be served from an R2 bucket which you can then further configure to use a CDN to serve for your frontend directly.
|
||||
|
||||
### D1 Database
|
||||
|
||||
The Worker will have direct access to a D1 SQLite database which Wrangler can connect locally to, just note that you won't have a connection string as you would typically with other providers.
|
||||
|
||||
## Working with Cloudflare
|
||||
|
||||
Firstly, after installing dependencies locally you need to authenticate with Wrangler by running:
|
||||
|
||||
```bash
|
||||
pnpm wrangler login
|
||||
```
|
||||
|
||||
This will take you to Cloudflare to login and then you can use the Wrangler CLI locally for anything, use `pnpm wrangler help` to see all available options.
|
||||
|
||||
Wrangler is pretty smart so it will automatically bind your services for local development just by running `pnpm dev`.
|
||||
|
||||
## Deployments
|
||||
|
||||
When you're ready to deploy, first make sure you have created your migrations:
|
||||
|
||||
```bash
|
||||
pnpm payload migrate:create
|
||||
```
|
||||
|
||||
Then run the following command:
|
||||
|
||||
```bash
|
||||
pnpm run deploy
|
||||
```
|
||||
|
||||
This will spin up Wrangler in `production` mode, run any created migrations, build the app and then deploy the bundle up to Cloudflare.
|
||||
|
||||
That's it! You can if you wish move these steps into your CI pipeline as well.
|
||||
|
||||
## Enabling logs
|
||||
|
||||
By default logs are not enabled for your API, we've made this decision because it does run against your quota so we've left it opt-in. But you can easily enable logs in one click in the Cloudflare panel, [see docs](https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs).
|
||||
|
||||
## Known issues
|
||||
|
||||
### GraphQL
|
||||
|
||||
We are currently waiting on some issues with GraphQL to be [fixed upstream in Workers](https://github.com/cloudflare/workerd/issues/5175) so full support for GraphQL is not currently guaranteed when deployed.
|
||||
|
||||
### Worker size limits
|
||||
|
||||
We currently recommend deploying this template to the Paid Workers plan due to bundle [size limits](https://developers.cloudflare.com/workers/platform/limits/#worker-size) of 3mb. We're actively trying to reduce our bundle footprint over time to better meet this metric.
|
||||
|
||||
This also applies to your own code, in the case of importing a lot of libraries you may find yourself limited by the bundle.
|
||||
|
||||
## Questions
|
||||
|
||||
If you have any issues or questions, reach out to us on [Discord](https://discord.com/invite/payload) or start a [GitHub discussion](https://github.com/payloadcms/payload/discussions).
|
||||
8317
templates/with-cloudflare-d1/cloudflare-env.d.ts
vendored
Normal file
8317
templates/with-cloudflare-d1/cloudflare-env.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
38
templates/with-cloudflare-d1/eslint.config.mjs
Normal file
38
templates/with-cloudflare-d1/eslint.config.mjs
Normal file
@@ -0,0 +1,38 @@
|
||||
import { dirname } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { FlatCompat } from '@eslint/eslintrc'
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = dirname(__filename)
|
||||
|
||||
const compat = new FlatCompat({
|
||||
baseDirectory: __dirname,
|
||||
})
|
||||
|
||||
const eslintConfig = [
|
||||
...compat.extends('next/core-web-vitals', 'next/typescript'),
|
||||
{
|
||||
rules: {
|
||||
'@typescript-eslint/ban-ts-comment': 'warn',
|
||||
'@typescript-eslint/no-empty-object-type': 'warn',
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
vars: 'all',
|
||||
args: 'after-used',
|
||||
ignoreRestSiblings: false,
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
destructuredArrayIgnorePattern: '^_',
|
||||
caughtErrorsIgnorePattern: '^(_|ignore)',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
ignores: ['.next/'],
|
||||
},
|
||||
]
|
||||
|
||||
export default eslintConfig
|
||||
20
templates/with-cloudflare-d1/next.config.ts
Normal file
20
templates/with-cloudflare-d1/next.config.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { withPayload } from '@payloadcms/next/withPayload'
|
||||
import { initOpenNextCloudflareForDev } from '@opennextjs/cloudflare'
|
||||
|
||||
initOpenNextCloudflareForDev({ environment: process.env.CLOUDFLARE_ENV })
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
// Your Next.js config here
|
||||
webpack: (webpackConfig: any) => {
|
||||
webpackConfig.resolve.extensionAlias = {
|
||||
'.cjs': ['.cts', '.cjs'],
|
||||
'.js': ['.ts', '.tsx', '.js', '.jsx'],
|
||||
'.mjs': ['.mts', '.mjs'],
|
||||
}
|
||||
|
||||
return webpackConfig
|
||||
},
|
||||
}
|
||||
|
||||
export default withPayload(nextConfig, { devBundleServerPackages: false })
|
||||
4
templates/with-cloudflare-d1/open-next.config.ts
Normal file
4
templates/with-cloudflare-d1/open-next.config.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// default open-next.config.ts file created by @opennextjs/cloudflare
|
||||
import { defineCloudflareConfig } from '@opennextjs/cloudflare/config'
|
||||
|
||||
export default defineCloudflareConfig({})
|
||||
84
templates/with-cloudflare-d1/package.json
Normal file
84
templates/with-cloudflare-d1/package.json
Normal file
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"name": "with-cloudflare-d1",
|
||||
"version": "1.0.0",
|
||||
"description": "A blank template to get started with Payload 3.0",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "cross-env NODE_OPTIONS=\"--no-deprecation --max-old-space-size=8000\" next build",
|
||||
"deploy": "pnpm run deploy:database && pnpm run deploy:app",
|
||||
"deploy:app": "opennextjs-cloudflare build -e $CLOUDFLARE_ENV && opennextjs-cloudflare deploy -e $CLOUDFLARE_ENV",
|
||||
"deploy:database": "NODE_ENV=production PAYLOAD_SECRET=ignore payload migrate && wrangler d1 execute D1 --command 'PRAGMA optimize' --remote",
|
||||
"dev": "cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||
"devsafe": "rm -rf .next && rm -rf .open-next && cross-env NODE_OPTIONS=--no-deprecation next dev",
|
||||
"generate:importmap": "cross-env NODE_OPTIONS=--no-deprecation payload generate:importmap",
|
||||
"generate:types": "pnpm run generate:types:cloudflare && pnpm run generate:types:payload",
|
||||
"generate:types:cloudflare": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts",
|
||||
"generate:types:payload": "cross-env NODE_OPTIONS=--no-deprecation payload generate:types",
|
||||
"ii": "pnpm install --ignore-workspace",
|
||||
"lint": "cross-env NODE_OPTIONS=--no-deprecation next lint",
|
||||
"payload": "cross-env NODE_OPTIONS=--no-deprecation payload",
|
||||
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview -e $CLOUDFLARE_ENV",
|
||||
"start": "cross-env NODE_OPTIONS=--no-deprecation next start",
|
||||
"test": "pnpm run test:int && pnpm run test:e2e",
|
||||
"test:e2e": "cross-env NODE_OPTIONS=\"--no-deprecation --no-experimental-strip-types\" pnpm exec playwright test",
|
||||
"test:int": "cross-env NODE_OPTIONS=--no-deprecation vitest run --config ./vitest.config.mts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opennextjs/cloudflare": "^1.6.5",
|
||||
"@payloadcms/db-d1-sqlite": "3.58.0-internal.8775d75",
|
||||
"@payloadcms/next": "3.58.0-internal.8775d75",
|
||||
"@payloadcms/payload-cloud": "3.58.0-internal.8775d75",
|
||||
"@payloadcms/richtext-lexical": "3.58.0-internal.8775d75",
|
||||
"@payloadcms/storage-r2": "3.58.0-internal.8775d75",
|
||||
"@payloadcms/ui": "3.58.0-internal.8775d75",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "16.4.7",
|
||||
"graphql": "^16.8.1",
|
||||
"next": "15.4.4",
|
||||
"payload": "3.58.0-internal.8775d75",
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.54.1",
|
||||
"@testing-library/react": "16.3.0",
|
||||
"@types/node": "^22.5.4",
|
||||
"@types/react": "19.1.8",
|
||||
"@types/react-dom": "19.1.6",
|
||||
"@vitejs/plugin-react": "4.5.2",
|
||||
"eslint": "^9.16.0",
|
||||
"eslint-config-next": "15.4.4",
|
||||
"jsdom": "26.1.0",
|
||||
"playwright": "1.54.1",
|
||||
"playwright-core": "1.54.1",
|
||||
"prettier": "^3.4.2",
|
||||
"typescript": "5.7.3",
|
||||
"vite-tsconfig-paths": "5.1.4",
|
||||
"vitest": "3.2.3",
|
||||
"wrangler": "^4.26.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.20.2 || >=20.9.0",
|
||||
"pnpm": "^9 || ^10"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"sharp",
|
||||
"esbuild",
|
||||
"unrs-resolver"
|
||||
]
|
||||
},
|
||||
"cloudflare": {
|
||||
"bindings": {
|
||||
"PAYLOAD_SECRET": {
|
||||
"description": "Generate a random string using `openssl rand -hex 32`"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"@payloadcms/db-d1-sqlite": {
|
||||
"drizzle-kit": "0.30.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
41
templates/with-cloudflare-d1/playwright.config.ts
Normal file
41
templates/with-cloudflare-d1/playwright.config.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { defineConfig, devices } from '@playwright/test'
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
import 'dotenv/config'
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: './tests/e2e',
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: 'html',
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
// baseURL: 'http://localhost:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
],
|
||||
webServer: {
|
||||
command: 'pnpm dev',
|
||||
reuseExistingServer: true,
|
||||
url: 'http://localhost:3000',
|
||||
},
|
||||
})
|
||||
19
templates/with-cloudflare-d1/src/app/(frontend)/layout.tsx
Normal file
19
templates/with-cloudflare-d1/src/app/(frontend)/layout.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import React from 'react'
|
||||
import './styles.css'
|
||||
|
||||
export const metadata = {
|
||||
description: 'A blank template using Payload in a Next.js app.',
|
||||
title: 'Payload Blank Template',
|
||||
}
|
||||
|
||||
export default async function RootLayout(props: { children: React.ReactNode }) {
|
||||
const { children } = props
|
||||
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<main>{children}</main>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
59
templates/with-cloudflare-d1/src/app/(frontend)/page.tsx
Normal file
59
templates/with-cloudflare-d1/src/app/(frontend)/page.tsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import { headers as getHeaders } from 'next/headers.js'
|
||||
import Image from 'next/image'
|
||||
import { getPayload } from 'payload'
|
||||
import React from 'react'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import config from '@/payload.config'
|
||||
import './styles.css'
|
||||
|
||||
export default async function HomePage() {
|
||||
const headers = await getHeaders()
|
||||
const payloadConfig = await config
|
||||
const payload = await getPayload({ config: payloadConfig })
|
||||
const { user } = await payload.auth({ headers })
|
||||
|
||||
const fileURL = `vscode://file/${fileURLToPath(import.meta.url)}`
|
||||
|
||||
return (
|
||||
<div className="home">
|
||||
<div className="content">
|
||||
<picture>
|
||||
<source srcSet="https://raw.githubusercontent.com/payloadcms/payload/main/packages/ui/src/assets/payload-favicon.svg" />
|
||||
<Image
|
||||
alt="Payload Logo"
|
||||
height={65}
|
||||
src="https://raw.githubusercontent.com/payloadcms/payload/main/packages/ui/src/assets/payload-favicon.svg"
|
||||
width={65}
|
||||
/>
|
||||
</picture>
|
||||
{!user && <h1>Welcome to your new project.</h1>}
|
||||
{user && <h1>Welcome back, {user.email}</h1>}
|
||||
<div className="links">
|
||||
<a
|
||||
className="admin"
|
||||
href={payloadConfig.routes.admin}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Go to admin panel
|
||||
</a>
|
||||
<a
|
||||
className="docs"
|
||||
href="https://payloadcms.com/docs"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="footer">
|
||||
<p>Update this page by editing</p>
|
||||
<a className="codeLink" href={fileURL}>
|
||||
<code>app/(frontend)/page.tsx</code>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
164
templates/with-cloudflare-d1/src/app/(frontend)/styles.css
Normal file
164
templates/with-cloudflare-d1/src/app/(frontend)/styles.css
Normal file
@@ -0,0 +1,164 @@
|
||||
:root {
|
||||
--font-mono: 'Roboto Mono', monospace;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
|
||||
background: rgb(0, 0, 0);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: system-ui;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
|
||||
margin: 0;
|
||||
color: rgb(1000, 1000, 1000);
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 40px 0;
|
||||
font-size: 64px;
|
||||
line-height: 70px;
|
||||
font-weight: bold;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
margin: 24px 0;
|
||||
font-size: 42px;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
font-size: 38px;
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
@media (max-width: 400px) {
|
||||
font-size: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 24px 0;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
margin: calc(var(--base) * 0.75) 0;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: currentColor;
|
||||
|
||||
&:focus {
|
||||
opacity: 0.8;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: 0.7;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.home {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
padding: 45px;
|
||||
max-width: 1024px;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: 400px) {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-grow: 1;
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.admin {
|
||||
color: rgb(0, 0, 0);
|
||||
background: rgb(1000, 1000, 1000);
|
||||
border: 1px solid rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
.docs {
|
||||
color: rgb(1000, 1000, 1000);
|
||||
background: rgb(0, 0, 0);
|
||||
border: 1px solid rgb(1000, 1000, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.codeLink {
|
||||
text-decoration: none;
|
||||
padding: 0 0.5rem;
|
||||
background: rgb(60, 60, 60);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
import { NotFoundPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
import { importMap } from '../importMap'
|
||||
|
||||
type Args = {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}>
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const NotFound = ({ params, searchParams }: Args) =>
|
||||
NotFoundPage({ config, params, searchParams, importMap })
|
||||
|
||||
export default NotFound
|
||||
@@ -0,0 +1,24 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import config from '@payload-config'
|
||||
import { RootPage, generatePageMetadata } from '@payloadcms/next/views'
|
||||
import { importMap } from '../importMap'
|
||||
|
||||
type Args = {
|
||||
params: Promise<{
|
||||
segments: string[]
|
||||
}>
|
||||
searchParams: Promise<{
|
||||
[key: string]: string | string[]
|
||||
}>
|
||||
}
|
||||
|
||||
export const generateMetadata = ({ params, searchParams }: Args): Promise<Metadata> =>
|
||||
generatePageMetadata({ config, params, searchParams })
|
||||
|
||||
const Page = ({ params, searchParams }: Args) =>
|
||||
RootPage({ config, params, searchParams, importMap })
|
||||
|
||||
export default Page
|
||||
@@ -0,0 +1 @@
|
||||
export const importMap = {}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import {
|
||||
REST_DELETE,
|
||||
REST_GET,
|
||||
REST_OPTIONS,
|
||||
REST_PATCH,
|
||||
REST_POST,
|
||||
REST_PUT,
|
||||
} from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = REST_GET(config)
|
||||
export const POST = REST_POST(config)
|
||||
export const DELETE = REST_DELETE(config)
|
||||
export const PATCH = REST_PATCH(config)
|
||||
export const PUT = REST_PUT(config)
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
@@ -0,0 +1,7 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import { GRAPHQL_PLAYGROUND_GET } from '@payloadcms/next/routes'
|
||||
|
||||
export const GET = GRAPHQL_PLAYGROUND_GET(config)
|
||||
@@ -0,0 +1,8 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import { GRAPHQL_POST, REST_OPTIONS } from '@payloadcms/next/routes'
|
||||
|
||||
export const POST = GRAPHQL_POST(config)
|
||||
|
||||
export const OPTIONS = REST_OPTIONS(config)
|
||||
31
templates/with-cloudflare-d1/src/app/(payload)/layout.tsx
Normal file
31
templates/with-cloudflare-d1/src/app/(payload)/layout.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
/* THIS FILE WAS GENERATED AUTOMATICALLY BY PAYLOAD. */
|
||||
/* DO NOT MODIFY IT BECAUSE IT COULD BE REWRITTEN AT ANY TIME. */
|
||||
import config from '@payload-config'
|
||||
import '@payloadcms/next/css'
|
||||
import type { ServerFunctionClient } from 'payload'
|
||||
import { handleServerFunctions, RootLayout } from '@payloadcms/next/layouts'
|
||||
import React from 'react'
|
||||
|
||||
import { importMap } from './admin/importMap.js'
|
||||
import './custom.scss'
|
||||
|
||||
type Args = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const serverFunction: ServerFunctionClient = async function (args) {
|
||||
'use server'
|
||||
return handleServerFunctions({
|
||||
...args,
|
||||
config,
|
||||
importMap,
|
||||
})
|
||||
}
|
||||
|
||||
const Layout = ({ children }: Args) => (
|
||||
<RootLayout config={config} importMap={importMap} serverFunction={serverFunction}>
|
||||
{children}
|
||||
</RootLayout>
|
||||
)
|
||||
|
||||
export default Layout
|
||||
12
templates/with-cloudflare-d1/src/app/my-route/route.ts
Normal file
12
templates/with-cloudflare-d1/src/app/my-route/route.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import configPromise from '@payload-config'
|
||||
import { getPayload } from 'payload'
|
||||
|
||||
export const GET = async (request: Request) => {
|
||||
const payload = await getPayload({
|
||||
config: configPromise,
|
||||
})
|
||||
|
||||
return Response.json({
|
||||
message: 'This is an example of a custom route.',
|
||||
})
|
||||
}
|
||||
20
templates/with-cloudflare-d1/src/collections/Media.ts
Normal file
20
templates/with-cloudflare-d1/src/collections/Media.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
export const Media: CollectionConfig = {
|
||||
slug: 'media',
|
||||
access: {
|
||||
read: () => true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'alt',
|
||||
type: 'text',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
upload: {
|
||||
// These are not supported on Workers yet due to lack of sharp
|
||||
crop: false,
|
||||
focalPoint: false,
|
||||
},
|
||||
}
|
||||
13
templates/with-cloudflare-d1/src/collections/Users.ts
Normal file
13
templates/with-cloudflare-d1/src/collections/Users.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
export const Users: CollectionConfig = {
|
||||
slug: 'users',
|
||||
admin: {
|
||||
useAsTitle: 'email',
|
||||
},
|
||||
auth: true,
|
||||
fields: [
|
||||
// Email added by default
|
||||
// Add more fields as needed
|
||||
],
|
||||
}
|
||||
655
templates/with-cloudflare-d1/src/migrations/20250929_111647.json
Normal file
655
templates/with-cloudflare-d1/src/migrations/20250929_111647.json
Normal file
@@ -0,0 +1,655 @@
|
||||
{
|
||||
"version": "6",
|
||||
"dialect": "sqlite",
|
||||
"tables": {
|
||||
"users_sessions": {
|
||||
"name": "users_sessions",
|
||||
"columns": {
|
||||
"_order": {
|
||||
"name": "_order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"_parent_id": {
|
||||
"name": "_parent_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "text",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"users_sessions_order_idx": {
|
||||
"name": "users_sessions_order_idx",
|
||||
"columns": ["_order"],
|
||||
"isUnique": false
|
||||
},
|
||||
"users_sessions_parent_id_idx": {
|
||||
"name": "users_sessions_parent_id_idx",
|
||||
"columns": ["_parent_id"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"users_sessions_parent_id_fk": {
|
||||
"name": "users_sessions_parent_id_fk",
|
||||
"tableFrom": "users_sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": ["_parent_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"users": {
|
||||
"name": "users",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reset_password_token": {
|
||||
"name": "reset_password_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"reset_password_expiration": {
|
||||
"name": "reset_password_expiration",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"salt": {
|
||||
"name": "salt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"hash": {
|
||||
"name": "hash",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"login_attempts": {
|
||||
"name": "login_attempts",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false,
|
||||
"default": 0
|
||||
},
|
||||
"lock_until": {
|
||||
"name": "lock_until",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"users_updated_at_idx": {
|
||||
"name": "users_updated_at_idx",
|
||||
"columns": ["updated_at"],
|
||||
"isUnique": false
|
||||
},
|
||||
"users_created_at_idx": {
|
||||
"name": "users_created_at_idx",
|
||||
"columns": ["created_at"],
|
||||
"isUnique": false
|
||||
},
|
||||
"users_email_idx": {
|
||||
"name": "users_email_idx",
|
||||
"columns": ["email"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"media": {
|
||||
"name": "media",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"alt": {
|
||||
"name": "alt",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
},
|
||||
"url": {
|
||||
"name": "url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"thumbnail_u_r_l": {
|
||||
"name": "thumbnail_u_r_l",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"filename": {
|
||||
"name": "filename",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"mime_type": {
|
||||
"name": "mime_type",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"filesize": {
|
||||
"name": "filesize",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"width": {
|
||||
"name": "width",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"height": {
|
||||
"name": "height",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"media_updated_at_idx": {
|
||||
"name": "media_updated_at_idx",
|
||||
"columns": ["updated_at"],
|
||||
"isUnique": false
|
||||
},
|
||||
"media_created_at_idx": {
|
||||
"name": "media_created_at_idx",
|
||||
"columns": ["created_at"],
|
||||
"isUnique": false
|
||||
},
|
||||
"media_filename_idx": {
|
||||
"name": "media_filename_idx",
|
||||
"columns": ["filename"],
|
||||
"isUnique": true
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"payload_locked_documents": {
|
||||
"name": "payload_locked_documents",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"global_slug": {
|
||||
"name": "global_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"payload_locked_documents_global_slug_idx": {
|
||||
"name": "payload_locked_documents_global_slug_idx",
|
||||
"columns": ["global_slug"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_locked_documents_updated_at_idx": {
|
||||
"name": "payload_locked_documents_updated_at_idx",
|
||||
"columns": ["updated_at"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_locked_documents_created_at_idx": {
|
||||
"name": "payload_locked_documents_created_at_idx",
|
||||
"columns": ["created_at"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"payload_locked_documents_rels": {
|
||||
"name": "payload_locked_documents_rels",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"order": {
|
||||
"name": "order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"parent_id": {
|
||||
"name": "parent_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"path": {
|
||||
"name": "path",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"media_id": {
|
||||
"name": "media_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"payload_locked_documents_rels_order_idx": {
|
||||
"name": "payload_locked_documents_rels_order_idx",
|
||||
"columns": ["order"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_locked_documents_rels_parent_idx": {
|
||||
"name": "payload_locked_documents_rels_parent_idx",
|
||||
"columns": ["parent_id"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_locked_documents_rels_path_idx": {
|
||||
"name": "payload_locked_documents_rels_path_idx",
|
||||
"columns": ["path"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_locked_documents_rels_users_id_idx": {
|
||||
"name": "payload_locked_documents_rels_users_id_idx",
|
||||
"columns": ["users_id"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_locked_documents_rels_media_id_idx": {
|
||||
"name": "payload_locked_documents_rels_media_id_idx",
|
||||
"columns": ["media_id"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"payload_locked_documents_rels_parent_fk": {
|
||||
"name": "payload_locked_documents_rels_parent_fk",
|
||||
"tableFrom": "payload_locked_documents_rels",
|
||||
"tableTo": "payload_locked_documents",
|
||||
"columnsFrom": ["parent_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"payload_locked_documents_rels_users_fk": {
|
||||
"name": "payload_locked_documents_rels_users_fk",
|
||||
"tableFrom": "payload_locked_documents_rels",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": ["users_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"payload_locked_documents_rels_media_fk": {
|
||||
"name": "payload_locked_documents_rels_media_fk",
|
||||
"tableFrom": "payload_locked_documents_rels",
|
||||
"tableTo": "media",
|
||||
"columnsFrom": ["media_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"payload_preferences": {
|
||||
"name": "payload_preferences",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"key": {
|
||||
"name": "key",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"value": {
|
||||
"name": "value",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"payload_preferences_key_idx": {
|
||||
"name": "payload_preferences_key_idx",
|
||||
"columns": ["key"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_preferences_updated_at_idx": {
|
||||
"name": "payload_preferences_updated_at_idx",
|
||||
"columns": ["updated_at"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_preferences_created_at_idx": {
|
||||
"name": "payload_preferences_created_at_idx",
|
||||
"columns": ["created_at"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"payload_preferences_rels": {
|
||||
"name": "payload_preferences_rels",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"order": {
|
||||
"name": "order",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"parent_id": {
|
||||
"name": "parent_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"path": {
|
||||
"name": "path",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"users_id": {
|
||||
"name": "users_id",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"payload_preferences_rels_order_idx": {
|
||||
"name": "payload_preferences_rels_order_idx",
|
||||
"columns": ["order"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_preferences_rels_parent_idx": {
|
||||
"name": "payload_preferences_rels_parent_idx",
|
||||
"columns": ["parent_id"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_preferences_rels_path_idx": {
|
||||
"name": "payload_preferences_rels_path_idx",
|
||||
"columns": ["path"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_preferences_rels_users_id_idx": {
|
||||
"name": "payload_preferences_rels_users_id_idx",
|
||||
"columns": ["users_id"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"payload_preferences_rels_parent_fk": {
|
||||
"name": "payload_preferences_rels_parent_fk",
|
||||
"tableFrom": "payload_preferences_rels",
|
||||
"tableTo": "payload_preferences",
|
||||
"columnsFrom": ["parent_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
},
|
||||
"payload_preferences_rels_users_fk": {
|
||||
"name": "payload_preferences_rels_users_fk",
|
||||
"tableFrom": "payload_preferences_rels",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": ["users_id"],
|
||||
"columnsTo": ["id"],
|
||||
"onDelete": "cascade",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
},
|
||||
"payload_migrations": {
|
||||
"name": "payload_migrations",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "integer",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"autoincrement": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"batch": {
|
||||
"name": "batch",
|
||||
"type": "numeric",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"autoincrement": false
|
||||
},
|
||||
"updated_at": {
|
||||
"name": "updated_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"autoincrement": false,
|
||||
"default": "(strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))"
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"payload_migrations_updated_at_idx": {
|
||||
"name": "payload_migrations_updated_at_idx",
|
||||
"columns": ["updated_at"],
|
||||
"isUnique": false
|
||||
},
|
||||
"payload_migrations_created_at_idx": {
|
||||
"name": "payload_migrations_created_at_idx",
|
||||
"columns": ["created_at"],
|
||||
"isUnique": false
|
||||
}
|
||||
},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"checkConstraints": {}
|
||||
}
|
||||
},
|
||||
"views": {},
|
||||
"enums": {},
|
||||
"_meta": {
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"indexes": {}
|
||||
},
|
||||
"id": "892a870d-47bc-44f3-8237-e7d4c7022b26",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
157
templates/with-cloudflare-d1/src/migrations/20250929_111647.ts
Normal file
157
templates/with-cloudflare-d1/src/migrations/20250929_111647.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-d1-sqlite'
|
||||
|
||||
export async function up({ db, payload, req }: MigrateUpArgs): Promise<void> {
|
||||
await db.run(sql`CREATE TABLE \`users_sessions\` (
|
||||
\`_order\` integer NOT NULL,
|
||||
\`_parent_id\` integer NOT NULL,
|
||||
\`id\` text PRIMARY KEY NOT NULL,
|
||||
\`created_at\` text,
|
||||
\`expires_at\` text NOT NULL,
|
||||
FOREIGN KEY (\`_parent_id\`) REFERENCES \`users\`(\`id\`) ON UPDATE no action ON DELETE cascade
|
||||
);
|
||||
`)
|
||||
await db.run(sql`CREATE INDEX \`users_sessions_order_idx\` ON \`users_sessions\` (\`_order\`);`)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`users_sessions_parent_id_idx\` ON \`users_sessions\` (\`_parent_id\`);`,
|
||||
)
|
||||
await db.run(sql`CREATE TABLE \`users\` (
|
||||
\`id\` integer PRIMARY KEY NOT NULL,
|
||||
\`updated_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
|
||||
\`created_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
|
||||
\`email\` text NOT NULL,
|
||||
\`reset_password_token\` text,
|
||||
\`reset_password_expiration\` text,
|
||||
\`salt\` text,
|
||||
\`hash\` text,
|
||||
\`login_attempts\` numeric DEFAULT 0,
|
||||
\`lock_until\` text
|
||||
);
|
||||
`)
|
||||
await db.run(sql`CREATE INDEX \`users_updated_at_idx\` ON \`users\` (\`updated_at\`);`)
|
||||
await db.run(sql`CREATE INDEX \`users_created_at_idx\` ON \`users\` (\`created_at\`);`)
|
||||
await db.run(sql`CREATE UNIQUE INDEX \`users_email_idx\` ON \`users\` (\`email\`);`)
|
||||
await db.run(sql`CREATE TABLE \`media\` (
|
||||
\`id\` integer PRIMARY KEY NOT NULL,
|
||||
\`alt\` text NOT NULL,
|
||||
\`updated_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
|
||||
\`created_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
|
||||
\`url\` text,
|
||||
\`thumbnail_u_r_l\` text,
|
||||
\`filename\` text,
|
||||
\`mime_type\` text,
|
||||
\`filesize\` numeric,
|
||||
\`width\` numeric,
|
||||
\`height\` numeric
|
||||
);
|
||||
`)
|
||||
await db.run(sql`CREATE INDEX \`media_updated_at_idx\` ON \`media\` (\`updated_at\`);`)
|
||||
await db.run(sql`CREATE INDEX \`media_created_at_idx\` ON \`media\` (\`created_at\`);`)
|
||||
await db.run(sql`CREATE UNIQUE INDEX \`media_filename_idx\` ON \`media\` (\`filename\`);`)
|
||||
await db.run(sql`CREATE TABLE \`payload_locked_documents\` (
|
||||
\`id\` integer PRIMARY KEY NOT NULL,
|
||||
\`global_slug\` text,
|
||||
\`updated_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
|
||||
\`created_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL
|
||||
);
|
||||
`)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_global_slug_idx\` ON \`payload_locked_documents\` (\`global_slug\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_updated_at_idx\` ON \`payload_locked_documents\` (\`updated_at\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_created_at_idx\` ON \`payload_locked_documents\` (\`created_at\`);`,
|
||||
)
|
||||
await db.run(sql`CREATE TABLE \`payload_locked_documents_rels\` (
|
||||
\`id\` integer PRIMARY KEY NOT NULL,
|
||||
\`order\` integer,
|
||||
\`parent_id\` integer NOT NULL,
|
||||
\`path\` text NOT NULL,
|
||||
\`users_id\` integer,
|
||||
\`media_id\` integer,
|
||||
FOREIGN KEY (\`parent_id\`) REFERENCES \`payload_locked_documents\`(\`id\`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (\`users_id\`) REFERENCES \`users\`(\`id\`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (\`media_id\`) REFERENCES \`media\`(\`id\`) ON UPDATE no action ON DELETE cascade
|
||||
);
|
||||
`)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_rels_order_idx\` ON \`payload_locked_documents_rels\` (\`order\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_rels_parent_idx\` ON \`payload_locked_documents_rels\` (\`parent_id\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_rels_path_idx\` ON \`payload_locked_documents_rels\` (\`path\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_rels_users_id_idx\` ON \`payload_locked_documents_rels\` (\`users_id\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_locked_documents_rels_media_id_idx\` ON \`payload_locked_documents_rels\` (\`media_id\`);`,
|
||||
)
|
||||
await db.run(sql`CREATE TABLE \`payload_preferences\` (
|
||||
\`id\` integer PRIMARY KEY NOT NULL,
|
||||
\`key\` text,
|
||||
\`value\` text,
|
||||
\`updated_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
|
||||
\`created_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL
|
||||
);
|
||||
`)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_preferences_key_idx\` ON \`payload_preferences\` (\`key\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_preferences_updated_at_idx\` ON \`payload_preferences\` (\`updated_at\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_preferences_created_at_idx\` ON \`payload_preferences\` (\`created_at\`);`,
|
||||
)
|
||||
await db.run(sql`CREATE TABLE \`payload_preferences_rels\` (
|
||||
\`id\` integer PRIMARY KEY NOT NULL,
|
||||
\`order\` integer,
|
||||
\`parent_id\` integer NOT NULL,
|
||||
\`path\` text NOT NULL,
|
||||
\`users_id\` integer,
|
||||
FOREIGN KEY (\`parent_id\`) REFERENCES \`payload_preferences\`(\`id\`) ON UPDATE no action ON DELETE cascade,
|
||||
FOREIGN KEY (\`users_id\`) REFERENCES \`users\`(\`id\`) ON UPDATE no action ON DELETE cascade
|
||||
);
|
||||
`)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_preferences_rels_order_idx\` ON \`payload_preferences_rels\` (\`order\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_preferences_rels_parent_idx\` ON \`payload_preferences_rels\` (\`parent_id\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_preferences_rels_path_idx\` ON \`payload_preferences_rels\` (\`path\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_preferences_rels_users_id_idx\` ON \`payload_preferences_rels\` (\`users_id\`);`,
|
||||
)
|
||||
await db.run(sql`CREATE TABLE \`payload_migrations\` (
|
||||
\`id\` integer PRIMARY KEY NOT NULL,
|
||||
\`name\` text,
|
||||
\`batch\` numeric,
|
||||
\`updated_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL,
|
||||
\`created_at\` text DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')) NOT NULL
|
||||
);
|
||||
`)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_migrations_updated_at_idx\` ON \`payload_migrations\` (\`updated_at\`);`,
|
||||
)
|
||||
await db.run(
|
||||
sql`CREATE INDEX \`payload_migrations_created_at_idx\` ON \`payload_migrations\` (\`created_at\`);`,
|
||||
)
|
||||
}
|
||||
|
||||
export async function down({ db, payload, req }: MigrateDownArgs): Promise<void> {
|
||||
await db.run(sql`DROP TABLE \`users_sessions\`;`)
|
||||
await db.run(sql`DROP TABLE \`users\`;`)
|
||||
await db.run(sql`DROP TABLE \`media\`;`)
|
||||
await db.run(sql`DROP TABLE \`payload_locked_documents\`;`)
|
||||
await db.run(sql`DROP TABLE \`payload_locked_documents_rels\`;`)
|
||||
await db.run(sql`DROP TABLE \`payload_preferences\`;`)
|
||||
await db.run(sql`DROP TABLE \`payload_preferences_rels\`;`)
|
||||
await db.run(sql`DROP TABLE \`payload_migrations\`;`)
|
||||
}
|
||||
9
templates/with-cloudflare-d1/src/migrations/index.ts
Normal file
9
templates/with-cloudflare-d1/src/migrations/index.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import * as migration_20250929_111647 from './20250929_111647'
|
||||
|
||||
export const migrations = [
|
||||
{
|
||||
up: migration_20250929_111647.up,
|
||||
down: migration_20250929_111647.down,
|
||||
name: '20250929_111647',
|
||||
},
|
||||
]
|
||||
299
templates/with-cloudflare-d1/src/payload-types.ts
Normal file
299
templates/with-cloudflare-d1/src/payload-types.ts
Normal file
@@ -0,0 +1,299 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* This file was automatically generated by Payload.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
|
||||
* and re-run `payload generate:types` to regenerate this file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Supported timezones in IANA format.
|
||||
*
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "supportedTimezones".
|
||||
*/
|
||||
export type SupportedTimezones =
|
||||
| 'Pacific/Midway'
|
||||
| 'Pacific/Niue'
|
||||
| 'Pacific/Honolulu'
|
||||
| 'Pacific/Rarotonga'
|
||||
| 'America/Anchorage'
|
||||
| 'Pacific/Gambier'
|
||||
| 'America/Los_Angeles'
|
||||
| 'America/Tijuana'
|
||||
| 'America/Denver'
|
||||
| 'America/Phoenix'
|
||||
| 'America/Chicago'
|
||||
| 'America/Guatemala'
|
||||
| 'America/New_York'
|
||||
| 'America/Bogota'
|
||||
| 'America/Caracas'
|
||||
| 'America/Santiago'
|
||||
| 'America/Buenos_Aires'
|
||||
| 'America/Sao_Paulo'
|
||||
| 'Atlantic/South_Georgia'
|
||||
| 'Atlantic/Azores'
|
||||
| 'Atlantic/Cape_Verde'
|
||||
| 'Europe/London'
|
||||
| 'Europe/Berlin'
|
||||
| 'Africa/Lagos'
|
||||
| 'Europe/Athens'
|
||||
| 'Africa/Cairo'
|
||||
| 'Europe/Moscow'
|
||||
| 'Asia/Riyadh'
|
||||
| 'Asia/Dubai'
|
||||
| 'Asia/Baku'
|
||||
| 'Asia/Karachi'
|
||||
| 'Asia/Tashkent'
|
||||
| 'Asia/Calcutta'
|
||||
| 'Asia/Dhaka'
|
||||
| 'Asia/Almaty'
|
||||
| 'Asia/Jakarta'
|
||||
| 'Asia/Bangkok'
|
||||
| 'Asia/Shanghai'
|
||||
| 'Asia/Singapore'
|
||||
| 'Asia/Tokyo'
|
||||
| 'Asia/Seoul'
|
||||
| 'Australia/Brisbane'
|
||||
| 'Australia/Sydney'
|
||||
| 'Pacific/Guam'
|
||||
| 'Pacific/Noumea'
|
||||
| 'Pacific/Auckland'
|
||||
| 'Pacific/Fiji';
|
||||
|
||||
export interface Config {
|
||||
auth: {
|
||||
users: UserAuthOperations;
|
||||
};
|
||||
blocks: {};
|
||||
collections: {
|
||||
users: User;
|
||||
media: Media;
|
||||
'payload-locked-documents': PayloadLockedDocument;
|
||||
'payload-preferences': PayloadPreference;
|
||||
'payload-migrations': PayloadMigration;
|
||||
};
|
||||
collectionsJoins: {};
|
||||
collectionsSelect: {
|
||||
users: UsersSelect<false> | UsersSelect<true>;
|
||||
media: MediaSelect<false> | MediaSelect<true>;
|
||||
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
|
||||
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
|
||||
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
|
||||
};
|
||||
db: {
|
||||
defaultIDType: number;
|
||||
};
|
||||
globals: {};
|
||||
globalsSelect: {};
|
||||
locale: null;
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
};
|
||||
jobs: {
|
||||
tasks: unknown;
|
||||
workflows: unknown;
|
||||
};
|
||||
}
|
||||
export interface UserAuthOperations {
|
||||
forgotPassword: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
login: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
registerFirstUser: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
unlock: {
|
||||
email: string;
|
||||
password: string;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users".
|
||||
*/
|
||||
export interface User {
|
||||
id: number;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
email: string;
|
||||
resetPasswordToken?: string | null;
|
||||
resetPasswordExpiration?: string | null;
|
||||
salt?: string | null;
|
||||
hash?: string | null;
|
||||
loginAttempts?: number | null;
|
||||
lockUntil?: string | null;
|
||||
sessions?:
|
||||
| {
|
||||
id: string;
|
||||
createdAt?: string | null;
|
||||
expiresAt: string;
|
||||
}[]
|
||||
| null;
|
||||
password?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "media".
|
||||
*/
|
||||
export interface Media {
|
||||
id: number;
|
||||
alt: string;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
url?: string | null;
|
||||
thumbnailURL?: string | null;
|
||||
filename?: string | null;
|
||||
mimeType?: string | null;
|
||||
filesize?: number | null;
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
focalX?: number | null;
|
||||
focalY?: number | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents".
|
||||
*/
|
||||
export interface PayloadLockedDocument {
|
||||
id: number;
|
||||
document?:
|
||||
| ({
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'media';
|
||||
value: number | Media;
|
||||
} | null);
|
||||
globalSlug?: string | null;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences".
|
||||
*/
|
||||
export interface PayloadPreference {
|
||||
id: number;
|
||||
user: {
|
||||
relationTo: 'users';
|
||||
value: number | User;
|
||||
};
|
||||
key?: string | null;
|
||||
value?:
|
||||
| {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations".
|
||||
*/
|
||||
export interface PayloadMigration {
|
||||
id: number;
|
||||
name?: string | null;
|
||||
batch?: number | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "users_select".
|
||||
*/
|
||||
export interface UsersSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
email?: T;
|
||||
resetPasswordToken?: T;
|
||||
resetPasswordExpiration?: T;
|
||||
salt?: T;
|
||||
hash?: T;
|
||||
loginAttempts?: T;
|
||||
lockUntil?: T;
|
||||
sessions?:
|
||||
| T
|
||||
| {
|
||||
id?: T;
|
||||
createdAt?: T;
|
||||
expiresAt?: T;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "media_select".
|
||||
*/
|
||||
export interface MediaSelect<T extends boolean = true> {
|
||||
alt?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
url?: T;
|
||||
thumbnailURL?: T;
|
||||
filename?: T;
|
||||
mimeType?: T;
|
||||
filesize?: T;
|
||||
width?: T;
|
||||
height?: T;
|
||||
focalX?: T;
|
||||
focalY?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-locked-documents_select".
|
||||
*/
|
||||
export interface PayloadLockedDocumentsSelect<T extends boolean = true> {
|
||||
document?: T;
|
||||
globalSlug?: T;
|
||||
user?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-preferences_select".
|
||||
*/
|
||||
export interface PayloadPreferencesSelect<T extends boolean = true> {
|
||||
user?: T;
|
||||
key?: T;
|
||||
value?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "payload-migrations_select".
|
||||
*/
|
||||
export interface PayloadMigrationsSelect<T extends boolean = true> {
|
||||
name?: T;
|
||||
batch?: T;
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
*/
|
||||
export interface Auth {
|
||||
[k: string]: unknown;
|
||||
}
|
||||
|
||||
|
||||
declare module 'payload' {
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
53
templates/with-cloudflare-d1/src/payload.config.ts
Normal file
53
templates/with-cloudflare-d1/src/payload.config.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
// storage-adapter-import-placeholder
|
||||
import { sqliteD1Adapter } from '@payloadcms/db-d1-sqlite'
|
||||
import { payloadCloudPlugin } from '@payloadcms/payload-cloud'
|
||||
import { lexicalEditor } from '@payloadcms/richtext-lexical'
|
||||
import path from 'path'
|
||||
import { buildConfig } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { CloudflareContext, getCloudflareContext } from '@opennextjs/cloudflare'
|
||||
import { GetPlatformProxyOptions } from 'wrangler'
|
||||
import { r2Storage } from '@payloadcms/storage-r2'
|
||||
|
||||
import { Users } from './collections/Users'
|
||||
import { Media } from './collections/Media'
|
||||
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
|
||||
const cloudflare = process.argv.find((value) => value.match(/^(generate|migrate):?/))
|
||||
? await getCloudflareContextFromWrangler()
|
||||
: await getCloudflareContext({ async: true })
|
||||
|
||||
export default buildConfig({
|
||||
admin: {
|
||||
user: Users.slug,
|
||||
importMap: {
|
||||
baseDir: path.resolve(dirname),
|
||||
},
|
||||
},
|
||||
collections: [Users, Media],
|
||||
editor: lexicalEditor(),
|
||||
secret: process.env.PAYLOAD_SECRET || '',
|
||||
typescript: {
|
||||
outputFile: path.resolve(dirname, 'payload-types.ts'),
|
||||
},
|
||||
db: sqliteD1Adapter({ binding: cloudflare.env.D1 }),
|
||||
plugins: [
|
||||
payloadCloudPlugin(),
|
||||
r2Storage({
|
||||
bucket: cloudflare.env.R2,
|
||||
collections: { media: true },
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
// Adapted from https://github.com/opennextjs/opennextjs-cloudflare/blob/d00b3a13e42e65aad76fba41774815726422cc39/packages/cloudflare/src/api/cloudflare-context.ts#L328C36-L328C46
|
||||
function getCloudflareContextFromWrangler(): Promise<CloudflareContext> {
|
||||
return import(`${'__wrangler'.replaceAll('_', '')}`).then(({ getPlatformProxy }) =>
|
||||
getPlatformProxy({
|
||||
environment: process.env.CLOUDFLARE_ENV,
|
||||
experimental: { remoteBindings: process.env.NODE_ENV === 'production' },
|
||||
} satisfies GetPlatformProxyOptions),
|
||||
)
|
||||
}
|
||||
1
templates/with-cloudflare-d1/test.env
Normal file
1
templates/with-cloudflare-d1/test.env
Normal file
@@ -0,0 +1 @@
|
||||
NODE_OPTIONS="--no-deprecation --no-experimental-strip-types"
|
||||
20
templates/with-cloudflare-d1/tests/e2e/frontend.e2e.spec.ts
Normal file
20
templates/with-cloudflare-d1/tests/e2e/frontend.e2e.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { test, expect, Page } from '@playwright/test'
|
||||
|
||||
test.describe('Frontend', () => {
|
||||
let page: Page
|
||||
|
||||
test.beforeAll(async ({ browser }, testInfo) => {
|
||||
const context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
})
|
||||
|
||||
test('can go on homepage', async ({ page }) => {
|
||||
await page.goto('http://localhost:3000')
|
||||
|
||||
await expect(page).toHaveTitle(/Payload Blank Template/)
|
||||
|
||||
const headging = page.locator('h1').first()
|
||||
|
||||
await expect(headging).toHaveText('Welcome to your new project.')
|
||||
})
|
||||
})
|
||||
20
templates/with-cloudflare-d1/tests/int/api.int.spec.ts
Normal file
20
templates/with-cloudflare-d1/tests/int/api.int.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { getPayload, Payload } from 'payload'
|
||||
import config from '@/payload.config'
|
||||
|
||||
import { describe, it, beforeAll, expect } from 'vitest'
|
||||
|
||||
let payload: Payload
|
||||
|
||||
describe('API', () => {
|
||||
beforeAll(async () => {
|
||||
const payloadConfig = await config
|
||||
payload = await getPayload({ config: payloadConfig })
|
||||
})
|
||||
|
||||
it('fetches users', async () => {
|
||||
const users = await payload.find({
|
||||
collection: 'users',
|
||||
})
|
||||
expect(users).toBeDefined()
|
||||
})
|
||||
})
|
||||
45
templates/with-cloudflare-d1/tsconfig.json
Normal file
45
templates/with-cloudflare-d1/tsconfig.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"lib": [
|
||||
"DOM",
|
||||
"DOM.Iterable",
|
||||
"ES2022"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"strictNullChecks": false,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "next"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
],
|
||||
"@payload-config": [
|
||||
"./src/payload.config.ts"
|
||||
]
|
||||
},
|
||||
"target": "ES2022",
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".next/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
}
|
||||
12
templates/with-cloudflare-d1/vitest.config.mts
Normal file
12
templates/with-cloudflare-d1/vitest.config.mts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [tsconfigPaths(), react()],
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
setupFiles: ['./vitest.setup.ts'],
|
||||
include: ['tests/int/**/*.int.spec.ts'],
|
||||
},
|
||||
})
|
||||
4
templates/with-cloudflare-d1/vitest.setup.ts
Normal file
4
templates/with-cloudflare-d1/vitest.setup.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// Any setup scripts you might need go here
|
||||
|
||||
// Load .env files
|
||||
import 'dotenv/config'
|
||||
80
templates/with-cloudflare-d1/wrangler.jsonc
Normal file
80
templates/with-cloudflare-d1/wrangler.jsonc
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"$schema": "node_modules/wrangler/config-schema.json",
|
||||
"main": ".open-next/worker.js",
|
||||
"name": "my-app",
|
||||
"compatibility_date": "2025-05-05",
|
||||
"compatibility_flags": [
|
||||
// Enable Node.js API
|
||||
// see https://developers.cloudflare.com/workers/configuration/compatibility-flags/#nodejs-compatibility-flag
|
||||
"nodejs_compat",
|
||||
// Allow to fetch URLs in your app
|
||||
// see https://developers.cloudflare.com/workers/configuration/compatibility-flags/#global-fetch-strictly-public
|
||||
"global_fetch_strictly_public",
|
||||
// Enable MessagePort, used by undici
|
||||
"expose_global_message_channel",
|
||||
],
|
||||
"assets": {
|
||||
"directory": ".open-next/assets",
|
||||
"binding": "ASSETS",
|
||||
},
|
||||
"d1_databases": [
|
||||
{
|
||||
"binding": "D1",
|
||||
"database_id": "DATABASE_ID",
|
||||
"database_name": "my-app",
|
||||
"remote": true,
|
||||
},
|
||||
],
|
||||
"services": [
|
||||
// The service should match the "name" of your worker
|
||||
// {
|
||||
// "binding": "WORKER_SELF_REFERENCE",
|
||||
// "service": "my-app"
|
||||
// },
|
||||
],
|
||||
"r2_buckets": [
|
||||
{
|
||||
"binding": "R2",
|
||||
"bucket_name": "my-app",
|
||||
},
|
||||
// Create a R2 binding with the binding name "NEXT_INC_CACHE_R2_BUCKET"
|
||||
// {
|
||||
// "binding": "NEXT_INC_CACHE_R2_BUCKET",
|
||||
// "bucket_name": "<BUCKET_NAME>",
|
||||
// },
|
||||
],
|
||||
|
||||
// Here's how to configure an additional environment
|
||||
// It can be deployed with `CLOUDFLARE_ENV=staging npm run deploy`
|
||||
// "env": {
|
||||
// "staging": {
|
||||
// "name": "my-app-staging",
|
||||
// "d1_databases": [
|
||||
// {
|
||||
// "binding": "D1",
|
||||
// "database_id": "DATABASE_ID",
|
||||
// "database_name": "my-app-staging",
|
||||
// "experimental_remote": true
|
||||
// }
|
||||
// ],
|
||||
// "services": [
|
||||
// // The service should match the "name" of your worker
|
||||
// // {
|
||||
// // "binding": "WORKER_SELF_REFERENCE",
|
||||
// // "service": "my-app-staging"
|
||||
// // },
|
||||
// ],
|
||||
// "r2_buckets": [
|
||||
// {
|
||||
// "binding": "R2",
|
||||
// "bucket_name": "my-app-staging"
|
||||
// }
|
||||
// // Create a R2 binding with the binding name "NEXT_INC_CACHE_R2_BUCKET"
|
||||
// // {
|
||||
// // "binding": "NEXT_INC_CACHE_R2_BUCKET",
|
||||
// // "bucket_name": "<BUCKET_NAME>",
|
||||
// // },
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -113,6 +113,11 @@ export const allDatabaseAdapters = {
|
||||
process.env.POSTGRES_URL || 'postgresql://postgres:postgres@127.0.0.1:54322/postgres',
|
||||
},
|
||||
})`,
|
||||
d1: `
|
||||
import { sqliteD1Adapter } from '@payloadcms/db-d1-sqlite'
|
||||
|
||||
export const databaseAdapter = sqliteD1Adapter({ binding: global.d1 })
|
||||
`,
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user