@otl-core/cms-types 1.1.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,13 @@
1
+ Copyright (c) 2025 OTL Core
2
+
3
+ Licensed under the PolyForm Shield License, Version 1.0.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may
5
+ obtain a copy of the License at
6
+
7
+ https://polyformproject.org/licenses/shield/1.0.0/
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ License for the specific language governing permissions and limitations
13
+ under the License.
package/dist/index.cjs ADDED
@@ -0,0 +1,111 @@
1
+ 'use strict';
2
+
3
+ // src/collection.types.ts
4
+ var COLLECTION_TYPE_TEMPLATES = {
5
+ blog: {
6
+ entry_singular: "Post",
7
+ entry_plural: "Posts",
8
+ category_singular: "Category",
9
+ category_plural: "Categories",
10
+ author_singular: "Author",
11
+ author_plural: "Authors",
12
+ tag_singular: "Tag",
13
+ tag_plural: "Tags"
14
+ },
15
+ news: {
16
+ entry_singular: "Article",
17
+ entry_plural: "Articles",
18
+ category_singular: "Topic",
19
+ category_plural: "Topics",
20
+ author_singular: "Reporter",
21
+ author_plural: "Reporters",
22
+ tag_singular: "Tag",
23
+ tag_plural: "Tags"
24
+ },
25
+ knowledge_base: {
26
+ entry_singular: "Article",
27
+ entry_plural: "Articles",
28
+ category_singular: "Section",
29
+ category_plural: "Sections",
30
+ author_singular: "Contributor",
31
+ author_plural: "Contributors",
32
+ tag_singular: "Tag",
33
+ tag_plural: "Tags"
34
+ },
35
+ changelog: {
36
+ entry_singular: "Release",
37
+ entry_plural: "Releases",
38
+ category_singular: "Product",
39
+ category_plural: "Products",
40
+ author_singular: "Contributor",
41
+ author_plural: "Contributors",
42
+ tag_singular: "Tag",
43
+ tag_plural: "Tags"
44
+ },
45
+ case_studies: {
46
+ entry_singular: "Case Study",
47
+ entry_plural: "Case Studies",
48
+ category_singular: "Industry",
49
+ category_plural: "Industries",
50
+ author_singular: "Author",
51
+ author_plural: "Authors",
52
+ tag_singular: "Tag",
53
+ tag_plural: "Tags"
54
+ },
55
+ custom: {
56
+ entry_singular: "Entry",
57
+ entry_plural: "Entries",
58
+ category_singular: "Category",
59
+ category_plural: "Categories",
60
+ author_singular: "Author",
61
+ author_plural: "Authors",
62
+ tag_singular: "Tag",
63
+ tag_plural: "Tags"
64
+ }
65
+ };
66
+
67
+ // src/schema.types.ts
68
+ var RESERVED_SECTION_TYPES = [
69
+ "hero-banner",
70
+ "content-blocks",
71
+ "feature-grid",
72
+ "testimonial-carousel",
73
+ "cta-banner",
74
+ "team-grid",
75
+ "faq-accordion",
76
+ "stats-showcase",
77
+ "logo-cloud"
78
+ ];
79
+ var RESERVED_BLOCK_TYPES = [
80
+ "markdown",
81
+ "html",
82
+ "image",
83
+ "quote",
84
+ "gallery",
85
+ "embed",
86
+ "cta",
87
+ "divider",
88
+ "code",
89
+ "about-the-authors",
90
+ "more-from-the-authors",
91
+ "recommended-posts",
92
+ "related-posts"
93
+ ];
94
+ function isReservedSchemaType(type) {
95
+ return RESERVED_SECTION_TYPES.includes(type) || RESERVED_BLOCK_TYPES.includes(type);
96
+ }
97
+ function isReservedSectionType(type) {
98
+ return RESERVED_SECTION_TYPES.includes(type);
99
+ }
100
+ function isReservedBlockType(type) {
101
+ return RESERVED_BLOCK_TYPES.includes(type);
102
+ }
103
+
104
+ exports.COLLECTION_TYPE_TEMPLATES = COLLECTION_TYPE_TEMPLATES;
105
+ exports.RESERVED_BLOCK_TYPES = RESERVED_BLOCK_TYPES;
106
+ exports.RESERVED_SECTION_TYPES = RESERVED_SECTION_TYPES;
107
+ exports.isReservedBlockType = isReservedBlockType;
108
+ exports.isReservedSchemaType = isReservedSchemaType;
109
+ exports.isReservedSectionType = isReservedSectionType;
110
+ //# sourceMappingURL=index.cjs.map
111
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/collection.types.ts","../src/schema.types.ts"],"names":[],"mappings":";;;AA4HO,IAAM,yBAAA,GAGT;AAAA,EACF,IAAA,EAAM;AAAA,IACJ,cAAA,EAAgB,MAAA;AAAA,IAChB,YAAA,EAAc,OAAA;AAAA,IACd,iBAAA,EAAmB,UAAA;AAAA,IACnB,eAAA,EAAiB,YAAA;AAAA,IACjB,eAAA,EAAiB,QAAA;AAAA,IACjB,aAAA,EAAe,SAAA;AAAA,IACf,YAAA,EAAc,KAAA;AAAA,IACd,UAAA,EAAY;AAAA,GACd;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,cAAA,EAAgB,SAAA;AAAA,IAChB,YAAA,EAAc,UAAA;AAAA,IACd,iBAAA,EAAmB,OAAA;AAAA,IACnB,eAAA,EAAiB,QAAA;AAAA,IACjB,eAAA,EAAiB,UAAA;AAAA,IACjB,aAAA,EAAe,WAAA;AAAA,IACf,YAAA,EAAc,KAAA;AAAA,IACd,UAAA,EAAY;AAAA,GACd;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,cAAA,EAAgB,SAAA;AAAA,IAChB,YAAA,EAAc,UAAA;AAAA,IACd,iBAAA,EAAmB,SAAA;AAAA,IACnB,eAAA,EAAiB,UAAA;AAAA,IACjB,eAAA,EAAiB,aAAA;AAAA,IACjB,aAAA,EAAe,cAAA;AAAA,IACf,YAAA,EAAc,KAAA;AAAA,IACd,UAAA,EAAY;AAAA,GACd;AAAA,EACA,SAAA,EAAW;AAAA,IACT,cAAA,EAAgB,SAAA;AAAA,IAChB,YAAA,EAAc,UAAA;AAAA,IACd,iBAAA,EAAmB,SAAA;AAAA,IACnB,eAAA,EAAiB,UAAA;AAAA,IACjB,eAAA,EAAiB,aAAA;AAAA,IACjB,aAAA,EAAe,cAAA;AAAA,IACf,YAAA,EAAc,KAAA;AAAA,IACd,UAAA,EAAY;AAAA,GACd;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,cAAA,EAAgB,YAAA;AAAA,IAChB,YAAA,EAAc,cAAA;AAAA,IACd,iBAAA,EAAmB,UAAA;AAAA,IACnB,eAAA,EAAiB,YAAA;AAAA,IACjB,eAAA,EAAiB,QAAA;AAAA,IACjB,aAAA,EAAe,SAAA;AAAA,IACf,YAAA,EAAc,KAAA;AAAA,IACd,UAAA,EAAY;AAAA,GACd;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,cAAA,EAAgB,OAAA;AAAA,IAChB,YAAA,EAAc,SAAA;AAAA,IACd,iBAAA,EAAmB,UAAA;AAAA,IACnB,eAAA,EAAiB,YAAA;AAAA,IACjB,eAAA,EAAiB,QAAA;AAAA,IACjB,aAAA,EAAe,SAAA;AAAA,IACf,YAAA,EAAc,KAAA;AAAA,IACd,UAAA,EAAY;AAAA;AAEhB;;;ACzJO,IAAM,sBAAA,GAAyB;AAAA,EACpC,aAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,sBAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF;AAEO,IAAM,oBAAA,GAAuB;AAAA,EAClC,UAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,mBAAA;AAAA,EACA,uBAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF;AAMO,SAAS,qBAAqB,IAAA,EAA0C;AAC7E,EAAA,OACG,uBAA6C,QAAA,CAAS,IAAI,CAAA,IAC1D,oBAAA,CAA2C,SAAS,IAAI,CAAA;AAE7D;AAEO,SAAS,sBACd,IAAA,EAC6B;AAC7B,EAAA,OAAQ,sBAAA,CAA6C,SAAS,IAAI,CAAA;AACpE;AAEO,SAAS,oBAAoB,IAAA,EAAyC;AAC3E,EAAA,OAAQ,oBAAA,CAA2C,SAAS,IAAI,CAAA;AAClE","file":"index.cjs","sourcesContent":["/**\n * Collection types (public/engine-facing)\n */\n\nimport type { BlockInstance } from \"./blocks\";\nimport type { SEOConfig } from \"./pages.types\";\nimport type { SchemaInstance } from \"./schema.types\";\nimport type { SectionInstance } from \"./sections/section-config.types\";\nimport type { InputField } from \"./sections/input-fields.types\";\n\n/**\n * A vocabulary term can be a plain string or a locale-keyed map for i18n.\n */\nexport type VocabularyTerm = string | Record<string, string>;\n\n/**\n * Feature flags for a collection (which sub-entities are enabled)\n */\nexport interface CollectionFeatures {\n authors: boolean;\n tags: boolean;\n categories: boolean;\n}\n\n/**\n * Social media link for a collection author\n */\nexport interface SocialLink {\n platform: string;\n url: string;\n}\n\n/**\n * Collection author entity\n */\nexport interface Author {\n id: string;\n collection_id: string;\n name: string;\n slug: string;\n bio?: Record<string, string>;\n excerpt?: Record<string, string>;\n avatar_url?: string;\n social_links?: SocialLink[];\n email?: string;\n website?: string;\n url?: string;\n custom_fields?: Record<string, unknown>;\n created_at: string;\n updated_at: string;\n}\n\n/**\n * Collection entry configuration\n */\nexport interface CollectionEntriesConfig {\n custom_fields_schema?: InputField[];\n allowed_block_types?: string;\n default_entry_blocks?: BlockInstance[];\n strict_block_structure?: boolean;\n}\n\n/**\n * Collection locale configuration\n */\nexport interface CollectionLocaleConfig {\n locale: string;\n title: string;\n base_path: string;\n}\n\n/**\n * Collection layouts for different page types\n */\nexport interface CollectionLayouts {\n entry: SectionInstance[];\n index: SectionInstance[];\n category: SectionInstance[];\n category_index: SectionInstance[];\n author: SectionInstance[];\n tag: SectionInstance[];\n author_index: SectionInstance[];\n tag_index: SectionInstance[];\n}\n\n/**\n * Collection layouts per locale with inheritance support\n */\nexport interface CollectionLocaleLayouts {\n locale: string;\n layouts: CollectionLayouts;\n inherits_from?: string;\n inherited_by?: string[];\n}\n\n/**\n * Collection type determines the template used to seed vocabulary\n */\nexport type CollectionType =\n | \"blog\"\n | \"news\"\n | \"knowledge_base\"\n | \"changelog\"\n | \"case_studies\"\n | \"custom\";\n\n/**\n * Customizable vocabulary labels for collection UI\n */\nexport interface CollectionVocabulary {\n entry_singular: VocabularyTerm;\n entry_plural: VocabularyTerm;\n category_singular: VocabularyTerm;\n category_plural: VocabularyTerm;\n author_singular: VocabularyTerm;\n author_plural: VocabularyTerm;\n tag_singular: VocabularyTerm;\n tag_plural: VocabularyTerm;\n}\n\n/**\n * Default vocabulary templates seeded by the backend for each collection type.\n * Kept in sync with backend/cms-main/internal/models/collection.go CollectionTypeTemplates.\n */\nexport const COLLECTION_TYPE_TEMPLATES: Record<\n CollectionType,\n CollectionVocabulary\n> = {\n blog: {\n entry_singular: \"Post\",\n entry_plural: \"Posts\",\n category_singular: \"Category\",\n category_plural: \"Categories\",\n author_singular: \"Author\",\n author_plural: \"Authors\",\n tag_singular: \"Tag\",\n tag_plural: \"Tags\",\n },\n news: {\n entry_singular: \"Article\",\n entry_plural: \"Articles\",\n category_singular: \"Topic\",\n category_plural: \"Topics\",\n author_singular: \"Reporter\",\n author_plural: \"Reporters\",\n tag_singular: \"Tag\",\n tag_plural: \"Tags\",\n },\n knowledge_base: {\n entry_singular: \"Article\",\n entry_plural: \"Articles\",\n category_singular: \"Section\",\n category_plural: \"Sections\",\n author_singular: \"Contributor\",\n author_plural: \"Contributors\",\n tag_singular: \"Tag\",\n tag_plural: \"Tags\",\n },\n changelog: {\n entry_singular: \"Release\",\n entry_plural: \"Releases\",\n category_singular: \"Product\",\n category_plural: \"Products\",\n author_singular: \"Contributor\",\n author_plural: \"Contributors\",\n tag_singular: \"Tag\",\n tag_plural: \"Tags\",\n },\n case_studies: {\n entry_singular: \"Case Study\",\n entry_plural: \"Case Studies\",\n category_singular: \"Industry\",\n category_plural: \"Industries\",\n author_singular: \"Author\",\n author_plural: \"Authors\",\n tag_singular: \"Tag\",\n tag_plural: \"Tags\",\n },\n custom: {\n entry_singular: \"Entry\",\n entry_plural: \"Entries\",\n category_singular: \"Category\",\n category_plural: \"Categories\",\n author_singular: \"Author\",\n author_plural: \"Authors\",\n tag_singular: \"Tag\",\n tag_plural: \"Tags\",\n },\n};\n\n/**\n * Collection entity\n */\nexport interface Collection {\n id: string;\n site_id: string;\n collection_type: CollectionType;\n name: string;\n vocabulary: CollectionVocabulary;\n features: CollectionFeatures;\n locales: CollectionLocaleConfig[];\n description?: string;\n entries_config: CollectionEntriesConfig;\n author_custom_fields_schema?: InputField[];\n category_custom_fields_schema?: InputField[];\n tag_custom_fields_schema?: InputField[];\n locale_layouts: CollectionLocaleLayouts[];\n status: \"active\" | \"inactive\";\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\n/**\n * Collection category with multi-locale support\n */\nexport interface Category {\n id: string;\n collection_id: string;\n parent_id?: string;\n title: string;\n name: Record<string, string>;\n slug: Record<string, string>;\n description?: Record<string, string>;\n sort_order: number;\n depth: number;\n full_path: Record<string, string>;\n seo?: Record<string, SEOConfig>;\n custom_fields?: Record<string, unknown>;\n is_visible: boolean;\n children?: Category[];\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\n/**\n * Collection tag entity with multi-locale support\n */\nexport interface Tag {\n id: string;\n collection_id: string;\n title: string;\n name: Record<string, string>;\n slug: Record<string, string>;\n description?: Record<string, string>;\n sort_order: number;\n is_visible: boolean;\n seo?: Record<string, SEOConfig>;\n custom_fields?: Record<string, unknown>;\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\n/**\n * Collection category slug entry (normalized for path resolution)\n */\nexport interface CategorySlug {\n id: string;\n site_id: string;\n collection_id: string;\n category_id: string;\n locale: string;\n slug: string;\n full_path: string;\n created_at: string;\n updated_at: string;\n}\n\n/**\n * Collection category tree node (for hierarchical display)\n */\nexport interface CategoryTreeNode extends Category {\n children: CategoryTreeNode[];\n}\n\n/**\n * Collection entry variant info\n */\nexport interface EntryVariant {\n id: string;\n label: string;\n draft_id?: string;\n live_id?: string;\n}\n\n/**\n * Collection entry locale-specific content configuration\n */\nexport interface EntryLocaleContent {\n locale: string;\n slug: string;\n enabled: boolean;\n inherits_from?: string;\n inherited_by?: string[];\n seo?: SEOConfig;\n variants: EntryVariant[];\n active_version: string;\n publish_at?: string;\n expires_at?: string;\n password_protection?: import(\"./pages.types\").PasswordProtection;\n header_preset_id?: string;\n footer_preset_id?: string;\n}\n\n/**\n * Collection entry with full content\n */\nexport interface Entry {\n // Metadata\n id: string;\n collection_id: string;\n category_id?: string;\n tags: string[];\n tag_ids: string[];\n author_ids: string[];\n is_featured: boolean;\n featured_priority: number;\n locale_content: EntryLocaleContent[];\n\n // Content (for the current locale/variant/version)\n title: string;\n slug: string;\n blocks?: SchemaInstance[];\n content: string;\n excerpt?: string;\n featured_image?: MediaReference;\n seo?: SEOConfig;\n custom_fields?: Record<string, unknown>;\n custom_field_values?: Record<string, unknown>;\n\n // Publishing\n status: \"draft\" | \"published\" | \"scheduled\" | \"expired\";\n published_at?: string;\n scheduled_at?: string;\n expires_at?: string;\n\n // Stats\n reading_time_minutes: number;\n\n // Context\n current_locale: string;\n current_variant: string;\n current_version_type: \"draft\" | \"live\";\n\n // Audit\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\n/**\n * Media reference for images/videos\n */\nexport interface MediaReference {\n src: string;\n alt: string;\n width?: number;\n height?: number;\n}\n\n/**\n * Media asset\n */\nexport interface Media {\n id: string;\n site_id: string;\n filename: string;\n original_name: string;\n mime_type: string;\n size: number;\n url: string;\n alt?: string;\n dimensions?: MediaDimensions;\n metadata?: Record<string, unknown>;\n created_at: string;\n updated_at: string;\n}\n\n/**\n * Media dimensions\n */\nexport interface MediaDimensions {\n width: number;\n height: number;\n}\n","// ============================================================================\n// UNIFIED SCHEMA SYSTEM - Public types for engine rendering\n// ============================================================================\n\n/**\n * Block target - what pages/contexts can a block be added to\n */\nexport type BlockTarget =\n | \"collection.entry\"\n | \"collection.index\"\n | \"collection.category\"\n | \"collection.category_index\"\n | \"collection.author\"\n | \"collection.author_index\"\n | \"collection.tag\"\n | \"collection.tag_index\"\n | \"collection.search\"\n | \"page\"\n | \"form\"\n | \"footer\"\n | \"*\";\n\n/**\n * Schema instance in a page (section) or collection entry (block)\n */\nexport interface SchemaInstance {\n id: string;\n type: string;\n config: Record<string, unknown>;\n}\n\n// ============================================================================\n// RESERVED/BUILT-IN SCHEMA TYPES\n// ============================================================================\n\nexport const RESERVED_SECTION_TYPES = [\n \"hero-banner\",\n \"content-blocks\",\n \"feature-grid\",\n \"testimonial-carousel\",\n \"cta-banner\",\n \"team-grid\",\n \"faq-accordion\",\n \"stats-showcase\",\n \"logo-cloud\",\n] as const;\n\nexport const RESERVED_BLOCK_TYPES = [\n \"markdown\",\n \"html\",\n \"image\",\n \"quote\",\n \"gallery\",\n \"embed\",\n \"cta\",\n \"divider\",\n \"code\",\n \"about-the-authors\",\n \"more-from-the-authors\",\n \"recommended-posts\",\n \"related-posts\",\n] as const;\n\nexport type ReservedSectionType = (typeof RESERVED_SECTION_TYPES)[number];\nexport type ReservedBlockType = (typeof RESERVED_BLOCK_TYPES)[number];\nexport type ReservedSchemaType = ReservedSectionType | ReservedBlockType;\n\nexport function isReservedSchemaType(type: string): type is ReservedSchemaType {\n return (\n (RESERVED_SECTION_TYPES as readonly string[]).includes(type) ||\n (RESERVED_BLOCK_TYPES as readonly string[]).includes(type)\n );\n}\n\nexport function isReservedSectionType(\n type: string,\n): type is ReservedSectionType {\n return (RESERVED_SECTION_TYPES as readonly string[]).includes(type);\n}\n\nexport function isReservedBlockType(type: string): type is ReservedBlockType {\n return (RESERVED_BLOCK_TYPES as readonly string[]).includes(type);\n}\n"]}