Bump version to 0.0.5

This commit is contained in:
2025-09-28 18:18:40 +02:00
parent 5b3cac12c3
commit d0acfd058a
3 changed files with 188 additions and 205 deletions

1
.gitignore vendored
View File

@@ -47,3 +47,4 @@ yarn-error.log*
/playwright-report/
/blob-report/
/playwright/.cache/
/dev.db

View File

@@ -1,6 +1,5 @@
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import { MongoMemoryReplSet } from 'mongodb-memory-server'
import path from 'path'
import { buildConfig } from 'payload'
import { payloadFeatureFlags } from '../src/index.js'
@@ -9,6 +8,7 @@ import { fileURLToPath } from 'url'
import { testEmailAdapter } from './helpers/testEmailAdapter.js'
import { seed } from './seed.js'
import {sqliteAdapter} from "@payloadcms/db-sqlite"
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@@ -17,221 +17,203 @@ if (!process.env.ROOT_DIR) {
process.env.ROOT_DIR = dirname
}
const buildConfigWithMemoryDB = async () => {
// Use in-memory MongoDB for both test and development
if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV !== 'production') {
console.log('🗃️ Starting MongoDB Memory Server...')
const memoryDB = await MongoMemoryReplSet.create({
replSet: {
count: 1,
dbName: 'payload-feature-flags-dev',
export default buildConfig({
admin: {
importMap: {
baseDir: path.resolve(dirname),
},
},
collections: [
{
slug: 'posts',
admin: {
useAsTitle: 'title',
},
})
const uri = memoryDB.getUri()
process.env.DATABASE_URI = `${uri}&retryWrites=true`
console.log('✅ MongoDB Memory Server started successfully')
}
return buildConfig({
admin: {
importMap: {
baseDir: path.resolve(dirname),
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
name: 'content',
type: 'richText',
},
{
name: 'status',
type: 'select',
options: ['draft', 'published'],
defaultValue: 'draft',
},
{
name: 'publishedAt',
type: 'date',
},
],
},
{
slug: 'pages',
admin: {
useAsTitle: 'title',
},
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
name: 'slug',
type: 'text',
required: true,
unique: true,
},
{
name: 'content',
type: 'richText',
},
{
name: 'layout',
type: 'select',
options: ['default', 'landing', 'sidebar'],
defaultValue: 'default',
},
],
},
{
slug: 'users',
admin: {
useAsTitle: 'email',
},
auth: true,
fields: [
{
name: 'name',
type: 'text',
},
{
name: 'role',
type: 'select',
options: ['admin', 'editor', 'user'],
defaultValue: 'user',
},
],
},
{
slug: 'media',
fields: [
{
name: 'alt',
type: 'text',
},
],
upload: {
staticDir: path.resolve(dirname, 'media'),
},
},
collections: [
{
slug: 'posts',
],
db: sqliteAdapter({
client: {
url: process.env.DATABASE_URI || 'file:./dev.db',
},
}),
editor: lexicalEditor(),
email: testEmailAdapter,
onInit: async (payload) => {
await seed(payload)
},
plugins: [
payloadFeatureFlags({
// Enable all features
enableRollouts: true,
enableVariants: true,
enableApi: true,
defaultValue: false,
// Custom collection configuration
collectionOverrides: {
admin: {
useAsTitle: 'title',
useAsTitle: 'name',
group: 'Configuration',
description: 'Manage feature flags for the development environment',
},
fields: [
access: {
// Only authenticated users can read/manage feature flags
read: ({ req: { user } }) => !!user,
create: ({ req: { user } }) => !!user,
update: ({ req: { user } }) => user?.role === 'admin',
delete: ({ req: { user } }) => user?.role === 'admin',
},
fields: ({ defaultFields }) => [
...defaultFields,
{
name: 'title',
type: 'text',
required: true,
},
{
name: 'content',
type: 'richText',
},
{
name: 'status',
name: 'environment',
type: 'select',
options: ['draft', 'published'],
defaultValue: 'draft',
options: [
{ label: 'Development', value: 'development' },
{ label: 'Staging', value: 'staging' },
{ label: 'Production', value: 'production' },
],
required: true,
defaultValue: 'development',
admin: {
description: 'Which environment this flag applies to',
},
},
{
name: 'publishedAt',
name: 'owner',
type: 'relationship',
relationTo: 'users',
admin: {
description: 'Team member responsible for this feature flag',
},
},
{
name: 'expiresAt',
type: 'date',
admin: {
description: 'Optional expiration date for temporary flags',
},
},
{
name: 'jiraTicket',
type: 'text',
admin: {
description: 'Related JIRA ticket or issue number',
},
},
],
},
{
slug: 'pages',
admin: {
useAsTitle: 'title',
},
fields: [
{
name: 'title',
type: 'text',
required: true,
},
{
name: 'slug',
type: 'text',
required: true,
unique: true,
},
{
name: 'content',
type: 'richText',
},
{
name: 'layout',
type: 'select',
options: ['default', 'landing', 'sidebar'],
defaultValue: 'default',
},
],
},
{
slug: 'users',
admin: {
useAsTitle: 'email',
},
auth: true,
fields: [
{
name: 'name',
type: 'text',
},
{
name: 'role',
type: 'select',
options: ['admin', 'editor', 'user'],
defaultValue: 'user',
},
],
},
{
slug: 'media',
fields: [
{
name: 'alt',
type: 'text',
},
],
upload: {
staticDir: path.resolve(dirname, 'media'),
},
},
],
db: mongooseAdapter({
ensureIndexes: true,
url: process.env.DATABASE_URI || 'mongodb://localhost/payload-feature-flags-dev',
}),
editor: lexicalEditor(),
email: testEmailAdapter,
onInit: async (payload) => {
await seed(payload)
},
plugins: [
payloadFeatureFlags({
// Enable all features
enableRollouts: true,
enableVariants: true,
enableApi: true,
defaultValue: false,
hooks: {
beforeChange: [
async ({ data, req, operation }) => {
// Auto-assign current user as owner for new flags
if (operation === 'create' && !data.owner && req.user) {
data.owner = req.user.id
}
// Custom collection configuration
collectionOverrides: {
admin: {
useAsTitle: 'name',
group: 'Configuration',
description: 'Manage feature flags for the development environment',
},
access: {
// Only authenticated users can read/manage feature flags
read: ({ req: { user } }) => !!user,
create: ({ req: { user } }) => !!user,
update: ({ req: { user } }) => user?.role === 'admin',
delete: ({ req: { user } }) => user?.role === 'admin',
},
fields: ({ defaultFields }) => [
...defaultFields,
{
name: 'environment',
type: 'select',
options: [
{ label: 'Development', value: 'development' },
{ label: 'Staging', value: 'staging' },
{ label: 'Production', value: 'production' },
],
required: true,
defaultValue: 'development',
admin: {
description: 'Which environment this flag applies to',
},
},
{
name: 'owner',
type: 'relationship',
relationTo: 'users',
admin: {
description: 'Team member responsible for this feature flag',
},
},
{
name: 'expiresAt',
type: 'date',
admin: {
description: 'Optional expiration date for temporary flags',
},
},
{
name: 'jiraTicket',
type: 'text',
admin: {
description: 'Related JIRA ticket or issue number',
},
// Log flag changes for audit trail
if (req.user) {
console.log(`Feature flag "${data.name}" ${operation} by ${req.user.email}`)
}
return data
},
],
afterChange: [
async ({ doc, req, operation }) => {
// Send notification for critical flag changes
if (doc.environment === 'production' && req.user) {
console.log(`🚨 Production feature flag "${doc.name}" was ${operation === 'create' ? 'created' : 'modified'} by ${req.user.email}`)
}
},
],
hooks: {
beforeChange: [
async ({ data, req, operation }) => {
// Auto-assign current user as owner for new flags
if (operation === 'create' && !data.owner && req.user) {
data.owner = req.user.id
}
// Log flag changes for audit trail
if (req.user) {
console.log(`Feature flag "${data.name}" ${operation} by ${req.user.email}`)
}
return data
},
],
afterChange: [
async ({ doc, req, operation }) => {
// Send notification for critical flag changes
if (doc.environment === 'production' && req.user) {
console.log(`🚨 Production feature flag "${doc.name}" was ${operation === 'create' ? 'created' : 'modified'} by ${req.user.email}`)
}
},
],
},
},
}),
],
secret: process.env.PAYLOAD_SECRET || 'dev-secret-key-change-in-production',
sharp,
typescript: {
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
})
}
export default buildConfigWithMemoryDB()
},
}),
],
secret: process.env.PAYLOAD_SECRET || 'dev-secret-key-change-in-production',
sharp,
typescript: {
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
})

View File

@@ -1,6 +1,6 @@
{
"name": "@xtr-dev/payload-feature-flags",
"version": "0.0.4",
"version": "0.0.5",
"description": "Feature flags plugin for Payload CMS - manage feature toggles, A/B tests, and gradual rollouts",
"license": "MIT",
"type": "module",