@dappermountain/payload-plugin-achievements 0.2.1 → 0.2.3

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.
Files changed (139) hide show
  1. package/README.md +14 -0
  2. package/dist/access/index.d.ts +2 -2
  3. package/dist/access/index.d.ts.map +1 -1
  4. package/dist/access/index.js +2 -2
  5. package/dist/access/roles/index.d.ts +1 -1
  6. package/dist/access/roles/index.d.ts.map +1 -1
  7. package/dist/access/roles/index.js +4 -4
  8. package/dist/admin/ActorField.js +1 -1
  9. package/dist/admin/MetricChangeField.js +1 -1
  10. package/dist/admin/MetricField.js +1 -1
  11. package/dist/cli/index.d.ts +2 -2
  12. package/dist/cli/index.d.ts.map +1 -1
  13. package/dist/cli/index.js +1 -1
  14. package/dist/cli/reconcile.d.ts +1 -1
  15. package/dist/cli/reconcile.d.ts.map +1 -1
  16. package/dist/cli/reconcile.js +1 -1
  17. package/dist/collections/AchievementRequests/access/index.js +2 -2
  18. package/dist/collections/AchievementRequests/hooks/index.js +1 -1
  19. package/dist/collections/AchievementRequests/hooks/prepareAchievementRequest.js +5 -5
  20. package/dist/collections/AchievementRequests/index.js +4 -4
  21. package/dist/collections/Achievements/access/index.js +1 -1
  22. package/dist/collections/Achievements/hooks/afterRequiresReviewDisabled.js +1 -1
  23. package/dist/collections/Achievements/hooks/index.js +2 -2
  24. package/dist/collections/Achievements/hooks/validateEligibilityRules.js +1 -1
  25. package/dist/collections/Achievements/index.js +4 -4
  26. package/dist/collections/EventTypes/access/index.js +1 -1
  27. package/dist/collections/EventTypes/hooks/index.js +2 -2
  28. package/dist/collections/EventTypes/index.js +4 -4
  29. package/dist/collections/Grants/access/index.js +2 -2
  30. package/dist/collections/Grants/hooks/afterGrantMutation.js +3 -3
  31. package/dist/collections/Grants/hooks/ensureUniqueGrant.js +2 -2
  32. package/dist/collections/Grants/hooks/index.js +3 -3
  33. package/dist/collections/Grants/hooks/setGrantTitle.js +2 -2
  34. package/dist/collections/Grants/index.js +5 -5
  35. package/dist/collections/Logs/access/index.js +2 -2
  36. package/dist/collections/Logs/fields/validators.js +2 -2
  37. package/dist/collections/Logs/hooks/ensureTypeRequirements.js +2 -2
  38. package/dist/collections/Logs/hooks/index.js +1 -1
  39. package/dist/collections/Logs/index.d.ts.map +1 -1
  40. package/dist/collections/Logs/index.js +10 -8
  41. package/dist/collections/Metrics/access/index.js +1 -1
  42. package/dist/collections/Metrics/hooks/index.js +2 -2
  43. package/dist/collections/Metrics/index.js +4 -4
  44. package/dist/collections/TierRequests/access/index.js +2 -2
  45. package/dist/collections/TierRequests/hooks/index.js +1 -1
  46. package/dist/collections/TierRequests/hooks/prepareTierRequest.js +4 -4
  47. package/dist/collections/TierRequests/index.js +4 -4
  48. package/dist/collections/Tiers/access/index.js +1 -1
  49. package/dist/collections/Tiers/hooks/afterRequiresReviewDisabled.js +1 -1
  50. package/dist/collections/Tiers/hooks/index.js +2 -2
  51. package/dist/collections/Tiers/hooks/validateUnlockRules.js +1 -1
  52. package/dist/collections/Tiers/index.js +5 -5
  53. package/dist/collections/access/definitions.d.ts +1 -1
  54. package/dist/collections/access/definitions.d.ts.map +1 -1
  55. package/dist/collections/access/definitions.js +2 -2
  56. package/dist/collections/applyOverrides.d.ts +1 -1
  57. package/dist/collections/applyOverrides.d.ts.map +1 -1
  58. package/dist/collections/fields/catalogFilter.js +1 -1
  59. package/dist/collections/fields/index.d.ts +5 -5
  60. package/dist/collections/fields/index.d.ts.map +1 -1
  61. package/dist/collections/fields/index.js +5 -5
  62. package/dist/collections/fields/ruleFields.js +2 -2
  63. package/dist/collections/fields/scopeField.js +1 -1
  64. package/dist/collections/fields/userField.js +1 -1
  65. package/dist/collections/fields/usersAchievementsGroup.d.ts +1 -1
  66. package/dist/collections/fields/usersAchievementsGroup.d.ts.map +1 -1
  67. package/dist/collections/helpers.d.ts +1 -1
  68. package/dist/collections/helpers.d.ts.map +1 -1
  69. package/dist/collections/helpers.js +1 -1
  70. package/dist/collections/hooks/index.d.ts +3 -3
  71. package/dist/collections/hooks/index.d.ts.map +1 -1
  72. package/dist/collections/hooks/index.js +3 -3
  73. package/dist/collections/hooks/preventCatalogDelete.js +3 -3
  74. package/dist/collections/index.js +10 -10
  75. package/dist/collections/slugs.d.ts +1 -1
  76. package/dist/collections/slugs.d.ts.map +1 -1
  77. package/dist/defaults.d.ts +2 -2
  78. package/dist/defaults.d.ts.map +1 -1
  79. package/dist/defaults.js +1 -1
  80. package/dist/enabled.js +2 -2
  81. package/dist/endpoints/index.d.ts +1 -1
  82. package/dist/endpoints/index.d.ts.map +1 -1
  83. package/dist/endpoints/index.js +2 -2
  84. package/dist/endpoints/me.js +2 -2
  85. package/dist/endpoints/reconcile.js +3 -3
  86. package/dist/exports/client.d.ts +4 -4
  87. package/dist/exports/client.d.ts.map +1 -1
  88. package/dist/exports/client.js +4 -4
  89. package/dist/extensions/registry.d.ts +1 -1
  90. package/dist/extensions/registry.d.ts.map +1 -1
  91. package/dist/extensions/registry.js +2 -2
  92. package/dist/index.d.ts +12 -12
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +8 -8
  95. package/dist/options-store.d.ts +2 -2
  96. package/dist/options-store.d.ts.map +1 -1
  97. package/dist/options-store.js +1 -1
  98. package/dist/plugin.d.ts +1 -1
  99. package/dist/plugin.d.ts.map +1 -1
  100. package/dist/plugin.js +5 -5
  101. package/dist/seed/index.js +3 -3
  102. package/dist/services/achievement/buildCatalogProgressGroups.js +2 -2
  103. package/dist/services/achievement/builtInRules.d.ts +1 -1
  104. package/dist/services/achievement/builtInRules.d.ts.map +1 -1
  105. package/dist/services/achievement/builtInRules.js +5 -5
  106. package/dist/services/achievement/evaluateRules.js +2 -2
  107. package/dist/services/achievement/eventTypeRequiresActor.js +2 -2
  108. package/dist/services/achievement/getUserProgress.js +4 -4
  109. package/dist/services/achievement/grantSideEffects.d.ts +1 -1
  110. package/dist/services/achievement/grantSideEffects.d.ts.map +1 -1
  111. package/dist/services/achievement/grantSideEffects.js +17 -16
  112. package/dist/services/achievement/index.d.ts +21 -19
  113. package/dist/services/achievement/index.d.ts.map +1 -1
  114. package/dist/services/achievement/index.js +14 -13
  115. package/dist/services/achievement/logData.d.ts +31 -0
  116. package/dist/services/achievement/logData.d.ts.map +1 -0
  117. package/dist/services/achievement/logData.js +30 -0
  118. package/dist/services/achievement/reconcile.d.ts.map +1 -1
  119. package/dist/services/achievement/reconcile.js +14 -11
  120. package/dist/services/achievement/recordEvent.d.ts.map +1 -1
  121. package/dist/services/achievement/recordEvent.js +27 -14
  122. package/dist/services/achievement/releaseReviewGate.js +2 -2
  123. package/dist/services/achievement/resolveCatalog.d.ts +1 -1
  124. package/dist/services/achievement/resolveCatalog.d.ts.map +1 -1
  125. package/dist/services/achievement/resolveCatalog.js +1 -1
  126. package/dist/services/achievement/resolveCurrentTier.js +4 -4
  127. package/dist/services/achievement/resolveTierProgress.d.ts +1 -1
  128. package/dist/services/achievement/resolveTierProgress.d.ts.map +1 -1
  129. package/dist/services/achievement/resolveTierProgress.js +4 -4
  130. package/dist/services/achievement/reviewAchievementRequest.js +3 -3
  131. package/dist/services/achievement/submitAchievementRequest.js +2 -2
  132. package/dist/services/achievement/tierApproval.js +1 -1
  133. package/dist/services/achievement/tierProgression.d.ts +1 -1
  134. package/dist/services/achievement/tierProgression.d.ts.map +1 -1
  135. package/dist/services/achievement/tierProgression.js +5 -5
  136. package/dist/services/achievement/validateRules.d.ts +1 -1
  137. package/dist/services/achievement/validateRules.d.ts.map +1 -1
  138. package/dist/services/achievement/validateRules.js +2 -2
  139. package/package.json +1 -1
