Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d47ac71c47 | ||
|
|
17e5371e9c |
No files matched your search
@@ -42,6 +42,12 @@ separate service. It powers `/blog`; `/about` is a plain coded page.
|
|||||||
- **New env vars:** `DATABASE_URL` and `PAYLOAD_SECRET` on the frontend service.
|
- **New env vars:** `DATABASE_URL` and `PAYLOAD_SECRET` on the frontend service.
|
||||||
Staging must use a different `PAYLOAD_SECRET` from production.
|
Staging must use a different `PAYLOAD_SECRET` from production.
|
||||||
- Publishing workflow and house style: `nextjs-app/docs/PUBLISHING.md`.
|
- Publishing workflow and house style: `nextjs-app/docs/PUBLISHING.md`.
|
||||||
|
- **Admin field components resolve through a generated import map**
|
||||||
|
(`app/(payload)/admin/importMap.js`). Payload hands the client a *path* per
|
||||||
|
field and looks it up there; a missing entry renders no field and reports no
|
||||||
|
error, while `required` still blocks the save. After adding or changing any
|
||||||
|
field, editor or lexical feature, run `npm run generate:importmap` in
|
||||||
|
`nextjs-app/` and commit the result.
|
||||||
|
|
||||||
### Two route groups
|
### Two route groups
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* The admin panel does not import field components directly. Payload sends the
|
||||||
|
* client a *path* for each one — a richText field's is
|
||||||
|
* `@payloadcms/richtext-lexical/rsc#RscEntryLexicalField` — and resolves it
|
||||||
|
* through this generated map. An entry that is missing from the map is not an
|
||||||
|
* error the panel reports: the field simply does not render.
|
||||||
|
*
|
||||||
|
* That failure is quietly awful, because `required: true` is enforced on the
|
||||||
|
* server regardless. A writer gets a new-post form with no Content editor and
|
||||||
|
* a save that refuses on a field they were never shown.
|
||||||
|
*
|
||||||
|
* The map is generated by `npx payload generate:importmap`, so it drifts every
|
||||||
|
* time a field or a lexical feature is added and nobody re-runs it. These
|
||||||
|
* assert the entries the current config needs.
|
||||||
|
*/
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
const MAP = fs.readFileSync(
|
||||||
|
path.join(__dirname, '..', '..', 'app', '(payload)', 'admin', 'importMap.js'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
const POSTS = fs.readFileSync(
|
||||||
|
path.join(__dirname, '..', '..', 'collections', 'Posts.ts'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('admin import map', () => {
|
||||||
|
it('resolves the richText field, so Content renders in the editor', () => {
|
||||||
|
// Guarded because Posts.content is required: without this entry the field
|
||||||
|
// is invisible and the post is unsaveable.
|
||||||
|
expect(POSTS).toMatch(/type:\s*'richText'/);
|
||||||
|
expect(MAP).toContain('@payloadcms/richtext-lexical/rsc#RscEntryLexicalField');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolves the richText cell, so the list view can render the column', () => {
|
||||||
|
expect(MAP).toContain('@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolves the diff component, which the drafts UI needs', () => {
|
||||||
|
// versions.drafts is on, so the panel offers version comparison.
|
||||||
|
expect(POSTS).toMatch(/drafts:\s*true/);
|
||||||
|
expect(MAP).toContain('@payloadcms/richtext-lexical/rsc#LexicalDiffComponent');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolves BlocksFeature, so the Callout block is insertable', () => {
|
||||||
|
expect(POSTS).toContain('BlocksFeature');
|
||||||
|
expect(MAP).toContain('@payloadcms/richtext-lexical/client#BlocksFeatureClient');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resolves the default toolbar features the editor is built with', () => {
|
||||||
|
// defaultFeatures is spread into the editor config; each one contributes a
|
||||||
|
// client component the toolbar cannot render without.
|
||||||
|
for (const feature of [
|
||||||
|
'BoldFeatureClient',
|
||||||
|
'ItalicFeatureClient',
|
||||||
|
'HeadingFeatureClient',
|
||||||
|
'LinkFeatureClient',
|
||||||
|
'UploadFeatureClient',
|
||||||
|
'UnorderedListFeatureClient',
|
||||||
|
'OrderedListFeatureClient',
|
||||||
|
'InlineToolbarFeatureClient',
|
||||||
|
]) {
|
||||||
|
expect(MAP).toContain(`@payloadcms/richtext-lexical/client#${feature}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,6 +1,54 @@
|
|||||||
|
import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||||
|
import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||||
|
import { LexicalDiffComponent as LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc'
|
||||||
|
import { BlocksFeatureClient as BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
|
import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||||
import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc'
|
import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc'
|
||||||
|
|
||||||
/** @type import('payload').ImportMap */
|
/** @type import('payload').ImportMap */
|
||||||
export const importMap = {
|
export const importMap = {
|
||||||
|
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
|
"@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
|
"@payloadcms/richtext-lexical/rsc#LexicalDiffComponent": LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e,
|
||||||
|
"@payloadcms/richtext-lexical/client#BlocksFeatureClient": BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#StrikethroughFeatureClient": StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#SubscriptFeatureClient": SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#SuperscriptFeatureClient": SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#InlineCodeFeatureClient": InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#AlignFeatureClient": AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#IndentFeatureClient": IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#UnorderedListFeatureClient": UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#OrderedListFeatureClient": OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#ChecklistFeatureClient": ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#RelationshipFeatureClient": RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#BlockquoteFeatureClient": BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
|
"@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||||
"@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1
|
"@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
|
"generate:importmap": "payload generate:importmap",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "jest --watch",
|
||||||
"test:coverage": "jest --coverage"
|
"test:coverage": "jest --coverage"
|
||||||
|
|||||||
Reference in new issue
Block a user