@sittari/payload-templates 0.2.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sittari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # @sittari/payload-templates
2
+
3
+ A Payload CMS plugin that creates one managed document for every developer-defined template. Users can edit template content, but cannot create, duplicate, delete, or change the identity of template documents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @sittari/payload-templates
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { templatesPlugin } from '@sittari/payload-templates'
15
+ import { buildConfig } from 'payload'
16
+
17
+ export default buildConfig({
18
+ collections: [],
19
+ plugins: [
20
+ templatesPlugin({
21
+ templates: [
22
+ {
23
+ name: '404',
24
+ label: 'Page 404',
25
+ fields: [
26
+ { name: 'heading', type: 'text', required: true },
27
+ { name: 'message', type: 'textarea' },
28
+ ],
29
+ initialData: {
30
+ heading: 'Page not found',
31
+ },
32
+ },
33
+ ],
34
+ }),
35
+ ],
36
+ })
37
+ ```
38
+
39
+ The generated document stores editable fields under `data_<name>`—for example, `data_404.heading`. The `title` and `templateType` fields are managed by the plugin and hidden from the admin form.
40
+
41
+ ## Configuration
42
+
43
+ | Option | Type | Default | Description |
44
+ | --- | --- | --- | --- |
45
+ | `templates` | `TemplateConfig[]` | Required | Complete set of managed template definitions. |
46
+ | `enabled` | `boolean` | `true` | Set to `false` to leave the Payload config unchanged. |
47
+
48
+ Each template has:
49
+
50
+ - `name`: stable unique identifier containing only letters, numbers, and underscores.
51
+ - `label`: admin document title.
52
+ - `fields`: Payload fields shown for this template.
53
+ - `initialData`: optional values applied only when the document is first created. Payload field defaults still apply.
54
+
55
+ ## Lifecycle and access
56
+
57
+ On Payload initialization, the plugin creates missing documents, updates labels, and deletes documents removed from configuration. Existing editable data is preserved. Renaming a template is treated as removing the old template and creating a new one.
58
+
59
+ Collection access prevents normal admin, REST, GraphQL, and access-controlled Local API users from creating or deleting template documents. The identity fields also deny user changes. As with every Payload collection, trusted Local API calls using the default `overrideAccess: true` bypass access control.
60
+
61
+ The package exports `TemplateConfig` and `TemplatesPluginConfig` from both the package root and `@sittari/payload-templates/types`.
62
+
63
+ ## Fetching a typed template
64
+
65
+ Create a lookup helper with the generated `Template` type from your project:
66
+
67
+ ```ts
68
+ import config from '@payload-config'
69
+ import { createTemplateGetter } from '@sittari/payload-templates'
70
+ import { getPayload } from 'payload'
71
+
72
+ import type { Template } from './payload-types'
73
+
74
+ export const getTemplate = createTemplateGetter<Template>(() => getPayload({ config }))
75
+
76
+ const notFound = await getTemplate('404')
77
+ // Typed as: { id: string | number; data_404?: Template['data_404'] } | null
78
+ ```
79
+
80
+ Valid template names are inferred from the generated type's `data_*` properties. Each lookup filters by `templateType` and selects only the matching `data_<name>` group (plus Payload's always-selected document ID). It returns `null` when no configured document is found.
@@ -0,0 +1,3 @@
1
+ export type { GetPayload, TemplateDocumentFor, TemplateName } from '../getTemplate.js';
2
+ export type { TemplateConfig, TemplatesPluginConfig } from '../types.js';
3
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACtF,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import type { Payload } from 'payload';
2
+ export type GetPayload = () => Payload | Promise<Payload>;
3
+ export type TemplateName<TDocument> = {
4
+ [TKey in Extract<keyof TDocument, string>]: TKey extends `data_${infer TName}` ? TName : never;
5
+ }[Extract<keyof TDocument, string>];
6
+ export type TemplateDocumentFor<TDocument extends {
7
+ id: number | string;
8
+ }, TName extends TemplateName<TDocument>> = Pick<TDocument, 'id' | Extract<keyof TDocument, `data_${TName}`>>;
9
+ /**
10
+ * Creates a typed template lookup backed by the provided Payload getter.
11
+ *
12
+ * The generated template document type is used to derive valid template names
13
+ * and the selected `data_<name>` group returned for each lookup.
14
+ */
15
+ export declare const createTemplateGetter: <TDocument extends {
16
+ id: number | string;
17
+ }>(getPayload: GetPayload) => <TName extends TemplateName<TDocument>>(templateName: TName) => Promise<TemplateDocumentFor<TDocument, TName> | null>;
18
+ //# sourceMappingURL=getTemplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTemplate.d.ts","sourceRoot":"","sources":["../src/getTemplate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;AAEzD,MAAM,MAAM,YAAY,CAAC,SAAS,IAAI;KACnC,IAAI,IAAI,OAAO,CAAC,MAAM,SAAS,EAAE,MAAM,CAAC,GAAG,IAAI,SAAS,QAAQ,MAAM,KAAK,EAAE,GAC5E,KAAK,GACL,KAAK;CACR,CAAC,OAAO,CAAC,MAAM,SAAS,EAAE,MAAM,CAAC,CAAC,CAAA;AAEnC,MAAM,MAAM,mBAAmB,CAC7B,SAAS,SAAS;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EACzC,KAAK,SAAS,YAAY,CAAC,SAAS,CAAC,IACnC,IAAI,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,SAAS,EAAE,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAA;AAErE;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAC9B,SAAS,SAAS;IAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EAAE,YAAY,UAAU,MACzD,KAAK,SAAS,YAAY,CAAC,SAAS,CAAC,EAC1C,cAAc,KAAK,KAClB,OAAO,CAAC,mBAAmB,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,IAAI,CAuBtD,CAAA"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Creates a typed template lookup backed by the provided Payload getter.
3
+ *
4
+ * The generated template document type is used to derive valid template names
5
+ * and the selected `data_<name>` group returned for each lookup.
6
+ */
7
+ export const createTemplateGetter = (getPayload) => async (templateName) => {
8
+ const payload = await getPayload();
9
+ const groupField = `data_${templateName}`;
10
+ const result = await payload.find({
11
+ collection: 'templates',
12
+ depth: 0,
13
+ limit: 1,
14
+ pagination: false,
15
+ select: {
16
+ [groupField]: true,
17
+ },
18
+ where: {
19
+ templateType: {
20
+ equals: templateName,
21
+ },
22
+ },
23
+ });
24
+ const doc = result.docs[0];
25
+ if (!doc) {
26
+ return null;
27
+ }
28
+ return doc;
29
+ };
30
+ //# sourceMappingURL=getTemplate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getTemplate.js","sourceRoot":"","sources":["../src/getTemplate.ts"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAC/B,CAA4C,UAAsB,EAAE,EAAE,CACpE,KAAK,EACH,YAAmB,EACoC,EAAE;IACzD,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,QAAQ,YAAY,EAAE,CAAA;IACzC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;QAChC,UAAU,EAAE,WAAoB;QAChC,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,CAAC;QACR,UAAU,EAAE,KAAK;QACjB,MAAM,EAAE;YACN,CAAC,UAAU,CAAC,EAAE,IAAI;SACnB;QACD,KAAK,EAAE;YACL,YAAY,EAAE;gBACZ,MAAM,EAAE,YAAY;aACrB;SACF;KACF,CAAC,CAAA;IAEF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAsD,CAAA;IAC/E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAA"}
@@ -0,0 +1,6 @@
1
+ export { createTemplateGetter } from './getTemplate.js';
2
+ export { templatesPlugin } from './plugin.js';
3
+ export type { GetPayload, TemplateDocumentFor, TemplateName, } from './getTemplate.js';
4
+ export type { TemplateConfig, TemplatesPluginConfig } from './types.js';
5
+ export { templatesPlugin as default } from './plugin.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7C,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,YAAY,GACb,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEvE,OAAO,EAAE,eAAe,IAAI,OAAO,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { createTemplateGetter } from './getTemplate.js';
2
+ export { templatesPlugin } from './plugin.js';
3
+ export { templatesPlugin as default } from './plugin.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAQ7C,OAAO,EAAE,eAAe,IAAI,OAAO,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from 'payload';
2
+ import type { TemplatesPluginConfig } from './types.js';
3
+ export declare const templatesPlugin: (pluginConfig: TemplatesPluginConfig) => Plugin;
4
+ export default templatesPlugin;
5
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmC,MAAM,EAAE,MAAM,SAAS,CAAA;AAEtE,OAAO,KAAK,EAAkB,qBAAqB,EAAE,MAAM,YAAY,CAAA;AA2KvE,eAAO,MAAM,eAAe,GACzB,cAAc,qBAAqB,KAAG,MAsBtC,CAAA;AAEH,eAAe,eAAe,CAAA"}
package/dist/plugin.js ADDED
@@ -0,0 +1,149 @@
1
+ const COLLECTION_SLUG = 'templates';
2
+ const DATA_FIELD_PREFIX = 'data_';
3
+ const VALID_TEMPLATE_NAME = /^[A-Za-z0-9_]+$/;
4
+ const dataFieldName = (name) => `${DATA_FIELD_PREFIX}${name}`;
5
+ const extendOnInit = (incomingConfig, onInit) => async (payload) => {
6
+ if (incomingConfig.onInit) {
7
+ await incomingConfig.onInit(payload);
8
+ }
9
+ await onInit(payload);
10
+ };
11
+ const validateTemplates = (templates) => {
12
+ const names = new Set();
13
+ const generatedFieldNames = new Set(['title', 'templateType']);
14
+ for (const template of templates) {
15
+ if (!template.name || !VALID_TEMPLATE_NAME.test(template.name)) {
16
+ throw new Error(`[templatesPlugin] Invalid template name "${template.name}". Use only letters, numbers, and underscores.`);
17
+ }
18
+ if (names.has(template.name)) {
19
+ throw new Error(`[templatesPlugin] Template names must be unique. Duplicate: "${template.name}".`);
20
+ }
21
+ const fieldName = dataFieldName(template.name);
22
+ if (generatedFieldNames.has(fieldName)) {
23
+ throw new Error(`[templatesPlugin] Template "${template.name}" conflicts with generated field "${fieldName}".`);
24
+ }
25
+ names.add(template.name);
26
+ generatedFieldNames.add(fieldName);
27
+ }
28
+ };
29
+ const createTemplateFields = (templates) => [
30
+ {
31
+ name: 'title',
32
+ type: 'text',
33
+ required: true,
34
+ access: {
35
+ create: () => false,
36
+ update: () => false,
37
+ },
38
+ admin: {
39
+ hidden: true,
40
+ readOnly: true,
41
+ },
42
+ },
43
+ {
44
+ name: 'templateType',
45
+ type: 'text',
46
+ required: true,
47
+ unique: true,
48
+ access: {
49
+ create: () => false,
50
+ update: () => false,
51
+ },
52
+ admin: {
53
+ hidden: true,
54
+ readOnly: true,
55
+ },
56
+ },
57
+ ...templates.map((template) => ({
58
+ name: dataFieldName(template.name),
59
+ type: 'group',
60
+ label: false,
61
+ fields: template.fields,
62
+ admin: {
63
+ condition: (_, siblingData) => siblingData?.templateType === template.name,
64
+ hideGutter: true,
65
+ },
66
+ })),
67
+ ];
68
+ const createTemplatesCollection = (templates) => ({
69
+ slug: COLLECTION_SLUG,
70
+ access: {
71
+ create: () => false,
72
+ delete: () => false,
73
+ },
74
+ disableDuplicate: true,
75
+ admin: {
76
+ defaultColumns: ['title', 'updatedAt'],
77
+ useAsTitle: 'title',
78
+ },
79
+ labels: {
80
+ singular: 'Template',
81
+ plural: 'Templates',
82
+ },
83
+ fields: createTemplateFields(templates),
84
+ });
85
+ const reconcileTemplates = async (payload, templates) => {
86
+ const result = await payload.find({
87
+ collection: COLLECTION_SLUG,
88
+ depth: 0,
89
+ limit: 0,
90
+ overrideAccess: true,
91
+ pagination: false,
92
+ });
93
+ const documents = result.docs;
94
+ const documentsByType = new Map(documents
95
+ .filter((document) => typeof document.templateType === 'string')
96
+ .map((document) => [document.templateType, document]));
97
+ const configuredNames = new Set(templates.map(({ name }) => name));
98
+ for (const template of templates) {
99
+ const existing = documentsByType.get(template.name);
100
+ if (!existing) {
101
+ await payload.create({
102
+ collection: COLLECTION_SLUG,
103
+ data: {
104
+ [dataFieldName(template.name)]: template.initialData ?? {},
105
+ templateType: template.name,
106
+ title: template.label,
107
+ },
108
+ overrideAccess: true,
109
+ });
110
+ continue;
111
+ }
112
+ if (existing.title !== template.label) {
113
+ await payload.update({
114
+ collection: COLLECTION_SLUG,
115
+ id: existing.id,
116
+ data: { title: template.label },
117
+ overrideAccess: true,
118
+ });
119
+ }
120
+ }
121
+ for (const document of documents) {
122
+ if (typeof document.templateType !== 'string' || !configuredNames.has(document.templateType)) {
123
+ await payload.delete({
124
+ collection: COLLECTION_SLUG,
125
+ id: document.id,
126
+ overrideAccess: true,
127
+ });
128
+ }
129
+ }
130
+ };
131
+ export const templatesPlugin = (pluginConfig) => (incomingConfig) => {
132
+ if (pluginConfig.enabled === false) {
133
+ return incomingConfig;
134
+ }
135
+ validateTemplates(pluginConfig.templates);
136
+ if (incomingConfig.collections?.some(({ slug }) => slug === COLLECTION_SLUG)) {
137
+ throw new Error(`[templatesPlugin] A collection with slug "${COLLECTION_SLUG}" already exists.`);
138
+ }
139
+ return {
140
+ ...incomingConfig,
141
+ collections: [
142
+ ...(incomingConfig.collections ?? []),
143
+ createTemplatesCollection(pluginConfig.templates),
144
+ ],
145
+ onInit: extendOnInit(incomingConfig, (payload) => reconcileTemplates(payload, pluginConfig.templates)),
146
+ };
147
+ };
148
+ export default templatesPlugin;
149
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Field } from 'payload';
2
+ export type TemplateConfig = {
3
+ /** Fields editable on this template's managed document. */
4
+ fields: Field[];
5
+ /** Data applied only when the managed document is first created. */
6
+ initialData?: Record<string, unknown>;
7
+ /** Human-readable document title. */
8
+ label: string;
9
+ /** Stable, unique template identifier. Letters, numbers, and underscores only. */
10
+ name: string;
11
+ };
12
+ export type TemplatesPluginConfig = {
13
+ /** Enable or disable the plugin. */
14
+ enabled?: boolean;
15
+ /** The complete set of template documents managed by the plugin. */
16
+ templates: TemplateConfig[];
17
+ };
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC,MAAM,MAAM,cAAc,GAAG;IAC3B,2DAA2D;IAC3D,MAAM,EAAE,KAAK,EAAE,CAAA;IACf,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACrC,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,oEAAoE;IACpE,SAAS,EAAE,cAAc,EAAE,CAAA;CAC5B,CAAA"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@sittari/payload-templates",
3
+ "version": "0.2.0",
4
+ "description": "Managed template documents for Payload CMS.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./types": {
16
+ "types": "./dist/exports/types.d.ts",
17
+ "import": "./dist/exports/types.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md"
23
+ ],
24
+ "sideEffects": false,
25
+ "peerDependencies": {
26
+ "payload": "^3.0.0"
27
+ },
28
+ "devDependencies": {
29
+ "@payloadcms/db-sqlite": "3.85.2",
30
+ "payload": "^3.0.0",
31
+ "typescript": "5.9.3",
32
+ "vitest": "4.1.9"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "keywords": [
38
+ "payload",
39
+ "payloadcms",
40
+ "payload-plugin",
41
+ "cms",
42
+ "templates"
43
+ ],
44
+ "scripts": {
45
+ "build": "pnpm run clean && pnpm run build:types && pnpm run build:js",
46
+ "build:js": "tsc -p tsconfig.build.json --declaration false --declarationMap false",
47
+ "build:types": "tsc -p tsconfig.build.json --emitDeclarationOnly",
48
+ "typecheck": "tsc --noEmit",
49
+ "test": "pnpm run test:int",
50
+ "test:int": "vitest run",
51
+ "dev": "node ../../scripts/dev-package.mjs",
52
+ "clean": "rm -rf dist *.tsbuildinfo"
53
+ }
54
+ }