package/README.md CHANGED
@@ -30,6 +30,8 @@ bun add @dappermountain/payload-plugin-achievements
30
30
 
31
31
  Other clients also work (`npm install @dappermountain/payload-plugin-achievements`, etc.).
32
32
 
33
+ Next.js hosts should list the package in `transpilePackages` so `'use client'` admin components compile. Host imports stay on the package name; relative `.js` specifiers are internal to this package.
34
+
33
35
  ## Quick start
34
36
 
35
37
  ```ts
@@ -279,6 +281,18 @@ await runReconcileCli({ config })
279
281
 
280
282
  Pass catalog **slugs** (or ids) for `type` and `metric`. Metric totals are the sum of `change` on matching logs. Creating or deleting **grants** (Admin or API) writes `achievement.granted` / `achievement.revoked`, syncs composed achievements, and may open tier requests / write `tier.changed`.
281
283
 
284
+ Engine log `data` for those system events uses a shared transition envelope:
285
+
286
+ ```ts
287
+ { from: { id, slug? } | null, to: { id, slug? } | null }
288
+ ```
289
+
290
+ | type | `from` | `to` |
291
+ | --- | --- | --- |
292
+ | `tier.changed` | previous tier (null on first climb) | current tier |
293
+ | `achievement.granted` | `null` | achievement |
294
+ | `achievement.revoked` | achievement | `null` |
295
+
282
296
  Turning **Requires review** off on a definition or tier **approves pending requests** for that row only (each waiting user goes through the existing request hooks).
283
297
 
284
298
  **Admin:** Grants list includes **Repair progression**, which `POST`s the reconcile endpoint (requires `canReview`).
@@ -1,3 +1,3 @@
1
- export * from './helpers/index';
2
- export * from './roles/index';
1
+ export * from './helpers/index.js';
2
+ export * from './roles/index.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/access/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/access/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA"}
@@ -1,2 +1,2 @@
1
- export * from './helpers/index';
2
- export * from './roles/index';
1
+ export * from './helpers/index.js';
2
+ export * from './roles/index.js';
@@ -1,5 +1,5 @@
1
1
  import type { AccessArgs } from 'payload';
2
- import type { AchievementCollectionKey } from '../../types';
2
+ import type { AchievementCollectionKey } from '../../types.js';
3
3
  /** Authenticated user may read/write rows tied to themselves. */
4
4
  export declare const isSelfUser: (userRelationField?: string) => ({ req, data }: AccessArgs) => boolean | {
5
5
  [x: string]: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/access/roles/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAM3D,iEAAiE;AACjE,eAAO,MAAM,UAAU,GACpB,0BAA0B,MAC1B,eAAe,UAAU;;;;CAgBzB,CAAA;AA0BH;;;GAGG;AACH,eAAO,MAAM,UAAU,GACpB,gBAAgB,wBAAwB,MAClC,MAAM,UAAU,qBAMtB,CAAA;AAEH,eAAO,MAAM,eAAe,GAAI,SAAS,UAAU,YAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/access/roles/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEzC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAM9D,iEAAiE;AACjE,eAAO,MAAM,UAAU,GACpB,0BAA0B,MAC1B,eAAe,UAAU;;;;CAgBzB,CAAA;AA0BH;;;GAGG;AACH,eAAO,MAAM,UAAU,GACpB,gBAAgB,wBAAwB,MAClC,MAAM,UAAU,qBAMtB,CAAA;AAEH,eAAO,MAAM,eAAe,GAAI,SAAS,UAAU,YAAsB,CAAA"}
@@ -1,7 +1,7 @@
1
- import { collectionOf } from '../../collections/helpers';
2
- import { getAchievementOptions } from '../../options-store';
3
- import { relationId } from '../../services/achievement/relationId';
4
- import { getUserId } from '../helpers/index';
1
+ import { collectionOf } from '../../collections/helpers.js';
2
+ import { getAchievementOptions } from '../../options-store.js';
3
+ import { relationId } from '../../services/achievement/relationId.js';
4
+ import { getUserId } from '../helpers/index.js';
5
5
  /** Authenticated user may read/write rows tied to themselves. */
6
6
  export const isSelfUser = (userRelationField = 'user') => ({ req, data }) => {
7
7
  const userId = getUserId(req);
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { RelationshipField, useField } from '@payloadcms/ui';
4
4
  import { useEffect } from 'react';
5
- import { useEventTypeFlags } from './useEventTypeFlags';
5
+ import { useEventTypeFlags } from './useEventTypeFlags.js';
6
6
  /** Relationship field that only renders when the selected event type requires an actor. */
7
7
  export function ActorField(props) {
8
8
  const { eventTypesSlug, ...fieldArgs } = props;
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { NumberField, useField, useFormFields } from '@payloadcms/ui';
4
4
  import { useEffect } from 'react';
5
- import { useEventTypeFlags } from './useEventTypeFlags';
5
+ import { useEventTypeFlags } from './useEventTypeFlags.js';
6
6
  /** Signed change amount — only when the type adjusts a metric and a metric is selected. */
7
7
  export function MetricChangeField(props) {
8
8
  const { eventTypesSlug, ...fieldArgs } = props;
@@ -2,7 +2,7 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { RelationshipField, useField } from '@payloadcms/ui';
4
4
  import { useEffect } from 'react';
5
- import { useEventTypeFlags } from './useEventTypeFlags';
5
+ import { useEventTypeFlags } from './useEventTypeFlags.js';
6
6
  /** Metric relationship — only for event types that adjust a score. */
7
7
  export function MetricField(props) {
8
8
  const { eventTypesSlug, ...fieldArgs } = props;
@@ -1,3 +1,3 @@
1
- export { parseReconcileCliArgs, printReconcileCliHelp, runReconcileCli, } from './reconcile';
2
- export type { ReconcileCliFilters } from './reconcile';
1
+ export { parseReconcileCliArgs, printReconcileCliHelp, runReconcileCli, } from './reconcile.js';
2
+ export type { ReconcileCliFilters } from './reconcile.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,GAChB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA"}
package/dist/cli/index.js CHANGED
@@ -1 +1 @@
1
- export { parseReconcileCliArgs, printReconcileCliHelp, runReconcileCli, } from './reconcile';
1
+ export { parseReconcileCliArgs, printReconcileCliHelp, runReconcileCli, } from './reconcile.js';
@@ -1,5 +1,5 @@
1
1
  import { type SanitizedConfig } from 'payload';
2
- import { type ReconcileProgressionArgs, type ReconcileProgressionResult } from '../services/achievement/reconcile';
2
+ import { type ReconcileProgressionArgs, type ReconcileProgressionResult } from '../services/achievement/reconcile.js';
3
3
  export type ReconcileCliFilters = Omit<ReconcileProgressionArgs, 'payload' | 'req'>;
4
4
  /** Parse `--user`, `--achievement`, `--tier`, `--scope`, `--limit` (ids or slugs). */
5
5
  export declare function parseReconcileCliArgs(argv?: string[]): ReconcileCliFilters;
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/cli/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,SAAS,CAAA;AAE1D,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAChC,MAAM,mCAAmC,CAAA;AAE1C,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,wBAAwB,EAAE,SAAS,GAAG,KAAK,CAAC,CAAA;AA2BnF,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,mBAAmB,CAUjG;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAc5C;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAClD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,GAAG,OAAO,CAAC,0BAA0B,CAAC,CA2BtC"}
1
+ {"version":3,"file":"reconcile.d.ts","sourceRoot":"","sources":["../../src/cli/reconcile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,SAAS,CAAA;AAE1D,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAChC,MAAM,sCAAsC,CAAA;AAE7C,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,wBAAwB,EAAE,SAAS,GAAG,KAAK,CAAC,CAAA;AA2BnF,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,mBAAmB,CAUjG;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAc5C;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAClD,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,kFAAkF;IAClF,IAAI,CAAC,EAAE,OAAO,CAAA;CACf,GAAG,OAAO,CAAC,0BAA0B,CAAC,CA2BtC"}
@@ -1,5 +1,5 @@
1
1
  import { getPayload } from 'payload';
2
- import { reconcileProgression, } from '../services/achievement/reconcile';
2
+ import { reconcileProgression, } from '../services/achievement/reconcile.js';
3
3
  function readFlag(argv, names) {
4
4
  for (const name of names) {
5
5
  const prefix = `${name}=`;
@@ -1,5 +1,5 @@
1
- import { isAuthenticated, requireOne } from '../../../access/index';
2
- import { isReviewer, isSelfUser } from '../../../access/roles/index';
1
+ import { isAuthenticated, requireOne } from '../../../access/index.js';
2
+ import { isReviewer, isSelfUser } from '../../../access/roles/index.js';
3
3
  export const access = {
4
4
  read: requireOne(isReviewer('achievementRequests'), isSelfUser('user')),
5
5
  create: isAuthenticated,
@@ -1,4 +1,4 @@
1
- import { grantOnApprovedRequest, prepareAchievementRequest } from './prepareAchievementRequest';
1
+ import { grantOnApprovedRequest, prepareAchievementRequest } from './prepareAchievementRequest.js';
2
2
  export const hooks = {
3
3
  beforeValidate: [prepareAchievementRequest],
4
4
  afterChange: [grantOnApprovedRequest],
@@ -1,9 +1,9 @@
1
1
  import { APIError } from 'payload';
2
- import { collectionOf } from '../../../collections/helpers';
3
- import { CTX_SYSTEM_REQUEST } from '../../../services/achievement/contextFlags';
4
- import { evaluateRules, ruleGroupHasProgressRequirements } from '../../../services/achievement/evaluateRules';
5
- import { grantAchievement } from '../../../services/achievement/submitAchievementRequest';
6
- import { relationId } from '../../../services/achievement/relationId';
2
+ import { collectionOf } from '../../../collections/helpers.js';
3
+ import { CTX_SYSTEM_REQUEST } from '../../../services/achievement/contextFlags.js';
4
+ import { evaluateRules, ruleGroupHasProgressRequirements } from '../../../services/achievement/evaluateRules.js';
5
+ import { grantAchievement } from '../../../services/achievement/submitAchievementRequest.js';
6
+ import { relationId } from '../../../services/achievement/relationId.js';
7
7
  function scopeIdOf(data) {
8
8
  const scope = data?.scope;
9
9
  if (!scope)
@@ -1,7 +1,7 @@
1
- import { collectionAdmin, collectionOf, optionalFields, slugOf } from '../helpers';
2
- import { scopeField, userField } from '../fields';
3
- import { access } from './access';
4
- import { hooks } from './hooks';
1
+ import { collectionAdmin, collectionOf, optionalFields, slugOf } from '../helpers.js';
2
+ import { scopeField, userField } from '../fields/index.js';
3
+ import { access } from './access/index.js';
4
+ import { hooks } from './hooks/index.js';
5
5
  export function buildAchievementRequestsCollection() {
6
6
  return {
7
7
  slug: slugOf('achievementRequests'),
@@ -1,2 +1,2 @@
1
- import { definitionAccess } from '../../access/definitions';
1
+ import { definitionAccess } from '../../access/definitions.js';
2
2
  export const access = definitionAccess('achievements');
@@ -1,4 +1,4 @@
1
- import { didDisableRequiresReview, releasePendingAchievementReviews, } from '../../../services/achievement/releaseReviewGate';
1
+ import { didDisableRequiresReview, releasePendingAchievementReviews, } from '../../../services/achievement/releaseReviewGate.js';
2
2
  /**
3
3
  * When Requires review is turned off, approve pending requests for this achievement
4
4
  * so each waiting user is granted via existing request hooks.
@@ -1,5 +1,5 @@
1
- import { afterRequiresReviewDisabled } from './afterRequiresReviewDisabled';
2
- import { validateAchievementRules } from './validateEligibilityRules';
1
+ import { afterRequiresReviewDisabled } from './afterRequiresReviewDisabled.js';
2
+ import { validateAchievementRules } from './validateEligibilityRules.js';
3
3
  export const hooks = {
4
4
  beforeValidate: [validateAchievementRules],
5
5
  afterChange: [afterRequiresReviewDisabled],
@@ -1,4 +1,4 @@
1
- import { assertRuleGroupValid } from '../../../services/achievement/validateRules';
1
+ import { assertRuleGroupValid } from '../../../services/achievement/validateRules.js';
2
2
  export const validateAchievementRules = ({ data }) => {
3
3
  if (!data)
4
4
  return data;
@@ -1,7 +1,7 @@
1
- import { buildRuleTreeFields, localizedDescriptionField, localizedNameField, scopeField } from '../fields';
2
- import { collectionAdmin, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers';
3
- import { access } from './access';
4
- import { hooks } from './hooks';
1
+ import { buildRuleTreeFields, localizedDescriptionField, localizedNameField, scopeField } from '../fields/index.js';
2
+ import { collectionAdmin, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers.js';
3
+ import { access } from './access/index.js';
4
+ import { hooks } from './hooks/index.js';
5
5
  export function buildAchievementsCollection() {
6
6
  return {
7
7
  slug: slugOf('achievements'),
@@ -1,2 +1,2 @@
1
- import { definitionAccess } from '../../access/definitions';
1
+ import { definitionAccess } from '../../access/definitions.js';
2
2
  export const access = definitionAccess('eventTypes');
@@ -1,5 +1,5 @@
1
- import { lockSystemCatalogFields } from '../../hooks/lockSystemCatalogFields';
2
- import { preventCatalogDelete } from '../../hooks/preventCatalogDelete';
1
+ import { lockSystemCatalogFields } from '../../hooks/lockSystemCatalogFields.js';
2
+ import { preventCatalogDelete } from '../../hooks/preventCatalogDelete.js';
3
3
  export const hooks = {
4
4
  beforeChange: [lockSystemCatalogFields],
5
5
  beforeDelete: [preventCatalogDelete({ kind: 'eventType' })],
@@ -1,7 +1,7 @@
1
- import { collectionAdmin, collectionOf, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers';
2
- import { localizedNameField, scopeField } from '../fields';
3
- import { access } from './access';
4
- import { hooks } from './hooks';
1
+ import { collectionAdmin, collectionOf, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers.js';
2
+ import { localizedNameField, scopeField } from '../fields/index.js';
3
+ import { access } from './access/index.js';
4
+ import { hooks } from './hooks/index.js';
5
5
  export function buildEventTypesCollection() {
6
6
  return {
7
7
  slug: slugOf('eventTypes'),
@@ -1,5 +1,5 @@
1
- import { requireOne } from '../../../access/index';
2
- import { isReviewer, isSelfUser } from '../../../access/roles/index';
1
+ import { requireOne } from '../../../access/index.js';
2
+ import { isReviewer, isSelfUser } from '../../../access/roles/index.js';
3
3
  export const access = {
4
4
  read: requireOne(isReviewer('grants'), isSelfUser('user')),
5
5
  create: requireOne(isReviewer('grants')),
@@ -1,6 +1,6 @@
1
- import { CTX_CASCADING_REVOKE, CTX_SKIP_GRANT_SIDE_EFFECTS, runAfterGrantCreated, runAfterGrantDeleted } from '../../../services/achievement/grantSideEffects';
2
- import { relationId } from '../../../services/achievement/relationId';
3
- import { collectionOf } from '../../../collections/helpers';
1
+ import { CTX_CASCADING_REVOKE, CTX_SKIP_GRANT_SIDE_EFFECTS, runAfterGrantCreated, runAfterGrantDeleted } from '../../../services/achievement/grantSideEffects.js';
2
+ import { relationId } from '../../../services/achievement/relationId.js';
3
+ import { collectionOf } from '../../../collections/helpers.js';
4
4
  async function achievementSlug(req, achievementId) {
5
5
  try {
6
6
  const def = (await req.payload.findByID({
@@ -1,6 +1,6 @@
1
1
  import { APIError } from 'payload';
2
- import { collectionOf } from '../../helpers';
3
- import { relationId } from '../../../services/achievement/relationId';
2
+ import { collectionOf } from '../../helpers.js';
3
+ import { relationId } from '../../../services/achievement/relationId.js';
4
4
  /** Reject a second grant of the same achievement for the same user (+ scope). */
5
5
  export const ensureUniqueGrant = async ({ data, originalDoc, operation, req, }) => {
6
6
  if (!req?.payload || !data)
@@ -1,6 +1,6 @@
1
- import { ensureUniqueGrant } from './ensureUniqueGrant';
2
- import { fillGrantTitle, setGrantTitle } from './setGrantTitle';
3
- import { afterGrantChange, afterGrantDelete } from './afterGrantMutation';
1
+ import { ensureUniqueGrant } from './ensureUniqueGrant.js';
2
+ import { fillGrantTitle, setGrantTitle } from './setGrantTitle.js';
3
+ import { afterGrantChange, afterGrantDelete } from './afterGrantMutation.js';
4
4
  export const hooks = {
5
5
  beforeValidate: [ensureUniqueGrant],
6
6
  beforeChange: [setGrantTitle],
@@ -1,5 +1,5 @@
1
- import { relationId } from '../../../services/achievement/relationId';
2
- import { collectionOf } from '../../helpers';
1
+ import { relationId } from '../../../services/achievement/relationId.js';
2
+ import { collectionOf } from '../../helpers.js';
3
3
  async function achievementName(args) {
4
4
  const id = relationId(args.value);
5
5
  if (!id)
@@ -1,8 +1,8 @@
1
- import { collectionAdmin, collectionOf, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers';
2
- import { scopeField, userField } from '../fields';
3
- import { getAchievementOptions } from '../../options-store';
4
- import { access } from './access';
5
- import { hooks } from './hooks';
1
+ import { collectionAdmin, collectionOf, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers.js';
2
+ import { scopeField, userField } from '../fields/index.js';
3
+ import { getAchievementOptions } from '../../options-store.js';
4
+ import { access } from './access/index.js';
5
+ import { hooks } from './hooks/index.js';
6
6
  export function buildGrantsCollection() {
7
7
  const reconcilePath = getAchievementOptions().endpoints?.reconcile;
8
8
  const apiPath = typeof reconcilePath === 'string' && reconcilePath.length > 0
@@ -1,5 +1,5 @@
1
- import { requireOne } from '../../../access/index';
2
- import { isReviewer, isSelfUser } from '../../../access/roles/index';
1
+ import { requireOne } from '../../../access/index.js';
2
+ import { isReviewer, isSelfUser } from '../../../access/roles/index.js';
3
3
  export const access = {
4
4
  read: requireOne(isReviewer('logs'), isSelfUser('user')),
5
5
  create: requireOne(isReviewer('logs')),
@@ -1,5 +1,5 @@
1
- import { eventTypeRequiresActor, eventTypeRequiresMetric, } from '../../../services/achievement/eventTypeRequiresActor';
2
- import { relationId } from '../../../services/achievement/relationId';
1
+ import { eventTypeRequiresActor, eventTypeRequiresMetric, } from '../../../services/achievement/eventTypeRequiresActor.js';
2
+ import { relationId } from '../../../services/achievement/relationId.js';
3
3
  export const validateActor = async (value, { data, req }) => {
4
4
  if (!req?.payload)
5
5
  return true;
@@ -1,6 +1,6 @@
1
1
  import { APIError } from 'payload';
2
- import { eventTypeRequiresActor, eventTypeRequiresMetric, } from '../../../services/achievement/eventTypeRequiresActor';
3
- import { relationId } from '../../../services/achievement/relationId';
2
+ import { eventTypeRequiresActor, eventTypeRequiresMetric, } from '../../../services/achievement/eventTypeRequiresActor.js';
3
+ import { relationId } from '../../../services/achievement/relationId.js';
4
4
  export const ensureTypeRequirements = async ({ data, req }) => {
5
5
  if (!data)
6
6
  return data;
@@ -1,4 +1,4 @@
1
- import { ensureTypeRequirements } from './ensureTypeRequirements';
1
+ import { ensureTypeRequirements } from './ensureTypeRequirements.js';
2
2
  export const hooks = {
3
3
  beforeValidate: [ensureTypeRequirements],
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/Logs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAS,MAAM,SAAS,CAAA;AAUtD,+EAA+E;AAC/E,wBAAgB,mBAAmB,IAAI,gBAAgB,CA0GtD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/Logs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAS,MAAM,SAAS,CAAA;AAUtD,+EAA+E;AAC/E,wBAAgB,mBAAmB,IAAI,gBAAgB,CA6GtD"}
@@ -1,10 +1,10 @@
1
- import { catalogFilterOptions } from '../fields/catalogFilter';
2
- import { collectionAdmin, collectionOf, optionalFields, slugOf } from '../helpers';
3
- import { getAchievementOptions } from '../../options-store';
4
- import { scopeField, userField } from '../fields';
5
- import { access } from './access';
6
- import { validateActor, validateChange, validateMetric } from './fields/validators';
7
- import { hooks } from './hooks';
1
+ import { catalogFilterOptions } from '../fields/catalogFilter.js';
2
+ import { collectionAdmin, collectionOf, optionalFields, slugOf } from '../helpers.js';
3
+ import { getAchievementOptions } from '../../options-store.js';
4
+ import { scopeField, userField } from '../fields/index.js';
5
+ import { access } from './access/index.js';
6
+ import { validateActor, validateChange, validateMetric } from './fields/validators.js';
7
+ import { hooks } from './hooks/index.js';
8
8
  /** Append-only occurrence log. `type` / `metric` are catalog relationships. */
9
9
  export function buildLogsCollection() {
10
10
  const users = getAchievementOptions().usersCollectionSlug ?? 'users';
@@ -104,7 +104,9 @@ export function buildLogsCollection() {
104
104
  {
105
105
  name: 'data',
106
106
  type: 'json',
107
- admin: { description: 'Any extra structured details.' },
107
+ admin: {
108
+ description: 'Engine transition envelope: `{ from, to }` each `{ id, slug? }` or null (tier.changed, achievement.granted/revoked). Hosts may add extra keys.',
109
+ },
108
110
  },
109
111
  ],
110
112
  },
@@ -1,2 +1,2 @@
1
- import { definitionAccess } from '../../access/definitions';
1
+ import { definitionAccess } from '../../access/definitions.js';
2
2
  export const access = definitionAccess('metrics');
@@ -1,5 +1,5 @@
1
- import { lockSystemCatalogFields } from '../../hooks/lockSystemCatalogFields';
2
- import { preventCatalogDelete } from '../../hooks/preventCatalogDelete';
1
+ import { lockSystemCatalogFields } from '../../hooks/lockSystemCatalogFields.js';
2
+ import { preventCatalogDelete } from '../../hooks/preventCatalogDelete.js';
3
3
  export const hooks = {
4
4
  beforeChange: [lockSystemCatalogFields],
5
5
  beforeDelete: [preventCatalogDelete({ kind: 'metric' })],
@@ -1,7 +1,7 @@
1
- import { collectionAdmin, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers';
2
- import { localizedNameField, scopeField } from '../fields';
3
- import { access } from './access';
4
- import { hooks } from './hooks';
1
+ import { collectionAdmin, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers.js';
2
+ import { localizedNameField, scopeField } from '../fields/index.js';
3
+ import { access } from './access/index.js';
4
+ import { hooks } from './hooks/index.js';
5
5
  export function buildMetricsCollection() {
6
6
  return {
7
7
  slug: slugOf('metrics'),
@@ -1,5 +1,5 @@
1
- import { isAuthenticated, requireOne } from '../../../access/index';
2
- import { isReviewer, isSelfUser } from '../../../access/roles/index';
1
+ import { isAuthenticated, requireOne } from '../../../access/index.js';
2
+ import { isReviewer, isSelfUser } from '../../../access/roles/index.js';
3
3
  export const access = {
4
4
  read: requireOne(isReviewer('tierRequests'), isSelfUser('user')),
5
5
  create: isAuthenticated,
@@ -1,4 +1,4 @@
1
- import { afterTierRequestChange, prepareTierRequest } from './prepareTierRequest';
1
+ import { afterTierRequestChange, prepareTierRequest } from './prepareTierRequest.js';
2
2
  export const hooks = {
3
3
  beforeValidate: [prepareTierRequest],
4
4
  afterChange: [afterTierRequestChange],
@@ -1,8 +1,8 @@
1
1
  import { APIError } from 'payload';
2
- import { collectionOf } from '../../../collections/helpers';
3
- import { CTX_SYSTEM_REQUEST } from '../../../services/achievement/contextFlags';
4
- import { syncTierChangedLog } from '../../../services/achievement/recordEvent';
5
- import { relationId } from '../../../services/achievement/relationId';
2
+ import { collectionOf } from '../../../collections/helpers.js';
3
+ import { CTX_SYSTEM_REQUEST } from '../../../services/achievement/contextFlags.js';
4
+ import { syncTierChangedLog } from '../../../services/achievement/recordEvent.js';
5
+ import { relationId } from '../../../services/achievement/relationId.js';
6
6
  function scopeIdOf(data) {
7
7
  return relationId(data?.scope);
8
8
  }
@@ -1,7 +1,7 @@
1
- import { collectionAdmin, collectionOf, optionalFields, slugOf } from '../helpers';
2
- import { scopeField, userField } from '../fields';
3
- import { access } from './access';
4
- import { hooks } from './hooks';
1
+ import { collectionAdmin, collectionOf, optionalFields, slugOf } from '../helpers.js';
2
+ import { scopeField, userField } from '../fields/index.js';
3
+ import { access } from './access/index.js';
4
+ import { hooks } from './hooks/index.js';
5
5
  export function buildTierRequestsCollection() {
6
6
  return {
7
7
  slug: slugOf('tierRequests'),
@@ -1,2 +1,2 @@
1
- import { definitionAccess } from '../../access/definitions';
1
+ import { definitionAccess } from '../../access/definitions.js';
2
2
  export const access = definitionAccess('tiers');
@@ -1,4 +1,4 @@
1
- import { didDisableRequiresReview, releasePendingTierReviews, } from '../../../services/achievement/releaseReviewGate';
1
+ import { didDisableRequiresReview, releasePendingTierReviews, } from '../../../services/achievement/releaseReviewGate.js';
2
2
  /**
3
3
  * When Requires review is turned off, approve pending tier requests for this step
4
4
  * so each waiting user gets a tier.changed audit via existing request hooks.
@@ -1,5 +1,5 @@
1
- import { afterRequiresReviewDisabled } from './afterRequiresReviewDisabled';
2
- import { validateUnlockRules } from './validateUnlockRules';
1
+ import { afterRequiresReviewDisabled } from './afterRequiresReviewDisabled.js';
2
+ import { validateUnlockRules } from './validateUnlockRules.js';
3
3
  export const hooks = {
4
4
  beforeValidate: [validateUnlockRules],
5
5
  afterChange: [afterRequiresReviewDisabled],
@@ -1,4 +1,4 @@
1
- import { assertRuleGroupValid } from '../../../services/achievement/validateRules';
1
+ import { assertRuleGroupValid } from '../../../services/achievement/validateRules.js';
2
2
  export const validateUnlockRules = ({ data }) => {
3
3
  if (!data)
4
4
  return data;
@@ -1,8 +1,8 @@
1
- import { collectionAdmin, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers';
2
- import { buildRuleTreeFields, localizedDescriptionField, localizedNameField, scopeField } from '../fields';
3
- import { getAchievementOptions } from '../../options-store';
4
- import { access } from './access';
5
- import { hooks } from './hooks';
1
+ import { collectionAdmin, columnsWithOptionalScope, optionalFields, slugOf } from '../helpers.js';
2
+ import { buildRuleTreeFields, localizedDescriptionField, localizedNameField, scopeField } from '../fields/index.js';
3
+ import { getAchievementOptions } from '../../options-store.js';
4
+ import { access } from './access/index.js';
5
+ import { hooks } from './hooks/index.js';
6
6
  export function buildTiersCollection() {
7
7
  const mediaCollection = getAchievementOptions().mediaCollection?.trim();
8
8
  return {
@@ -1,5 +1,5 @@
1
1
  import type { CollectionConfig } from 'payload';
2
- import type { AchievementCollectionKey } from '../../types';
2
+ import type { AchievementCollectionKey } from '../../types.js';
3
3
  /** Catalog / definition collections (writes gated by `canReview`). */
4
4
  export declare function definitionAccess(collectionKey: AchievementCollectionKey): NonNullable<CollectionConfig['access']>;
5
5
  //# sourceMappingURL=definitions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../../src/collections/access/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAI3D,sEAAsE;AACtE,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,wBAAwB,GACtC,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAOzC"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../../src/collections/access/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAI9D,sEAAsE;AACtE,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,wBAAwB,GACtC,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAOzC"}
@@ -1,5 +1,5 @@
1
- import { isAuthenticated, requireOne } from '../../access/index';
2
- import { isReviewer } from '../../access/roles/index';
1
+ import { isAuthenticated, requireOne } from '../../access/index.js';
2
+ import { isReviewer } from '../../access/roles/index.js';
3
3
  /** Catalog / definition collections (writes gated by `canReview`). */
4
4
  export function definitionAccess(collectionKey) {
5
5
  return {
@@ -1,5 +1,5 @@
1
1
  import type { CollectionConfig } from 'payload';
2
- import type { AchievementCollectionOverride } from '../types';
2
+ import type { AchievementCollectionOverride } from '../types.js';
3
3
  /**
4
4
  * Layer host overrides on a plugin collection:
5
5
  * - `access` / `admin` / `labels`: shallow merge (host wins per key)
@@ -1 +1 @@
1
- {"version":3,"file":"applyOverrides.d.ts","sourceRoot":"","sources":["../../src/collections/applyOverrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAA;AAE7D;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,CAAC,EAAE,6BAA6B,GACvC,gBAAgB,CA6BlB"}
1
+ {"version":3,"file":"applyOverrides.d.ts","sourceRoot":"","sources":["../../src/collections/applyOverrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAEhE;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,gBAAgB,EAC5B,QAAQ,CAAC,EAAE,6BAA6B,GACvC,gBAAgB,CA6BlB"}
@@ -1,4 +1,4 @@
1
- import { relationId } from '../../services/achievement/relationId';
1
+ import { relationId } from '../../services/achievement/relationId.js';
2
2
  /** Relationship picker: same scope as the parent doc, or unscoped (global) catalog rows. */
3
3
  export function catalogFilterOptions({ data }) {
4
4
  const scopeId = relationId(data?.scope);
@@ -1,6 +1,6 @@
1
- export { scopeField } from './scopeField';
2
- export { userField } from './userField';
3
- export { buildRuleRowFields, buildRuleTreeFields } from './ruleFields';
4
- export { usersAchievementsGroup } from './usersAchievementsGroup';
5
- export { localizedDescriptionField, localizedNameField } from './localizedText';
1
+ export { scopeField } from './scopeField.js';
2
+ export { userField } from './userField.js';
3
+ export { buildRuleRowFields, buildRuleTreeFields } from './ruleFields.js';
4
+ export { usersAchievementsGroup } from './usersAchievementsGroup.js';
5
+ export { localizedDescriptionField, localizedNameField } from './localizedText.js';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/fields/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/fields/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA"}