@dappermountain/payload-plugin-achievements 0.2.3 → 0.2.5
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.
- package/README.md +5 -1
- package/dist/admin/LucideIconField.d.ts +6 -0
- package/dist/admin/LucideIconField.d.ts.map +1 -0
- package/dist/admin/LucideIconField.js +56 -0
- package/dist/collections/Tiers/index.d.ts.map +1 -1
- package/dist/collections/Tiers/index.js +4 -1
- package/dist/collections/fields/localizedText.d.ts +1 -0
- package/dist/collections/fields/localizedText.d.ts.map +1 -1
- package/dist/collections/fields/localizedText.js +28 -1
- package/dist/collections/fields/usersAchievementsGroup.d.ts.map +1 -1
- package/dist/collections/fields/usersAchievementsGroup.js +2 -1
- package/dist/exports/client.d.ts +1 -0
- package/dist/exports/client.d.ts.map +1 -1
- package/dist/exports/client.js +1 -0
- package/dist/fields/descriptionPlaintext.d.ts +6 -0
- package/dist/fields/descriptionPlaintext.d.ts.map +1 -0
- package/dist/fields/descriptionPlaintext.js +24 -0
- package/dist/fields/plainTextToLexical.d.ts +7 -0
- package/dist/fields/plainTextToLexical.d.ts.map +1 -0
- package/dist/fields/plainTextToLexical.js +40 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/seed/index.d.ts.map +1 -1
- package/dist/seed/index.js +6 -3
- package/dist/services/achievement/buildCatalogProgressGroups.d.ts +5 -3
- package/dist/services/achievement/buildCatalogProgressGroups.d.ts.map +1 -1
- package/dist/services/achievement/buildCatalogProgressGroups.js +11 -6
- package/dist/services/achievement/getUserProgress.d.ts +2 -1
- package/dist/services/achievement/getUserProgress.d.ts.map +1 -1
- package/dist/services/achievement/getUserProgress.js +4 -3
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -133,9 +133,13 @@ When your Payload config enables **`localization`**, catalog display fields are
|
|
|
133
133
|
|
|
134
134
|
| Collection | Localized | Not localized |
|
|
135
135
|
| --- | --- | --- |
|
|
136
|
-
| Achievements / tiers | `name
|
|
136
|
+
| Achievements / tiers | `name` (text), `description` (**Lexical** rich text) | `slug`, rules, flags |
|
|
137
137
|
| Metrics / event types | `name` | `slug`, system flags |
|
|
138
138
|
|
|
139
|
+
Tier `icon` is a searchable Lucide picker in Admin (stores the kebab-case name, e.g. `sparkles`). Hosts must peer-depend on `@payloadcms/richtext-lexical` and `lucide-react` (same major as Payload). After upgrading, run `payload generate:importmap` and push/migrate schema so `description` columns accept JSON.
|
|
140
|
+
|
|
141
|
+
Progress / `GET /api/achievements/me` pass through catalog `description` as **Lexical** (same as the collection document). Convert to HTML/plaintext in the UI with `@payloadcms/richtext-lexical` helpers (`convertLexicalToHTML`, `convertLexicalToPlaintext`) — the plugin also exports `descriptionToPlaintext` / `plainTextToLexical` for hosts.
|
|
142
|
+
|
|
139
143
|
UI chrome and validation messages ship in English. Application UI copy stays in your app’s i18n layer — the plugin does not inject host translation dictionaries. Seed extra locales yourself after the English system catalog is in place.
|
|
140
144
|
|
|
141
145
|
## Configuration reference
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LucideIconField.d.ts","sourceRoot":"","sources":["../../src/admin/LucideIconField.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAgB,MAAM,SAAS,CAAA;AA4BrE;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,wBA4D7B,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { FieldDescription, FieldError, FieldLabel, SelectInput, useField } from '@payloadcms/ui';
|
|
4
|
+
import { icons } from 'lucide-react';
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
function toKebabCase(pascal) {
|
|
7
|
+
return pascal
|
|
8
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
9
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
|
|
10
|
+
.toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
function toPascalCase(kebab) {
|
|
13
|
+
return kebab
|
|
14
|
+
.split('-')
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
17
|
+
.join('');
|
|
18
|
+
}
|
|
19
|
+
const ICON_OPTIONS = Object.keys(icons)
|
|
20
|
+
.filter((key) => /^[A-Z]/.test(key))
|
|
21
|
+
.map((pascal) => {
|
|
22
|
+
const value = toKebabCase(pascal);
|
|
23
|
+
return { label: value, value };
|
|
24
|
+
})
|
|
25
|
+
.sort((a, b) => a.value.localeCompare(b.value));
|
|
26
|
+
/**
|
|
27
|
+
* Searchable Lucide icon picker. Stores the kebab-case Lucide name (e.g. `sparkles`).
|
|
28
|
+
*/
|
|
29
|
+
export const LucideIconField = (props) => {
|
|
30
|
+
const { field, path: pathFromProps, readOnly } = props;
|
|
31
|
+
const path = pathFromProps ?? field?.name ?? 'icon';
|
|
32
|
+
const { errorMessage, setValue, showError, value } = useField({
|
|
33
|
+
path,
|
|
34
|
+
});
|
|
35
|
+
const selected = typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
36
|
+
const PreviewIcon = selected
|
|
37
|
+
? icons[toPascalCase(selected)]
|
|
38
|
+
: undefined;
|
|
39
|
+
const options = useMemo(() => ICON_OPTIONS, []);
|
|
40
|
+
return (_jsxs("div", { className: "field-type", children: [_jsx(FieldLabel, { label: field?.label ?? 'Icon', path: path, required: Boolean(field?.required) }), _jsxs("div", { style: { alignItems: 'center', display: 'flex', gap: '0.75rem' }, children: [_jsx("div", { "aria-hidden": true, style: {
|
|
41
|
+
alignItems: 'center',
|
|
42
|
+
border: '1px solid var(--theme-elevation-150)',
|
|
43
|
+
borderRadius: 6,
|
|
44
|
+
display: 'flex',
|
|
45
|
+
flexShrink: 0,
|
|
46
|
+
height: 40,
|
|
47
|
+
justifyContent: 'center',
|
|
48
|
+
width: 40,
|
|
49
|
+
}, children: PreviewIcon ? (_jsx(PreviewIcon, { size: 20 })) : (_jsx("span", { style: { color: 'var(--theme-elevation-400)', fontSize: 12 }, children: "\u2014" })) }), _jsx("div", { style: { flex: 1, minWidth: 0 }, children: _jsx(SelectInput, { isClearable: true, name: path, onChange: (option) => {
|
|
50
|
+
if (Array.isArray(option)) {
|
|
51
|
+
setValue(option[0]?.value ?? null);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
setValue(option?.value ?? null);
|
|
55
|
+
}, options: options, path: path, readOnly: Boolean(readOnly), value: selected }) })] }), _jsx(FieldDescription, { description: field?.admin?.description, path: path }), _jsx(FieldError, { message: errorMessage, path: path, showError: showError })] }));
|
|
56
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/Tiers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAQ/C,wBAAgB,oBAAoB,IAAI,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/collections/Tiers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAQ/C,wBAAgB,oBAAoB,IAAI,gBAAgB,CA2FvD"}
|
|
@@ -49,7 +49,10 @@ export function buildTiersCollection() {
|
|
|
49
49
|
type: 'text',
|
|
50
50
|
admin: {
|
|
51
51
|
width: mediaCollection ? '50%' : '100%',
|
|
52
|
-
description: 'Optional
|
|
52
|
+
description: 'Optional Lucide icon for the rank ladder when no image is set (searchable by name).',
|
|
53
|
+
components: {
|
|
54
|
+
Field: '@dappermountain/payload-plugin-achievements/client#LucideIconField',
|
|
55
|
+
},
|
|
53
56
|
},
|
|
54
57
|
},
|
|
55
58
|
...(mediaCollection
|
|
@@ -6,5 +6,6 @@ import type { Field } from 'payload';
|
|
|
6
6
|
export declare function localizedNameField(admin?: {
|
|
7
7
|
width?: string;
|
|
8
8
|
}): Field;
|
|
9
|
+
/** Catalog blurb — Lexical in Admin; seed may still pass plain strings (coerced). */
|
|
9
10
|
export declare function localizedDescriptionField(): Field;
|
|
10
11
|
//# sourceMappingURL=localizedText.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"localizedText.d.ts","sourceRoot":"","sources":["../../../src/collections/fields/localizedText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"localizedText.d.ts","sourceRoot":"","sources":["../../../src/collections/fields/localizedText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAgBpC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAQpE;AAED,qFAAqF;AACrF,wBAAgB,yBAAyB,IAAI,KAAK,CA4BjD"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { BoldFeature, FixedToolbarFeature, InlineToolbarFeature, ItalicFeature, LinkFeature, OrderedListFeature, ParagraphFeature, UnderlineFeature, UnorderedListFeature, lexicalEditor, } from '@payloadcms/richtext-lexical';
|
|
2
|
+
import { plainTextToLexical } from '../../fields/plainTextToLexical.js';
|
|
1
3
|
/**
|
|
2
4
|
* Display copy for catalog rows. Localized when the host enables Payload `localization`.
|
|
3
5
|
* Slugs stay non-localized identifiers for rules and code.
|
|
@@ -11,10 +13,35 @@ export function localizedNameField(admin) {
|
|
|
11
13
|
...(admin ? { admin } : {}),
|
|
12
14
|
};
|
|
13
15
|
}
|
|
16
|
+
/** Catalog blurb — Lexical in Admin; seed may still pass plain strings (coerced). */
|
|
14
17
|
export function localizedDescriptionField() {
|
|
15
18
|
return {
|
|
16
19
|
name: 'description',
|
|
17
|
-
type: '
|
|
20
|
+
type: 'richText',
|
|
18
21
|
localized: true,
|
|
22
|
+
editor: lexicalEditor({
|
|
23
|
+
features: () => [
|
|
24
|
+
ParagraphFeature(),
|
|
25
|
+
BoldFeature(),
|
|
26
|
+
ItalicFeature(),
|
|
27
|
+
UnderlineFeature(),
|
|
28
|
+
UnorderedListFeature(),
|
|
29
|
+
OrderedListFeature(),
|
|
30
|
+
LinkFeature(),
|
|
31
|
+
FixedToolbarFeature(),
|
|
32
|
+
InlineToolbarFeature(),
|
|
33
|
+
],
|
|
34
|
+
}),
|
|
35
|
+
hooks: {
|
|
36
|
+
beforeValidate: [
|
|
37
|
+
({ value }) => {
|
|
38
|
+
if (value == null || value === '')
|
|
39
|
+
return value;
|
|
40
|
+
if (typeof value === 'string')
|
|
41
|
+
return plainTextToLexical(value);
|
|
42
|
+
return value;
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
19
46
|
};
|
|
20
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usersAchievementsGroup.d.ts","sourceRoot":"","sources":["../../../src/collections/fields/usersAchievementsGroup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAEnE;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,0BAA0B,GAAG,KAAK,
|
|
1
|
+
{"version":3,"file":"usersAchievementsGroup.d.ts","sourceRoot":"","sources":["../../../src/collections/fields/usersAchievementsGroup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAEnE;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,0BAA0B,GAAG,KAAK,CAiCjF"}
|
|
@@ -17,7 +17,8 @@ export function usersAchievementsGroup(options) {
|
|
|
17
17
|
collection: slugs.grants,
|
|
18
18
|
on: 'user',
|
|
19
19
|
admin: {
|
|
20
|
-
|
|
20
|
+
// Create from the user doc — Payload pre-fills `user` on the grant drawer.
|
|
21
|
+
allowCreate: true,
|
|
21
22
|
defaultColumns: ['achievement', 'completedAt', 'scope'],
|
|
22
23
|
},
|
|
23
24
|
},
|
package/dist/exports/client.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ActorField } from '../admin/ActorField.js';
|
|
2
|
+
export { LucideIconField } from '../admin/LucideIconField.js';
|
|
2
3
|
export { MetricChangeField } from '../admin/MetricChangeField.js';
|
|
3
4
|
export { MetricField } from '../admin/MetricField.js';
|
|
4
5
|
export { ReconcileProgressionButton } from '../admin/ReconcileProgressionButton.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAA"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,wCAAwC,CAAA"}
|
package/dist/exports/client.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { ActorField } from '../admin/ActorField.js';
|
|
2
|
+
export { LucideIconField } from '../admin/LucideIconField.js';
|
|
2
3
|
export { MetricChangeField } from '../admin/MetricChangeField.js';
|
|
3
4
|
export { MetricField } from '../admin/MetricField.js';
|
|
4
5
|
export { ReconcileProgressionButton } from '../admin/ReconcileProgressionButton.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress / me APIs expose catalog blurbs as plain strings for search and simple UI.
|
|
3
|
+
* Admin stores Lexical JSON; legacy string rows still work.
|
|
4
|
+
*/
|
|
5
|
+
export declare function descriptionToPlaintext(value: unknown): string | undefined;
|
|
6
|
+
//# sourceMappingURL=descriptionPlaintext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptionPlaintext.d.ts","sourceRoot":"","sources":["../../src/fields/descriptionPlaintext.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAgBzE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { convertLexicalToPlaintext } from '@payloadcms/richtext-lexical/plaintext';
|
|
2
|
+
/**
|
|
3
|
+
* Progress / me APIs expose catalog blurbs as plain strings for search and simple UI.
|
|
4
|
+
* Admin stores Lexical JSON; legacy string rows still work.
|
|
5
|
+
*/
|
|
6
|
+
export function descriptionToPlaintext(value) {
|
|
7
|
+
if (value == null)
|
|
8
|
+
return undefined;
|
|
9
|
+
if (typeof value === 'string') {
|
|
10
|
+
const trimmed = value.trim();
|
|
11
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
12
|
+
}
|
|
13
|
+
if (typeof value !== 'object')
|
|
14
|
+
return undefined;
|
|
15
|
+
try {
|
|
16
|
+
const plaintext = convertLexicalToPlaintext({
|
|
17
|
+
data: value,
|
|
18
|
+
}).trim();
|
|
19
|
+
return plaintext.length > 0 ? plaintext : undefined;
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SerializedEditorState } from '@payloadcms/richtext-lexical/lexical';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal Lexical editor state for a single paragraph of plain text.
|
|
4
|
+
* Used by seed + beforeValidate coercion when hosts still pass strings.
|
|
5
|
+
*/
|
|
6
|
+
export declare function plainTextToLexical(text: string): SerializedEditorState;
|
|
7
|
+
//# sourceMappingURL=plainTextToLexical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plainTextToLexical.d.ts","sourceRoot":"","sources":["../../src/fields/plainTextToLexical.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAA;AAEjF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAmCtE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal Lexical editor state for a single paragraph of plain text.
|
|
3
|
+
* Used by seed + beforeValidate coercion when hosts still pass strings.
|
|
4
|
+
*/
|
|
5
|
+
export function plainTextToLexical(text) {
|
|
6
|
+
const trimmed = text.trim();
|
|
7
|
+
return {
|
|
8
|
+
root: {
|
|
9
|
+
type: 'root',
|
|
10
|
+
format: '',
|
|
11
|
+
indent: 0,
|
|
12
|
+
version: 1,
|
|
13
|
+
direction: 'ltr',
|
|
14
|
+
children: [
|
|
15
|
+
{
|
|
16
|
+
type: 'paragraph',
|
|
17
|
+
format: '',
|
|
18
|
+
indent: 0,
|
|
19
|
+
version: 1,
|
|
20
|
+
direction: 'ltr',
|
|
21
|
+
textFormat: 0,
|
|
22
|
+
textStyle: '',
|
|
23
|
+
children: trimmed
|
|
24
|
+
? [
|
|
25
|
+
{
|
|
26
|
+
type: 'text',
|
|
27
|
+
text: trimmed,
|
|
28
|
+
detail: 0,
|
|
29
|
+
format: 0,
|
|
30
|
+
mode: 'normal',
|
|
31
|
+
style: '',
|
|
32
|
+
version: 1,
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
: [],
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,4 +10,6 @@ export { DEFAULT_COLLECTION_BASE_SLUGS, DEFAULT_COLLECTION_PREFIX, DEFAULT_ADMIN
|
|
|
10
10
|
export { DEFAULT_ME_ENDPOINT_PATH, DEFAULT_RECONCILE_ENDPOINT_PATH } from './defaults.js';
|
|
11
11
|
export { collectionOf, slugOf } from './collections/helpers.js';
|
|
12
12
|
export { isAchievementPluginEnabled } from './enabled.js';
|
|
13
|
+
export { descriptionToPlaintext } from './fields/descriptionPlaintext.js';
|
|
14
|
+
export { plainTextToLexical } from './fields/plainTextToLexical.js';
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,YAAY,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,GACpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,8BAA8B,EAC9B,0BAA0B,EAC1B,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,gCAAgC,EAChC,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EACV,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,iBAAiB,EACjB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,2BAA2B,EAC3B,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,6BAA6B,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AACtH,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAA;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,cAAc,GACf,MAAM,cAAc,CAAA;AACrB,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,YAAY,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,GACpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,8BAA8B,EAC9B,0BAA0B,EAC1B,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,gCAAgC,EAChC,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EACV,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,iBAAiB,EACjB,wBAAwB,EACxB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,iCAAiC,CAAA;AACxC,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,6BAA6B,EAC7B,6BAA6B,EAC7B,2BAA2B,EAC3B,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,6BAA6B,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AACtH,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,eAAe,CAAA;AACzF,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -6,3 +6,5 @@ export { DEFAULT_COLLECTION_BASE_SLUGS, DEFAULT_COLLECTION_PREFIX, DEFAULT_ADMIN
|
|
|
6
6
|
export { DEFAULT_ME_ENDPOINT_PATH, DEFAULT_RECONCILE_ENDPOINT_PATH } from './defaults.js';
|
|
7
7
|
export { collectionOf, slugOf } from './collections/helpers.js';
|
|
8
8
|
export { isAchievementPluginEnabled } from './enabled.js';
|
|
9
|
+
export { descriptionToPlaintext } from './fields/descriptionPlaintext.js';
|
|
10
|
+
export { plainTextToLexical } from './fields/plainTextToLexical.js';
|
package/dist/seed/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seed/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/seed/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAOtC,mGAAmG;AACnG,MAAM,MAAM,4BAA4B,GAAG,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAExG,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,4BAA4B,CAAA;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,4BAA4B,CAAA;IAC1C,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qFAAqF;IACrF,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAAE,CAAA;CACrG,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,4BAA4B,CAAA;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,4BAA4B,CAAA;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAAE,CAAA;IACzG,qGAAqG;IACrG,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;KAAE,CAAA;CACzG,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,4BAA4B,CAAA;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,gFAAgF;IAChF,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,CAAC,EAAE,yBAAyB,EAAE,CAAA;IACxC,OAAO,CAAC,EAAE,yBAAyB,EAAE,CAAA;IACrC,KAAK,CAAC,EAAE,mBAAmB,EAAE,CAAA;IAC7B,YAAY,CAAC,EAAE,0BAA0B,EAAE,CAAA;IAC3C,gEAAgE;IAChE,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAA;CAClC,CAAA;AAmMD,2FAA2F;AAC3F,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB5F;AAiCD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqLnG"}
|
package/dist/seed/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ENGINE_EVENT_TYPES, ENGINE_METRICS } from '../catalog.js';
|
|
2
2
|
import { collectionOf } from '../collections/helpers.js';
|
|
3
|
+
import { plainTextToLexical } from '../fields/plainTextToLexical.js';
|
|
3
4
|
import { normalizeRuleGroup } from '../services/achievement/evaluateRules.js';
|
|
4
5
|
function localizedParts(value) {
|
|
5
6
|
if (value == null)
|
|
@@ -31,7 +32,7 @@ async function writeLocalizedFields(payload, args) {
|
|
|
31
32
|
data: {
|
|
32
33
|
...(locale === 'en' ? base : {}),
|
|
33
34
|
...(name != null ? { name } : {}),
|
|
34
|
-
...(description != null ? { description } : {}),
|
|
35
|
+
...(description != null ? { description: plainTextToLexical(description) } : {}),
|
|
35
36
|
},
|
|
36
37
|
locale: locale,
|
|
37
38
|
overrideAccess: true,
|
|
@@ -242,7 +243,7 @@ export async function seedAchievements(payload, input) {
|
|
|
242
243
|
...baseData,
|
|
243
244
|
name: nameParts.en ?? tier.slug,
|
|
244
245
|
...(localizedParts(tier.description).en != null
|
|
245
|
-
? { description: localizedParts(tier.description).en }
|
|
246
|
+
? { description: plainTextToLexical(localizedParts(tier.description).en) }
|
|
246
247
|
: {}),
|
|
247
248
|
},
|
|
248
249
|
locale: 'en',
|
|
@@ -290,7 +291,9 @@ export async function seedAchievements(payload, input) {
|
|
|
290
291
|
data: {
|
|
291
292
|
...baseData,
|
|
292
293
|
name: nameParts.en ?? achievement.slug,
|
|
293
|
-
...(descriptionParts.en != null
|
|
294
|
+
...(descriptionParts.en != null
|
|
295
|
+
? { description: plainTextToLexical(descriptionParts.en) }
|
|
296
|
+
: {}),
|
|
294
297
|
},
|
|
295
298
|
locale: 'en',
|
|
296
299
|
overrideAccess: true,
|
|
@@ -2,7 +2,8 @@ export type CatalogProgressItem = {
|
|
|
2
2
|
id: string;
|
|
3
3
|
name?: string;
|
|
4
4
|
slug?: string;
|
|
5
|
-
|
|
5
|
+
/** Same as the achievement collection field (Lexical JSON, or legacy string). */
|
|
6
|
+
description?: unknown;
|
|
6
7
|
completedAt?: string | null;
|
|
7
8
|
earned: boolean;
|
|
8
9
|
};
|
|
@@ -10,14 +11,15 @@ export type CatalogProgressGroup = {
|
|
|
10
11
|
id: string;
|
|
11
12
|
title: string;
|
|
12
13
|
slug?: string;
|
|
13
|
-
|
|
14
|
+
/** Same as the achievement collection field (Lexical JSON, or legacy string). */
|
|
15
|
+
description?: unknown;
|
|
14
16
|
items: CatalogProgressItem[];
|
|
15
17
|
};
|
|
16
18
|
type CatalogDoc = {
|
|
17
19
|
id: string;
|
|
18
20
|
name?: string;
|
|
19
21
|
slug?: string;
|
|
20
|
-
description?:
|
|
22
|
+
description?: unknown;
|
|
21
23
|
completionRules?: unknown;
|
|
22
24
|
};
|
|
23
25
|
type GrantDoc = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildCatalogProgressGroups.d.ts","sourceRoot":"","sources":["../../../src/services/achievement/buildCatalogProgressGroups.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"buildCatalogProgressGroups.d.ts","sourceRoot":"","sources":["../../../src/services/achievement/buildCatalogProgressGroups.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,GAAG;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,MAAM,EAAE,OAAO,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,KAAK,EAAE,mBAAmB,EAAE,CAAA;CAC7B,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED,KAAK,QAAQ,GAAG;IACd,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAiBD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAC/C,YAAY,EAAE,UAAU,EAAE,CAAA;IAC1B,MAAM,EAAE,QAAQ,EAAE,CAAA;CACnB,GAAG,oBAAoB,EAAE,CAyDzB"}
|
|
@@ -7,6 +7,13 @@ function grantKey(achievement) {
|
|
|
7
7
|
: '';
|
|
8
8
|
return { id, slug };
|
|
9
9
|
}
|
|
10
|
+
function passDescription(value) {
|
|
11
|
+
if (typeof value === 'string' && value.trim().length > 0)
|
|
12
|
+
return value;
|
|
13
|
+
if (value != null && typeof value === 'object')
|
|
14
|
+
return value;
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
10
17
|
/**
|
|
11
18
|
* Groups catalog achievements by composite parents (`completionRules`).
|
|
12
19
|
* Children follow completion-rule order. Unearned children stay in the list with `earned: false`.
|
|
@@ -27,14 +34,13 @@ export function buildCatalogProgressGroups(args) {
|
|
|
27
34
|
.map((doc) => [String(doc.slug), doc]));
|
|
28
35
|
const toItem = (doc) => {
|
|
29
36
|
const grant = grantsById.get(doc.id) ?? (doc.slug ? grantsBySlug.get(doc.slug) : undefined);
|
|
37
|
+
const description = passDescription(doc.description);
|
|
30
38
|
return {
|
|
31
39
|
id: doc.id,
|
|
32
40
|
earned: Boolean(grant),
|
|
33
41
|
...(typeof doc.name === 'string' && doc.name ? { name: doc.name } : {}),
|
|
34
42
|
...(typeof doc.slug === 'string' && doc.slug ? { slug: doc.slug } : {}),
|
|
35
|
-
...(
|
|
36
|
-
? { description: doc.description }
|
|
37
|
-
: {}),
|
|
43
|
+
...(description !== undefined ? { description } : {}),
|
|
38
44
|
completedAt: grant?.completedAt ?? null,
|
|
39
45
|
};
|
|
40
46
|
};
|
|
@@ -56,13 +62,12 @@ export function buildCatalogProgressGroups(args) {
|
|
|
56
62
|
seen.add(child.id);
|
|
57
63
|
items.push(toItem(child));
|
|
58
64
|
}
|
|
65
|
+
const description = passDescription(parent.description);
|
|
59
66
|
return {
|
|
60
67
|
id: parent.id,
|
|
61
68
|
title: parent.name || parent.slug || parent.id,
|
|
62
69
|
...(parent.slug ? { slug: parent.slug } : {}),
|
|
63
|
-
...(
|
|
64
|
-
? { description: parent.description }
|
|
65
|
-
: {}),
|
|
70
|
+
...(description !== undefined ? { description } : {}),
|
|
66
71
|
items,
|
|
67
72
|
};
|
|
68
73
|
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { PaginatedDocs, Payload, PayloadRequest } from 'payload';
|
|
2
|
+
/** Catalog slice — `description` matches the collection (Lexical JSON, or legacy string). */
|
|
2
3
|
type LeanCatalog = {
|
|
3
4
|
id: string;
|
|
4
5
|
name?: string;
|
|
5
6
|
slug?: string;
|
|
6
|
-
description?:
|
|
7
|
+
description?: unknown;
|
|
7
8
|
};
|
|
8
9
|
type LeanTier = LeanCatalog & {
|
|
9
10
|
rank?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUserProgress.d.ts","sourceRoot":"","sources":["../../../src/services/achievement/getUserProgress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAOrE,KAAK,WAAW,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"getUserProgress.d.ts","sourceRoot":"","sources":["../../../src/services/achievement/getUserProgress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAOrE,6FAA6F;AAC7F,KAAK,WAAW,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AACtF,KAAK,QAAQ,GAAG,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAExE,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAmBD,iBAAS,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;EAU9C;AAED,iBAAS,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;EAShD;AAoBD,MAAM,MAAM,sBAAsB,GAAG,aAAa,CAAC,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,GAAG;IACjF,sCAAsC;IACtC,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,EAAE,CAAA;CAC3C,CAAA;AAkED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,cAAc,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,CAAC,EAAE,qBAAqB,CAAA;IAC9B,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAiDlC"}
|
|
@@ -9,13 +9,14 @@ function leanCatalog(value) {
|
|
|
9
9
|
if (!value || typeof value !== 'object')
|
|
10
10
|
return { id };
|
|
11
11
|
const row = value;
|
|
12
|
+
const description = row.description;
|
|
13
|
+
const hasDescription = (typeof description === 'string' && description.trim().length > 0) ||
|
|
14
|
+
(description != null && typeof description === 'object');
|
|
12
15
|
return {
|
|
13
16
|
id,
|
|
14
17
|
...(typeof row.name === 'string' && row.name ? { name: row.name } : {}),
|
|
15
18
|
...(typeof row.slug === 'string' && row.slug ? { slug: row.slug } : {}),
|
|
16
|
-
...(
|
|
17
|
-
? { description: row.description }
|
|
18
|
-
: {}),
|
|
19
|
+
...(hasDescription ? { description } : {}),
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
22
|
function leanGrant(doc) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dappermountain/payload-plugin-achievements",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "A robust, Admin-configured achievements engine for Payload: composable unlock rules, derived rank progress, request/review grants, metrics, and scoped multi-tenant support.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -69,16 +69,20 @@
|
|
|
69
69
|
"skills:check": "bunx skills check -p"
|
|
70
70
|
},
|
|
71
71
|
"peerDependencies": {
|
|
72
|
+
"@payloadcms/richtext-lexical": "^3.88.0",
|
|
72
73
|
"@payloadcms/ui": "^3.88.0",
|
|
74
|
+
"lucide-react": "^0.543.0",
|
|
73
75
|
"payload": "^3.88.0",
|
|
74
76
|
"react": "^19.0.0"
|
|
75
77
|
},
|
|
76
78
|
"devDependencies": {
|
|
77
79
|
"@dappermountain/agent-payload": "^0.1.5",
|
|
78
80
|
"@dappermountain/agent-practices": "^0.1.2",
|
|
81
|
+
"@payloadcms/richtext-lexical": "3.88.0",
|
|
79
82
|
"@payloadcms/ui": "3.88.0",
|
|
80
83
|
"@types/bun": "1.4.0",
|
|
81
84
|
"@types/react": "^19.0.0",
|
|
85
|
+
"lucide-react": "0.543.0",
|
|
82
86
|
"payload": "3.88.0",
|
|
83
87
|
"prettier": "^3.6.2",
|
|
84
88
|
"react": "19.2.4",
|