@kiryl.pekarski/payload-plugin-ab 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { S as StorageAdapter } from '../../config-CQrzAj5Q.js';
1
+ import { S as StorageAdapter } from '../../config-Bq-Mi7k_.js';
2
2
  import 'payload';
3
3
 
4
4
  interface PayloadGlobalAdapterConfig {
@@ -1,4 +1,4 @@
1
- import { S as StorageAdapter } from '../../config-CQrzAj5Q.js';
1
+ import { S as StorageAdapter } from '../../config-Bq-Mi7k_.js';
2
2
  import 'payload';
3
3
 
4
4
  interface VercelEdgeAdapterConfig {
@@ -22,9 +22,7 @@ interface CollectionABConfig<TVariantData extends object = object> {
22
22
  * Default: 'page'
23
23
  */
24
24
  parentField?: string;
25
- /**
26
- * Optional: dot-notation path to the tenant field on the variant document.
27
- */
25
+ /** Optional: dot-notation path to the tenant field on the parent document. */
28
26
  tenantField?: string;
29
27
  generatePath: (args: {
30
28
  doc: Record<string, unknown>;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Plugin } from 'payload';
2
- import { A as AbTestingPluginConfig } from './config-CQrzAj5Q.js';
3
- export { C as CollectionABConfig, S as StorageAdapter } from './config-CQrzAj5Q.js';
2
+ import { A as AbTestingPluginConfig } from './config-Bq-Mi7k_.js';
3
+ export { C as CollectionABConfig, S as StorageAdapter } from './config-Bq-Mi7k_.js';
4
4
  export { A as AbCookieConfig, R as ResolvedAbCookieNames, r as resolveAbCookieNames } from './resolveAbCookieNames-DH8evjWm.js';
5
5
 
6
6
  declare const abTestingPlugin: <TVariantData extends object>(pluginConfig: AbTestingPluginConfig<TVariantData>) => Plugin;
package/dist/index.js CHANGED
@@ -29,15 +29,30 @@ function getLocales(payload) {
29
29
  return locales.map((l) => typeof l === "string" ? l : l.code);
30
30
  }
31
31
 
32
+ // src/utils/getNestedValue.ts
33
+ function getNestedValue(obj, path) {
34
+ return path.split(".").reduce((acc, key) => {
35
+ if (acc !== null && typeof acc === "object") {
36
+ return acc[key];
37
+ }
38
+ return void 0;
39
+ }, obj);
40
+ }
41
+
42
+ // src/constants.ts
43
+ var DEFAULT_PASS_PERCENTAGE_FIELD = "passPercentage";
44
+ var DEFAULT_PARENT_FIELD = "page";
45
+
32
46
  // src/hooks/buildAfterChangeHook.ts
33
47
  function buildAfterChangeHook(parentCollectionSlug, abConfig, pluginConfig) {
34
48
  return async ({ doc, req, previousDoc }) => {
35
49
  const { payload } = req;
36
50
  if (!payload) return;
37
- const pageId = resolveId(doc.page);
51
+ const parentFieldPath = abConfig.parentField ?? DEFAULT_PARENT_FIELD;
52
+ const pageId = resolveId(getNestedValue(doc, parentFieldPath));
38
53
  if (!pageId) return;
39
54
  const locales = getLocales(payload);
40
- const previousPageId = previousDoc ? resolveId(previousDoc.page) : null;
55
+ const previousPageId = previousDoc ? resolveId(getNestedValue(previousDoc, parentFieldPath)) : null;
41
56
  if (previousPageId && previousPageId !== pageId) {
42
57
  for (const locale of locales) {
43
58
  const oldPageDoc = await payload.findByID({
@@ -54,7 +69,7 @@ function buildAfterChangeHook(parentCollectionSlug, abConfig, pluginConfig) {
54
69
  const remainingOldVariants = await payload.find({
55
70
  collection: abConfig.variantCollectionSlug,
56
71
  where: {
57
- and: [{ page: { equals: previousPageId } }, { id: { not_equals: doc.id } }]
72
+ and: [{ [parentFieldPath]: { equals: previousPageId } }, { id: { not_equals: doc.id } }]
58
73
  },
59
74
  depth: 2,
60
75
  locale,
@@ -86,7 +101,7 @@ function buildAfterChangeHook(parentCollectionSlug, abConfig, pluginConfig) {
86
101
  if (!manifestKey) continue;
87
102
  const allVariants = await payload.find({
88
103
  collection: abConfig.variantCollectionSlug,
89
- where: { page: { equals: pageId } },
104
+ where: { [parentFieldPath]: { equals: pageId } },
90
105
  depth: 2,
91
106
  locale,
92
107
  overrideAccess: true,
@@ -106,7 +121,8 @@ function buildAfterDeleteHook(parentCollectionSlug, abConfig, pluginConfig) {
106
121
  return async ({ doc, req, id }) => {
107
122
  const { payload } = req;
108
123
  if (!payload) return;
109
- const pageId = resolveId(doc.page);
124
+ const parentFieldPath = abConfig.parentField ?? DEFAULT_PARENT_FIELD;
125
+ const pageId = resolveId(getNestedValue(doc, parentFieldPath));
110
126
  if (!pageId) return;
111
127
  const locales = getLocales(payload);
112
128
  for (const locale of locales) {
@@ -124,7 +140,7 @@ function buildAfterDeleteHook(parentCollectionSlug, abConfig, pluginConfig) {
124
140
  const remainingVariants = await payload.find({
125
141
  collection: abConfig.variantCollectionSlug,
126
142
  where: {
127
- and: [{ page: { equals: pageId } }, { id: { not_equals: id } }]
143
+ and: [{ [parentFieldPath]: { equals: pageId } }, { id: { not_equals: id } }]
128
144
  },
129
145
  depth: 2,
130
146
  locale,
@@ -146,16 +162,8 @@ function buildAfterDeleteHook(parentCollectionSlug, abConfig, pluginConfig) {
146
162
 
147
163
  // src/hooks/validateVariantPercentageSum.ts
148
164
  import { ValidationError } from "payload";
149
- function getNestedValue(obj, path) {
150
- return path.split(".").reduce((acc, key) => {
151
- if (acc !== null && typeof acc === "object") {
152
- return acc[key];
153
- }
154
- return void 0;
155
- }, obj);
156
- }
157
165
  function createValidateVariantPercentageSum(config) {
158
- const { variantCollectionSlug, parentField, passPercentageField, tenantField } = config;
166
+ const { variantCollectionSlug, parentCollectionSlug, parentField, passPercentageField, tenantField } = config;
159
167
  return async ({ data, originalDoc, req, operation }) => {
160
168
  const passPercentage = getNestedValue(data, passPercentageField);
161
169
  if (passPercentage === void 0 || passPercentage === null) return data;
@@ -163,9 +171,18 @@ function createValidateVariantPercentageSum(config) {
163
171
  if (!parentId) return data;
164
172
  const andConditions = [{ [parentField]: { equals: parentId } }];
165
173
  if (tenantField) {
166
- const tenantId = resolveId(getNestedValue(data, tenantField));
167
- if (tenantId) {
168
- andConditions.push({ [tenantField]: { equals: tenantId } });
174
+ const parentDoc = await req.payload.findByID({
175
+ collection: parentCollectionSlug,
176
+ id: parentId,
177
+ depth: 0,
178
+ overrideAccess: true,
179
+ req
180
+ });
181
+ if (parentDoc) {
182
+ const tenantId = resolveId(getNestedValue(parentDoc, tenantField));
183
+ if (tenantId) {
184
+ andConditions.push({ [`${parentField}.${tenantField}`]: { equals: tenantId } });
185
+ }
169
186
  }
170
187
  }
171
188
  if (operation === "update" && originalDoc?.id) {
@@ -227,10 +244,6 @@ function isFieldPathExists(fields, path) {
227
244
  return false;
228
245
  }
229
246
 
230
- // src/constants.ts
231
- var DEFAULT_PASS_PERCENTAGE_FIELD = "passPercentage";
232
- var DEFAULT_PARENT_FIELD = "page";
233
-
234
247
  // src/utils/addHooksToVariantCollections.ts
235
248
  function addHooksToVariantCollections(config, pluginConfig, variantToParent) {
236
249
  const patchedCollections = (config.collections ?? []).map((collection) => {
@@ -248,6 +261,7 @@ function addHooksToVariantCollections(config, pluginConfig, variantToParent) {
248
261
  beforeChangeHooks.push(
249
262
  createValidateVariantPercentageSum({
250
263
  variantCollectionSlug: abConfig.variantCollectionSlug,
264
+ parentCollectionSlug: parentSlug,
251
265
  parentField: abConfig.parentField ?? DEFAULT_PARENT_FIELD,
252
266
  passPercentageField: resolvedPassPercentageField,
253
267
  tenantField: abConfig.tenantField
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/buildVariantToParentCollectionSlugsMap.ts","../src/utils/resolveId.ts","../src/utils/getLocales.ts","../src/hooks/buildAfterChangeHook.ts","../src/hooks/buildAfterDeleteHook.ts","../src/hooks/validateVariantPercentageSum.ts","../src/utils/isFieldPathExists.ts","../src/constants.ts","../src/utils/addHooksToVariantCollections.ts","../src/plugin.ts","../src/cookie/utils/defaultGetExpCookieName.ts","../src/cookie/constants.ts","../src/cookie/utils/resolveAbCookieNames.ts"],"sourcesContent":["import type { CollectionABConfig } from \"../types/config\";\n\nexport function buildVariantToParentCollectionSlugsMap<TVariantData extends object>(\n collections: Record<string, CollectionABConfig<TVariantData>>,\n) {\n const variantToParent = new Map<string, string>();\n\n for (const [parentSlug, abConfig] of Object.entries(collections)) {\n if (abConfig) variantToParent.set(abConfig.variantCollectionSlug, parentSlug);\n }\n\n return variantToParent;\n}\n","interface BaseDocument {\n id: number | string;\n}\n\nconst isValueIsBaseDocument = (value: object): value is BaseDocument => {\n return \"id\" in value;\n};\n\nexport function resolveId(value: unknown) {\n if (!value) return null;\n\n if (typeof value === \"number\" || typeof value === \"string\") return value;\n\n if (typeof value === \"object\" && isValueIsBaseDocument(value)) {\n return value.id;\n }\n\n return null;\n}\n","import type { Payload } from \"payload\";\n\nexport function getLocales(payload: Payload): (string | undefined)[] {\n const { localization } = payload.config;\n\n if (!localization) return [undefined];\n\n const { locales } = localization;\n\n if (!locales?.length) return [undefined];\n\n return locales.map((l) => (typeof l === \"string\" ? l : l.code));\n}\n","import type { CollectionAfterChangeHook, CollectionSlug, TypedLocale } from \"payload\";\nimport type { AbTestingPluginConfig, CollectionABConfig } from \"../types/config\";\nimport { resolveId } from \"../utils/resolveId\";\nimport { getLocales } from \"../utils/getLocales\";\n\nexport function buildAfterChangeHook<TVariantData extends object>(\n parentCollectionSlug: string,\n abConfig: CollectionABConfig<TVariantData>,\n pluginConfig: AbTestingPluginConfig<TVariantData>,\n): CollectionAfterChangeHook {\n return async ({ doc, req, previousDoc }) => {\n const { payload } = req;\n if (!payload) return;\n\n const pageId = resolveId(doc.page);\n if (!pageId) return;\n\n const locales = getLocales(payload);\n\n const previousPageId = previousDoc ? resolveId(previousDoc.page) : null;\n if (previousPageId && previousPageId !== pageId) {\n for (const locale of locales) {\n const oldPageDoc = await payload.findByID({\n collection: parentCollectionSlug as CollectionSlug,\n id: previousPageId,\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n req,\n });\n if (!oldPageDoc) continue;\n\n const oldManifestKey = abConfig.generatePath({ doc: oldPageDoc, locale });\n if (!oldManifestKey) continue;\n\n const remainingOldVariants = await payload.find({\n collection: abConfig.variantCollectionSlug as CollectionSlug,\n where: {\n and: [{ page: { equals: previousPageId } }, { id: { not_equals: doc.id } }],\n },\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n limit: 100,\n req,\n });\n\n if (remainingOldVariants.docs.length === 0) {\n await pluginConfig.storage.clear(oldManifestKey, payload);\n } else {\n const oldVariantData = remainingOldVariants.docs.map((variantDoc) =>\n abConfig.generateVariantData({ doc: oldPageDoc, variantDoc, locale }),\n );\n await pluginConfig.storage.write(oldManifestKey, oldVariantData, payload);\n }\n }\n }\n\n for (const locale of locales) {\n const pageDoc = await payload.findByID({\n collection: parentCollectionSlug as CollectionSlug,\n id: pageId,\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n req,\n });\n if (!pageDoc) continue;\n\n const manifestKey = abConfig.generatePath({ doc: pageDoc, locale });\n if (!manifestKey) continue;\n\n const allVariants = await payload.find({\n collection: abConfig.variantCollectionSlug as CollectionSlug,\n where: { page: { equals: pageId } },\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n limit: 100,\n req,\n });\n\n const variantData = allVariants.docs.map((variantDoc) =>\n abConfig.generateVariantData({ doc: pageDoc, variantDoc, locale }),\n );\n\n await pluginConfig.storage.write(manifestKey, variantData, payload);\n }\n };\n}\n","import type { CollectionAfterDeleteHook, CollectionSlug, TypedLocale } from \"payload\";\nimport type { AbTestingPluginConfig, CollectionABConfig } from \"../types/config\";\nimport { resolveId } from \"../utils/resolveId\";\nimport { getLocales } from \"../utils/getLocales\";\n\nexport function buildAfterDeleteHook<TVariantData extends object>(\n parentCollectionSlug: string,\n abConfig: CollectionABConfig<TVariantData>,\n pluginConfig: AbTestingPluginConfig<TVariantData>,\n): CollectionAfterDeleteHook {\n return async ({ doc, req, id }) => {\n const { payload } = req;\n if (!payload) return;\n\n const pageId = resolveId(doc.page);\n if (!pageId) return;\n\n const locales = getLocales(payload);\n\n for (const locale of locales) {\n const pageDoc = await payload.findByID({\n collection: parentCollectionSlug as CollectionSlug,\n id: pageId,\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n req,\n });\n if (!pageDoc) continue;\n\n const manifestKey = abConfig.generatePath({ doc: pageDoc, locale });\n if (!manifestKey) continue;\n\n const remainingVariants = await payload.find({\n collection: abConfig.variantCollectionSlug as CollectionSlug,\n where: {\n and: [{ page: { equals: pageId } }, { id: { not_equals: id } }],\n },\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n limit: 100,\n req,\n });\n\n if (remainingVariants.docs.length === 0) {\n await pluginConfig.storage.clear(manifestKey, payload);\n } else {\n const variantData = remainingVariants.docs.map((variantDoc) =>\n abConfig.generateVariantData({ doc: pageDoc, variantDoc, locale }),\n );\n\n await pluginConfig.storage.write(manifestKey, variantData, payload);\n }\n }\n };\n}\n","import { ValidationError } from \"payload\";\nimport type { CollectionBeforeChangeHook, CollectionSlug, Where } from \"payload\";\nimport { resolveId } from \"../utils/resolveId\";\n\nfunction getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n return path.split(\".\").reduce((acc: unknown, key) => {\n if (acc !== null && typeof acc === \"object\") {\n return (acc as Record<string, unknown>)[key];\n }\n\n return undefined;\n }, obj);\n}\n\ninterface ValidateVariantPercentageSumConfig {\n variantCollectionSlug: CollectionSlug;\n parentField: string;\n passPercentageField: string;\n tenantField?: string;\n}\n\nexport function createValidateVariantPercentageSum(\n config: ValidateVariantPercentageSumConfig,\n): CollectionBeforeChangeHook {\n const { variantCollectionSlug, parentField, passPercentageField, tenantField } = config;\n\n return async ({ data, originalDoc, req, operation }) => {\n const passPercentage = getNestedValue(data, passPercentageField);\n if (passPercentage === undefined || passPercentage === null) return data;\n\n const parentId = resolveId(getNestedValue(data, parentField));\n if (!parentId) return data;\n\n const andConditions: Where[] = [{ [parentField]: { equals: parentId } }];\n\n if (tenantField) {\n const tenantId = resolveId(getNestedValue(data, tenantField));\n if (tenantId) {\n andConditions.push({ [tenantField]: { equals: tenantId } });\n }\n }\n\n if (operation === \"update\" && originalDoc?.id) {\n andConditions.push({ id: { not_equals: originalDoc.id } });\n }\n\n const { docs: siblings } = await req.payload.find({\n collection: variantCollectionSlug,\n where: { and: andConditions },\n depth: 0,\n req,\n });\n\n const existingSum = siblings.reduce((sum, doc) => {\n const percentage = getNestedValue(doc, passPercentageField);\n\n return sum + (typeof percentage === \"number\" ? percentage : 0);\n }, 0);\n\n if (existingSum + (passPercentage as number) > 100) {\n const remaining = 100 - existingSum;\n throw new ValidationError({\n errors: [\n {\n path: passPercentageField,\n message: `Total variant traffic for this page is ${existingSum}%. This variant cannot exceed ${remaining}% (would exceed 100%).`,\n },\n ],\n });\n }\n\n return data;\n };\n}\n","import type { Field } from \"payload\";\n\ntype TabLike = { name?: string; fields: Field[] };\n\ntype TabsFieldLike = { type: \"tabs\"; tabs: TabLike[] };\n\ntype FieldsContainer = { fields: Field[] };\n\nexport function isFieldPathExists(fields: Field[], path: string): boolean {\n const [head, ...rest] = path.split(\".\");\n\n for (const field of fields) {\n // Named fields\n if (\"name\" in field && field.name === head) {\n if (rest.length === 0) return true;\n\n if (\"fields\" in field && Array.isArray((field as unknown as FieldsContainer).fields)) {\n return isFieldPathExists((field as unknown as FieldsContainer).fields, rest.join(\".\"));\n }\n\n return false;\n }\n\n // Tabs field\n if (field.type === \"tabs\") {\n const { tabs } = field as unknown as TabsFieldLike;\n\n for (const tab of tabs) {\n if (tab.name) {\n if (tab.name === head) {\n if (rest.length === 0) return true;\n\n if (isFieldPathExists(tab.fields, rest.join(\".\"))) return true;\n }\n } else {\n if (isFieldPathExists(tab.fields, path)) return true;\n }\n }\n }\n\n // Transparent layout fields\n if (\n (field.type === \"row\" || field.type === \"collapsible\")\n && \"fields\" in field\n && Array.isArray((field as unknown as FieldsContainer).fields)\n ) {\n if (isFieldPathExists((field as unknown as FieldsContainer).fields, path)) return true;\n }\n }\n\n return false;\n}\n","export const DEFAULT_PASS_PERCENTAGE_FIELD = \"passPercentage\";\nexport const DEFAULT_PARENT_FIELD = \"page\";\n","import type { CollectionConfig, CollectionSlug, Config } from \"payload\";\nimport type { AbTestingPluginConfig } from \"../types/config\";\nimport { buildAfterChangeHook } from \"../hooks/buildAfterChangeHook\";\nimport { buildAfterDeleteHook } from \"../hooks/buildAfterDeleteHook\";\nimport { createValidateVariantPercentageSum } from \"../hooks/validateVariantPercentageSum\";\nimport { isFieldPathExists } from \"./isFieldPathExists\";\nimport { DEFAULT_PARENT_FIELD, DEFAULT_PASS_PERCENTAGE_FIELD } from \"../constants\";\n\nexport function addHooksToVariantCollections<TVariantData extends object>(\n config: Config,\n pluginConfig: AbTestingPluginConfig<TVariantData>,\n variantToParent: Map<string, string>,\n) {\n const patchedCollections = (config.collections ?? []).map((collection) => {\n const parentSlug = variantToParent.get(collection.slug);\n if (!parentSlug) return collection;\n\n const abConfig = pluginConfig.collections[parentSlug];\n if (!abConfig) return collection;\n\n let resolvedPassPercentageField: string | null = null;\n\n const passPercentagePath =\n typeof abConfig.passPercentageField === \"string\" ? abConfig.passPercentageField : DEFAULT_PASS_PERCENTAGE_FIELD;\n\n if (isFieldPathExists(collection.fields, passPercentagePath)) {\n resolvedPassPercentageField = passPercentagePath;\n }\n\n const beforeChangeHooks = [...(collection.hooks?.beforeChange ?? [])];\n\n if (resolvedPassPercentageField) {\n beforeChangeHooks.push(\n createValidateVariantPercentageSum({\n variantCollectionSlug: abConfig.variantCollectionSlug as CollectionSlug,\n parentField: abConfig.parentField ?? DEFAULT_PARENT_FIELD,\n passPercentageField: resolvedPassPercentageField,\n tenantField: abConfig.tenantField,\n }),\n );\n }\n\n return {\n ...collection,\n hooks: {\n ...collection.hooks,\n beforeChange: beforeChangeHooks,\n afterChange: [\n ...(collection.hooks?.afterChange ?? []),\n buildAfterChangeHook(parentSlug, abConfig, pluginConfig),\n ],\n afterDelete: [\n ...(collection.hooks?.afterDelete ?? []),\n buildAfterDeleteHook(parentSlug, abConfig, pluginConfig),\n ],\n },\n } as CollectionConfig;\n });\n\n return patchedCollections;\n}\n","import type { Config, Plugin } from \"payload\";\nimport type { AbTestingPluginConfig } from \"./types/config\";\nimport { buildVariantToParentCollectionSlugsMap } from \"./utils/buildVariantToParentCollectionSlugsMap\";\nimport { addHooksToVariantCollections } from \"./utils/addHooksToVariantCollections\";\n\nexport const abTestingPlugin =\n <TVariantData extends object>(pluginConfig: AbTestingPluginConfig<TVariantData>): Plugin =>\n (incomingConfig: Config): Config => {\n const { enabled = true, debug = false, collections, storage } = pluginConfig;\n\n if (!enabled) return incomingConfig;\n\n const extraGlobals = storage.createGlobal ? [storage.createGlobal(debug)] : [];\n\n const variantToParent = buildVariantToParentCollectionSlugsMap<TVariantData>(collections);\n\n const patchedCollections = addHooksToVariantCollections<TVariantData>(\n incomingConfig,\n pluginConfig,\n variantToParent,\n );\n\n return {\n ...incomingConfig,\n collections: patchedCollections,\n globals: [...(incomingConfig.globals ?? []), ...extraGlobals],\n };\n };\n","export function defaultGetExpCookieName(key: string) {\n return `exp_${encodeURIComponent(key)}`;\n}\n","export const DEFAULT_VISITOR_ID_COOKIE_NAME = \"ab_visitor_id\";\n","import type { AbCookieConfig } from \"../types\";\nimport { defaultGetExpCookieName } from \"./defaultGetExpCookieName\";\nimport { DEFAULT_VISITOR_ID_COOKIE_NAME } from \"../constants\";\n\nexport interface ResolvedAbCookieNames {\n /** Resolved variant cookie name for the given experiment. */\n variantCookieName: string;\n /** Resolved visitor ID cookie name. */\n visitorCookieName: string;\n}\n\n/**\n * Resolves an `AbCookieConfig` + experiment ID into plain serializable strings.\n * Use this in Server Components to derive props for Client Components.\n */\nexport function resolveAbCookieNames(config: AbCookieConfig | undefined, experimentId: string): ResolvedAbCookieNames {\n return {\n variantCookieName: (config?.getExpCookieName ?? defaultGetExpCookieName)(experimentId),\n visitorCookieName: config?.visitorIdCookieName ?? DEFAULT_VISITOR_ID_COOKIE_NAME,\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/utils/buildVariantToParentCollectionSlugsMap.ts","../src/utils/resolveId.ts","../src/utils/getLocales.ts","../src/utils/getNestedValue.ts","../src/constants.ts","../src/hooks/buildAfterChangeHook.ts","../src/hooks/buildAfterDeleteHook.ts","../src/hooks/validateVariantPercentageSum.ts","../src/utils/isFieldPathExists.ts","../src/utils/addHooksToVariantCollections.ts","../src/plugin.ts","../src/cookie/utils/defaultGetExpCookieName.ts","../src/cookie/constants.ts","../src/cookie/utils/resolveAbCookieNames.ts"],"sourcesContent":["import type { CollectionABConfig } from \"../types/config\";\n\nexport function buildVariantToParentCollectionSlugsMap<TVariantData extends object>(\n collections: Record<string, CollectionABConfig<TVariantData>>,\n) {\n const variantToParent = new Map<string, string>();\n\n for (const [parentSlug, abConfig] of Object.entries(collections)) {\n if (abConfig) variantToParent.set(abConfig.variantCollectionSlug, parentSlug);\n }\n\n return variantToParent;\n}\n","interface BaseDocument {\n id: number | string;\n}\n\nconst isValueIsBaseDocument = (value: object): value is BaseDocument => {\n return \"id\" in value;\n};\n\nexport function resolveId(value: unknown) {\n if (!value) return null;\n\n if (typeof value === \"number\" || typeof value === \"string\") return value;\n\n if (typeof value === \"object\" && isValueIsBaseDocument(value)) {\n return value.id;\n }\n\n return null;\n}\n","import type { Payload } from \"payload\";\n\nexport function getLocales(payload: Payload): (string | undefined)[] {\n const { localization } = payload.config;\n\n if (!localization) return [undefined];\n\n const { locales } = localization;\n\n if (!locales?.length) return [undefined];\n\n return locales.map((l) => (typeof l === \"string\" ? l : l.code));\n}\n","export function getNestedValue(obj: Record<string, unknown>, path: string): unknown {\n return path.split(\".\").reduce((acc: unknown, key) => {\n if (acc !== null && typeof acc === \"object\") {\n return (acc as Record<string, unknown>)[key];\n }\n\n return undefined;\n }, obj);\n}\n","export const DEFAULT_PASS_PERCENTAGE_FIELD = \"passPercentage\";\nexport const DEFAULT_PARENT_FIELD = \"page\";\n","import type { CollectionAfterChangeHook, CollectionSlug, TypedLocale } from \"payload\";\nimport type { AbTestingPluginConfig, CollectionABConfig } from \"../types/config\";\nimport { resolveId } from \"../utils/resolveId\";\nimport { getLocales } from \"../utils/getLocales\";\nimport { getNestedValue } from \"../utils/getNestedValue\";\nimport { DEFAULT_PARENT_FIELD } from \"../constants\";\n\nexport function buildAfterChangeHook<TVariantData extends object>(\n parentCollectionSlug: string,\n abConfig: CollectionABConfig<TVariantData>,\n pluginConfig: AbTestingPluginConfig<TVariantData>,\n): CollectionAfterChangeHook {\n return async ({ doc, req, previousDoc }) => {\n const { payload } = req;\n if (!payload) return;\n\n const parentFieldPath = abConfig.parentField ?? DEFAULT_PARENT_FIELD;\n\n const pageId = resolveId(getNestedValue(doc, parentFieldPath));\n if (!pageId) return;\n\n const locales = getLocales(payload);\n\n const previousPageId = previousDoc ? resolveId(getNestedValue(previousDoc, parentFieldPath)) : null;\n if (previousPageId && previousPageId !== pageId) {\n for (const locale of locales) {\n const oldPageDoc = await payload.findByID({\n collection: parentCollectionSlug as CollectionSlug,\n id: previousPageId,\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n req,\n });\n if (!oldPageDoc) continue;\n\n const oldManifestKey = abConfig.generatePath({ doc: oldPageDoc, locale });\n if (!oldManifestKey) continue;\n\n const remainingOldVariants = await payload.find({\n collection: abConfig.variantCollectionSlug as CollectionSlug,\n where: {\n and: [{ [parentFieldPath]: { equals: previousPageId } }, { id: { not_equals: doc.id } }],\n },\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n limit: 100,\n req,\n });\n\n if (remainingOldVariants.docs.length === 0) {\n await pluginConfig.storage.clear(oldManifestKey, payload);\n } else {\n const oldVariantData = remainingOldVariants.docs.map((variantDoc) =>\n abConfig.generateVariantData({ doc: oldPageDoc, variantDoc, locale }),\n );\n await pluginConfig.storage.write(oldManifestKey, oldVariantData, payload);\n }\n }\n }\n\n for (const locale of locales) {\n const pageDoc = await payload.findByID({\n collection: parentCollectionSlug as CollectionSlug,\n id: pageId,\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n req,\n });\n if (!pageDoc) continue;\n\n const manifestKey = abConfig.generatePath({ doc: pageDoc, locale });\n if (!manifestKey) continue;\n\n const allVariants = await payload.find({\n collection: abConfig.variantCollectionSlug as CollectionSlug,\n where: { [parentFieldPath]: { equals: pageId } },\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n limit: 100,\n req,\n });\n\n const variantData = allVariants.docs.map((variantDoc) =>\n abConfig.generateVariantData({ doc: pageDoc, variantDoc, locale }),\n );\n\n await pluginConfig.storage.write(manifestKey, variantData, payload);\n }\n };\n}\n","import type { CollectionAfterDeleteHook, CollectionSlug, TypedLocale } from \"payload\";\nimport type { AbTestingPluginConfig, CollectionABConfig } from \"../types/config\";\nimport { resolveId } from \"../utils/resolveId\";\nimport { getLocales } from \"../utils/getLocales\";\nimport { getNestedValue } from \"../utils/getNestedValue\";\nimport { DEFAULT_PARENT_FIELD } from \"../constants\";\n\nexport function buildAfterDeleteHook<TVariantData extends object>(\n parentCollectionSlug: string,\n abConfig: CollectionABConfig<TVariantData>,\n pluginConfig: AbTestingPluginConfig<TVariantData>,\n): CollectionAfterDeleteHook {\n return async ({ doc, req, id }) => {\n const { payload } = req;\n if (!payload) return;\n\n const parentFieldPath = abConfig.parentField ?? DEFAULT_PARENT_FIELD;\n\n const pageId = resolveId(getNestedValue(doc, parentFieldPath));\n if (!pageId) return;\n\n const locales = getLocales(payload);\n\n for (const locale of locales) {\n const pageDoc = await payload.findByID({\n collection: parentCollectionSlug as CollectionSlug,\n id: pageId,\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n req,\n });\n if (!pageDoc) continue;\n\n const manifestKey = abConfig.generatePath({ doc: pageDoc, locale });\n if (!manifestKey) continue;\n\n const remainingVariants = await payload.find({\n collection: abConfig.variantCollectionSlug as CollectionSlug,\n where: {\n and: [{ [parentFieldPath]: { equals: pageId } }, { id: { not_equals: id } }],\n },\n depth: 2,\n locale: locale as TypedLocale,\n overrideAccess: true,\n limit: 100,\n req,\n });\n\n if (remainingVariants.docs.length === 0) {\n await pluginConfig.storage.clear(manifestKey, payload);\n } else {\n const variantData = remainingVariants.docs.map((variantDoc) =>\n abConfig.generateVariantData({ doc: pageDoc, variantDoc, locale }),\n );\n\n await pluginConfig.storage.write(manifestKey, variantData, payload);\n }\n }\n };\n}\n","import { ValidationError } from \"payload\";\r\nimport type { CollectionBeforeChangeHook, CollectionSlug, Where } from \"payload\";\r\nimport { resolveId } from \"../utils/resolveId\";\r\nimport { getNestedValue } from \"../utils/getNestedValue\";\r\n\r\ninterface ValidateVariantPercentageSumConfig {\r\n variantCollectionSlug: CollectionSlug;\r\n parentCollectionSlug: CollectionSlug;\r\n parentField: string;\r\n passPercentageField: string;\r\n tenantField?: string;\r\n}\r\n\r\nexport function createValidateVariantPercentageSum(\r\n config: ValidateVariantPercentageSumConfig,\r\n): CollectionBeforeChangeHook {\r\n const { variantCollectionSlug, parentCollectionSlug, parentField, passPercentageField, tenantField } = config;\r\n\r\n return async ({ data, originalDoc, req, operation }) => {\r\n const passPercentage = getNestedValue(data, passPercentageField);\r\n if (passPercentage === undefined || passPercentage === null) return data;\r\n\r\n const parentId = resolveId(getNestedValue(data, parentField));\r\n if (!parentId) return data;\r\n\r\n const andConditions: Where[] = [{ [parentField]: { equals: parentId } }];\r\n\r\n if (tenantField) {\r\n const parentDoc = await req.payload.findByID({\r\n collection: parentCollectionSlug,\r\n id: parentId,\r\n depth: 0,\r\n overrideAccess: true,\r\n req,\r\n });\r\n\r\n if (parentDoc) {\r\n const tenantId = resolveId(getNestedValue(parentDoc, tenantField));\r\n\r\n if (tenantId) {\r\n andConditions.push({ [`${parentField}.${tenantField}`]: { equals: tenantId } });\r\n }\r\n }\r\n }\r\n\r\n if (operation === \"update\" && originalDoc?.id) {\r\n andConditions.push({ id: { not_equals: originalDoc.id } });\r\n }\r\n\r\n const { docs: siblings } = await req.payload.find({\r\n collection: variantCollectionSlug,\r\n where: { and: andConditions },\r\n depth: 0,\r\n req,\r\n });\r\n\r\n const existingSum = siblings.reduce((sum, doc) => {\r\n const percentage = getNestedValue(doc, passPercentageField);\r\n\r\n return sum + (typeof percentage === \"number\" ? percentage : 0);\r\n }, 0);\r\n\r\n if (existingSum + (passPercentage as number) > 100) {\r\n const remaining = 100 - existingSum;\r\n throw new ValidationError({\r\n errors: [\r\n {\r\n path: passPercentageField,\r\n message: `Total variant traffic for this page is ${existingSum}%. This variant cannot exceed ${remaining}% (would exceed 100%).`,\r\n },\r\n ],\r\n });\r\n }\r\n\r\n return data;\r\n };\r\n}\r\n","import type { Field } from \"payload\";\n\ntype TabLike = { name?: string; fields: Field[] };\n\ntype TabsFieldLike = { type: \"tabs\"; tabs: TabLike[] };\n\ntype FieldsContainer = { fields: Field[] };\n\nexport function isFieldPathExists(fields: Field[], path: string): boolean {\n const [head, ...rest] = path.split(\".\");\n\n for (const field of fields) {\n // Named fields\n if (\"name\" in field && field.name === head) {\n if (rest.length === 0) return true;\n\n if (\"fields\" in field && Array.isArray((field as unknown as FieldsContainer).fields)) {\n return isFieldPathExists((field as unknown as FieldsContainer).fields, rest.join(\".\"));\n }\n\n return false;\n }\n\n // Tabs field\n if (field.type === \"tabs\") {\n const { tabs } = field as unknown as TabsFieldLike;\n\n for (const tab of tabs) {\n if (tab.name) {\n if (tab.name === head) {\n if (rest.length === 0) return true;\n\n if (isFieldPathExists(tab.fields, rest.join(\".\"))) return true;\n }\n } else {\n if (isFieldPathExists(tab.fields, path)) return true;\n }\n }\n }\n\n // Transparent layout fields\n if (\n (field.type === \"row\" || field.type === \"collapsible\")\n && \"fields\" in field\n && Array.isArray((field as unknown as FieldsContainer).fields)\n ) {\n if (isFieldPathExists((field as unknown as FieldsContainer).fields, path)) return true;\n }\n }\n\n return false;\n}\n","import type { CollectionConfig, CollectionSlug, Config } from \"payload\";\nimport type { AbTestingPluginConfig } from \"../types/config\";\nimport { buildAfterChangeHook } from \"../hooks/buildAfterChangeHook\";\nimport { buildAfterDeleteHook } from \"../hooks/buildAfterDeleteHook\";\nimport { createValidateVariantPercentageSum } from \"../hooks/validateVariantPercentageSum\";\nimport { isFieldPathExists } from \"./isFieldPathExists\";\nimport { DEFAULT_PARENT_FIELD, DEFAULT_PASS_PERCENTAGE_FIELD } from \"../constants\";\n\nexport function addHooksToVariantCollections<TVariantData extends object>(\n config: Config,\n pluginConfig: AbTestingPluginConfig<TVariantData>,\n variantToParent: Map<string, string>,\n) {\n const patchedCollections = (config.collections ?? []).map((collection) => {\n const parentSlug = variantToParent.get(collection.slug);\n if (!parentSlug) return collection;\n\n const abConfig = pluginConfig.collections[parentSlug];\n if (!abConfig) return collection;\n\n let resolvedPassPercentageField: string | null = null;\n\n const passPercentagePath =\n typeof abConfig.passPercentageField === \"string\" ? abConfig.passPercentageField : DEFAULT_PASS_PERCENTAGE_FIELD;\n\n if (isFieldPathExists(collection.fields, passPercentagePath)) {\n resolvedPassPercentageField = passPercentagePath;\n }\n\n const beforeChangeHooks = [...(collection.hooks?.beforeChange ?? [])];\n\n if (resolvedPassPercentageField) {\n beforeChangeHooks.push(\n createValidateVariantPercentageSum({\n variantCollectionSlug: abConfig.variantCollectionSlug as CollectionSlug,\n parentCollectionSlug: parentSlug as CollectionSlug,\n parentField: abConfig.parentField ?? DEFAULT_PARENT_FIELD,\n passPercentageField: resolvedPassPercentageField,\n tenantField: abConfig.tenantField,\n }),\n );\n }\n\n return {\n ...collection,\n hooks: {\n ...collection.hooks,\n beforeChange: beforeChangeHooks,\n afterChange: [\n ...(collection.hooks?.afterChange ?? []),\n buildAfterChangeHook(parentSlug, abConfig, pluginConfig),\n ],\n afterDelete: [\n ...(collection.hooks?.afterDelete ?? []),\n buildAfterDeleteHook(parentSlug, abConfig, pluginConfig),\n ],\n },\n } as CollectionConfig;\n });\n\n return patchedCollections;\n}\n","import type { Config, Plugin } from \"payload\";\nimport type { AbTestingPluginConfig } from \"./types/config\";\nimport { buildVariantToParentCollectionSlugsMap } from \"./utils/buildVariantToParentCollectionSlugsMap\";\nimport { addHooksToVariantCollections } from \"./utils/addHooksToVariantCollections\";\n\nexport const abTestingPlugin =\n <TVariantData extends object>(pluginConfig: AbTestingPluginConfig<TVariantData>): Plugin =>\n (incomingConfig: Config): Config => {\n const { enabled = true, debug = false, collections, storage } = pluginConfig;\n\n if (!enabled) return incomingConfig;\n\n const extraGlobals = storage.createGlobal ? [storage.createGlobal(debug)] : [];\n\n const variantToParent = buildVariantToParentCollectionSlugsMap<TVariantData>(collections);\n\n const patchedCollections = addHooksToVariantCollections<TVariantData>(\n incomingConfig,\n pluginConfig,\n variantToParent,\n );\n\n return {\n ...incomingConfig,\n collections: patchedCollections,\n globals: [...(incomingConfig.globals ?? []), ...extraGlobals],\n };\n };\n","export function defaultGetExpCookieName(key: string) {\n return `exp_${encodeURIComponent(key)}`;\n}\n","export const DEFAULT_VISITOR_ID_COOKIE_NAME = \"ab_visitor_id\";\n","import type { AbCookieConfig } from \"../types\";\nimport { defaultGetExpCookieName } from \"./defaultGetExpCookieName\";\nimport { DEFAULT_VISITOR_ID_COOKIE_NAME } from \"../constants\";\n\nexport interface ResolvedAbCookieNames {\n /** Resolved variant cookie name for the given experiment. */\n variantCookieName: string;\n /** Resolved visitor ID cookie name. */\n visitorCookieName: string;\n}\n\n/**\n * Resolves an `AbCookieConfig` + experiment ID into plain serializable strings.\n * Use this in Server Components to derive props for Client Components.\n */\nexport function resolveAbCookieNames(config: AbCookieConfig | undefined, experimentId: string): ResolvedAbCookieNames {\n return {\n variantCookieName: (config?.getExpCookieName ?? defaultGetExpCookieName)(experimentId),\n visitorCookieName: config?.visitorIdCookieName ?? DEFAULT_VISITOR_ID_COOKIE_NAME,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
1
  import { NextRequest, NextResponse } from 'next/server';
2
- import { S as StorageAdapter } from '../config-CQrzAj5Q.js';
2
+ import { S as StorageAdapter } from '../config-Bq-Mi7k_.js';
3
3
  import { A as AbCookieConfig } from '../resolveAbCookieNames-DH8evjWm.js';
4
4
  export { R as ResolvedAbCookieNames, r as resolveAbCookieNames } from '../resolveAbCookieNames-DH8evjWm.js';
5
5
  import 'payload';
@@ -33,7 +33,7 @@ function defaultGetExpCookieName(key) {
33
33
  }
34
34
 
35
35
  // src/middleware/resolveAbRewrite.ts
36
- var DEFAULT_BUCKET_COOKIE_PREFIX = "payload-ab-bucket";
36
+ var DEFAULT_BUCKET_COOKIE_PREFIX = "payload_ab_bucket";
37
37
  var DEFAULT_VISITOR_MAX_AGE = 60 * 60 * 24 * 365;
38
38
  var DEFAULT_EXP_MAX_AGE = 60 * 60 * 24 * 90;
39
39
  function createResolveAbRewrite(config) {
@@ -53,7 +53,7 @@ function createResolveAbRewrite(config) {
53
53
  return null;
54
54
  }
55
55
  if (!variants?.length) return null;
56
- const bucketCookieName = `${bucketCookiePrefix}_${encodeURIComponent(visiblePathname)}`;
56
+ const bucketCookieName = `${bucketCookiePrefix}_${manifestKey.replace(/^\//, "").replace(/\//g, "_")}`;
57
57
  const existingBucket = request.cookies.get(bucketCookieName)?.value;
58
58
  const existingVisitorId = request.cookies.get(visitorIdCookieName)?.value;
59
59
  const visitorId = existingVisitorId ?? crypto.randomUUID();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/middleware/resolveAbRewrite.ts","../../src/middleware/utils/pickUniformBucket.ts","../../src/middleware/utils/pickWeightedBucket.ts","../../src/cookie/constants.ts","../../src/cookie/utils/defaultGetExpCookieName.ts","../../src/cookie/utils/resolveAbCookieNames.ts"],"sourcesContent":["import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport type { ResolveAbRewriteConfig } from \"./types\";\nimport { pickWeightedBucket } from \"./utils/pickWeightedBucket\";\nimport { pickUniformBucket } from \"./utils/pickUniformBucket\";\nimport { DEFAULT_VISITOR_ID_COOKIE_NAME } from \"../cookie/constants\";\nimport { defaultGetExpCookieName } from \"../cookie/utils/defaultGetExpCookieName\";\n\nconst DEFAULT_BUCKET_COOKIE_PREFIX = \"payload-ab-bucket\";\nconst DEFAULT_VISITOR_MAX_AGE = 60 * 60 * 24 * 365;\nconst DEFAULT_EXP_MAX_AGE = 60 * 60 * 24 * 90;\n\nexport function createResolveAbRewrite<TVariantData extends object>(config: ResolveAbRewriteConfig<TVariantData>) {\n const { storage, getBucket, getRewritePath, getPassPercentage, cookies: cookieConfig = {} } = config;\n\n const {\n bucketCookiePrefix = DEFAULT_BUCKET_COOKIE_PREFIX,\n visitorIdCookieName = DEFAULT_VISITOR_ID_COOKIE_NAME,\n getExpCookieName = defaultGetExpCookieName,\n visitorIdMaxAge = DEFAULT_VISITOR_MAX_AGE,\n expCookieMaxAge = DEFAULT_EXP_MAX_AGE,\n } = cookieConfig;\n\n return async function resolveAbRewrite(\n request: NextRequest,\n /** The URL pathname visible to the user (used as bucket cookie key). */\n visiblePathname: string,\n /** The manifest key to look up — typically the internal rewrite path. */\n manifestKey: string,\n /** Path to rewrite to when no variant is selected ('original' bucket). */\n originalRewritePath: string,\n ): Promise<NextResponse | null> {\n let variants: TVariantData[] | null = null;\n\n try {\n variants = await storage.read(manifestKey);\n } catch {\n return null;\n }\n\n if (!variants?.length) return null;\n\n const bucketCookieName = `${bucketCookiePrefix}_${encodeURIComponent(visiblePathname)}`;\n const existingBucket = request.cookies.get(bucketCookieName)?.value;\n\n const existingVisitorId = request.cookies.get(visitorIdCookieName)?.value;\n const visitorId = existingVisitorId ?? crypto.randomUUID();\n\n const expCookieName = getExpCookieName(manifestKey);\n\n let bucket = existingBucket;\n if (!bucket) {\n bucket =\n getPassPercentage ?\n pickWeightedBucket(variants, getBucket, getPassPercentage)\n : pickUniformBucket(variants, getBucket);\n }\n\n const setAbCookies = (res: NextResponse, assignedBucket: string, isNewAssignment: boolean) => {\n if (!existingVisitorId) {\n res.cookies.set(visitorIdCookieName, visitorId, {\n path: \"/\",\n sameSite: \"lax\",\n maxAge: visitorIdMaxAge,\n });\n }\n\n if (isNewAssignment) {\n res.cookies.set(expCookieName, assignedBucket, {\n path: \"/\",\n sameSite: \"lax\",\n maxAge: expCookieMaxAge,\n });\n }\n };\n\n if (bucket === \"original\") {\n if (!existingBucket) {\n const url = request.nextUrl.clone();\n\n url.pathname = originalRewritePath;\n\n const res = NextResponse.rewrite(url);\n\n res.cookies.set(bucketCookieName, \"original\", { path: \"/\", sameSite: \"lax\" });\n setAbCookies(res, \"original\", true);\n\n return res;\n }\n\n return null;\n }\n\n const match = variants.find((v) => getBucket(v) === bucket);\n if (!match) return null;\n\n const url = request.nextUrl.clone();\n url.pathname = getRewritePath(match);\n const res = NextResponse.rewrite(url);\n\n if (!existingBucket) {\n res.cookies.set(bucketCookieName, bucket, { path: \"/\", sameSite: \"lax\" });\n setAbCookies(res, bucket, true);\n } else {\n setAbCookies(res, bucket, false);\n }\n\n return res;\n };\n}\n","export function pickUniformBucket<T extends object>(variants: T[], getBucket: (v: T) => string) {\n const idx = Math.floor(Math.random() * (variants.length + 1));\n\n if (idx === variants.length) return \"original\";\n\n const selected = variants[idx];\n\n return selected !== undefined ? getBucket(selected) : \"original\";\n}\n","import { pickUniformBucket } from \"./pickUniformBucket\";\n\nexport function pickWeightedBucket<T extends object>(\n variants: T[],\n getBucket: (v: T) => string,\n getPassPercentage: (v: T) => number,\n) {\n const totalVariantWeight = variants.reduce((sum, v) => sum + getPassPercentage(v), 0);\n const originalWeight = Math.max(0, 100 - totalVariantWeight);\n const total = totalVariantWeight + originalWeight;\n\n if (totalVariantWeight === 0) return pickUniformBucket(variants, getBucket);\n\n const rand = Math.random() * total;\n\n let cumulative = 0;\n for (const variant of variants) {\n cumulative += getPassPercentage(variant);\n\n if (rand < cumulative) return getBucket(variant);\n }\n\n return \"original\";\n}\n","export const DEFAULT_VISITOR_ID_COOKIE_NAME = \"ab_visitor_id\";\n","export function defaultGetExpCookieName(key: string) {\n return `exp_${encodeURIComponent(key)}`;\n}\n","import type { AbCookieConfig } from \"../types\";\nimport { defaultGetExpCookieName } from \"./defaultGetExpCookieName\";\nimport { DEFAULT_VISITOR_ID_COOKIE_NAME } from \"../constants\";\n\nexport interface ResolvedAbCookieNames {\n /** Resolved variant cookie name for the given experiment. */\n variantCookieName: string;\n /** Resolved visitor ID cookie name. */\n visitorCookieName: string;\n}\n\n/**\n * Resolves an `AbCookieConfig` + experiment ID into plain serializable strings.\n * Use this in Server Components to derive props for Client Components.\n */\nexport function resolveAbCookieNames(config: AbCookieConfig | undefined, experimentId: string): ResolvedAbCookieNames {\n return {\n variantCookieName: (config?.getExpCookieName ?? defaultGetExpCookieName)(experimentId),\n visitorCookieName: config?.visitorIdCookieName ?? DEFAULT_VISITOR_ID_COOKIE_NAME,\n };\n}\n"],"mappings":"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","names":["res","url"]}
1
+ {"version":3,"sources":["../../src/middleware/resolveAbRewrite.ts","../../src/middleware/utils/pickUniformBucket.ts","../../src/middleware/utils/pickWeightedBucket.ts","../../src/cookie/constants.ts","../../src/cookie/utils/defaultGetExpCookieName.ts","../../src/cookie/utils/resolveAbCookieNames.ts"],"sourcesContent":["import { NextResponse } from \"next/server\";\nimport type { NextRequest } from \"next/server\";\nimport type { ResolveAbRewriteConfig } from \"./types\";\nimport { pickWeightedBucket } from \"./utils/pickWeightedBucket\";\nimport { pickUniformBucket } from \"./utils/pickUniformBucket\";\nimport { DEFAULT_VISITOR_ID_COOKIE_NAME } from \"../cookie/constants\";\nimport { defaultGetExpCookieName } from \"../cookie/utils/defaultGetExpCookieName\";\n\nconst DEFAULT_BUCKET_COOKIE_PREFIX = \"payload_ab_bucket\";\nconst DEFAULT_VISITOR_MAX_AGE = 60 * 60 * 24 * 365;\nconst DEFAULT_EXP_MAX_AGE = 60 * 60 * 24 * 90;\n\nexport function createResolveAbRewrite<TVariantData extends object>(config: ResolveAbRewriteConfig<TVariantData>) {\n const { storage, getBucket, getRewritePath, getPassPercentage, cookies: cookieConfig = {} } = config;\n\n const {\n bucketCookiePrefix = DEFAULT_BUCKET_COOKIE_PREFIX,\n visitorIdCookieName = DEFAULT_VISITOR_ID_COOKIE_NAME,\n getExpCookieName = defaultGetExpCookieName,\n visitorIdMaxAge = DEFAULT_VISITOR_MAX_AGE,\n expCookieMaxAge = DEFAULT_EXP_MAX_AGE,\n } = cookieConfig;\n\n return async function resolveAbRewrite(\n request: NextRequest,\n /** The URL pathname visible to the user (used as bucket cookie key). */\n visiblePathname: string,\n /** The manifest key to look up — typically the internal rewrite path. */\n manifestKey: string,\n /** Path to rewrite to when no variant is selected ('original' bucket). */\n originalRewritePath: string,\n ): Promise<NextResponse | null> {\n let variants: TVariantData[] | null = null;\n\n try {\n variants = await storage.read(manifestKey);\n } catch {\n return null;\n }\n\n if (!variants?.length) return null;\n\n const bucketCookieName = `${bucketCookiePrefix}_${manifestKey.replace(/^\\//, \"\").replace(/\\//g, \"_\")}`;\n const existingBucket = request.cookies.get(bucketCookieName)?.value;\n\n const existingVisitorId = request.cookies.get(visitorIdCookieName)?.value;\n const visitorId = existingVisitorId ?? crypto.randomUUID();\n\n const expCookieName = getExpCookieName(manifestKey);\n\n let bucket = existingBucket;\n if (!bucket) {\n bucket =\n getPassPercentage ?\n pickWeightedBucket(variants, getBucket, getPassPercentage)\n : pickUniformBucket(variants, getBucket);\n }\n\n const setAbCookies = (res: NextResponse, assignedBucket: string, isNewAssignment: boolean) => {\n if (!existingVisitorId) {\n res.cookies.set(visitorIdCookieName, visitorId, {\n path: \"/\",\n sameSite: \"lax\",\n maxAge: visitorIdMaxAge,\n });\n }\n\n if (isNewAssignment) {\n res.cookies.set(expCookieName, assignedBucket, {\n path: \"/\",\n sameSite: \"lax\",\n maxAge: expCookieMaxAge,\n });\n }\n };\n\n if (bucket === \"original\") {\n if (!existingBucket) {\n const url = request.nextUrl.clone();\n\n url.pathname = originalRewritePath;\n\n const res = NextResponse.rewrite(url);\n\n res.cookies.set(bucketCookieName, \"original\", { path: \"/\", sameSite: \"lax\" });\n setAbCookies(res, \"original\", true);\n\n return res;\n }\n\n return null;\n }\n\n const match = variants.find((v) => getBucket(v) === bucket);\n if (!match) return null;\n\n const url = request.nextUrl.clone();\n url.pathname = getRewritePath(match);\n const res = NextResponse.rewrite(url);\n\n if (!existingBucket) {\n res.cookies.set(bucketCookieName, bucket, { path: \"/\", sameSite: \"lax\" });\n setAbCookies(res, bucket, true);\n } else {\n setAbCookies(res, bucket, false);\n }\n\n return res;\n };\n}\n","export function pickUniformBucket<T extends object>(variants: T[], getBucket: (v: T) => string) {\n const idx = Math.floor(Math.random() * (variants.length + 1));\n\n if (idx === variants.length) return \"original\";\n\n const selected = variants[idx];\n\n return selected !== undefined ? getBucket(selected) : \"original\";\n}\n","import { pickUniformBucket } from \"./pickUniformBucket\";\n\nexport function pickWeightedBucket<T extends object>(\n variants: T[],\n getBucket: (v: T) => string,\n getPassPercentage: (v: T) => number,\n) {\n const totalVariantWeight = variants.reduce((sum, v) => sum + getPassPercentage(v), 0);\n const originalWeight = Math.max(0, 100 - totalVariantWeight);\n const total = totalVariantWeight + originalWeight;\n\n if (totalVariantWeight === 0) return pickUniformBucket(variants, getBucket);\n\n const rand = Math.random() * total;\n\n let cumulative = 0;\n for (const variant of variants) {\n cumulative += getPassPercentage(variant);\n\n if (rand < cumulative) return getBucket(variant);\n }\n\n return \"original\";\n}\n","export const DEFAULT_VISITOR_ID_COOKIE_NAME = \"ab_visitor_id\";\n","export function defaultGetExpCookieName(key: string) {\n return `exp_${encodeURIComponent(key)}`;\n}\n","import type { AbCookieConfig } from \"../types\";\nimport { defaultGetExpCookieName } from \"./defaultGetExpCookieName\";\nimport { DEFAULT_VISITOR_ID_COOKIE_NAME } from \"../constants\";\n\nexport interface ResolvedAbCookieNames {\n /** Resolved variant cookie name for the given experiment. */\n variantCookieName: string;\n /** Resolved visitor ID cookie name. */\n visitorCookieName: string;\n}\n\n/**\n * Resolves an `AbCookieConfig` + experiment ID into plain serializable strings.\n * Use this in Server Components to derive props for Client Components.\n */\nexport function resolveAbCookieNames(config: AbCookieConfig | undefined, experimentId: string): ResolvedAbCookieNames {\n return {\n variantCookieName: (config?.getExpCookieName ?? defaultGetExpCookieName)(experimentId),\n visitorCookieName: config?.visitorIdCookieName ?? DEFAULT_VISITOR_ID_COOKIE_NAME,\n };\n}\n"],"mappings":"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","names":["res","url"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiryl.pekarski/payload-plugin-ab",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "A/B testing plugin for Payload CMS",
5
5
  "keywords": [
6
6
  "payload-cms",