diff --git a/plugins/page-builder/src/links/post-author-user.ts b/plugins/page-builder/src/links/post-author-user.ts new file mode 100644 index 00000000..87cbaf27 --- /dev/null +++ b/plugins/page-builder/src/links/post-author-user.ts @@ -0,0 +1,14 @@ +import { defineLink } from '@medusajs/framework/utils' +import UserModule from '@medusajs/medusa/user' +import PageBuilderModule from '../modules/page-builder' + +export default defineLink( + { + ...PageBuilderModule.linkable.postAuthor.id, + field: 'medusa_user_id', + }, + UserModule.linkable.user, + { + readOnly: true, + }, +) diff --git a/plugins/page-builder/src/links/post-tag-user.ts b/plugins/page-builder/src/links/post-tag-user.ts new file mode 100644 index 00000000..86a515b3 --- /dev/null +++ b/plugins/page-builder/src/links/post-tag-user.ts @@ -0,0 +1,14 @@ +import { defineLink } from '@medusajs/framework/utils' +import UserModule from '@medusajs/medusa/user' +import PageBuilderModule from '../modules/page-builder' + +export default defineLink( + { + ...PageBuilderModule.linkable.postTag.id, + field: 'created_by_id', + }, + UserModule.linkable.user, + { + readOnly: true, + }, +) diff --git a/plugins/page-builder/src/modules/page-builder/index.ts b/plugins/page-builder/src/modules/page-builder/index.ts new file mode 100644 index 00000000..15a80ff4 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/index.ts @@ -0,0 +1,8 @@ +import PageBuilderService from './service' +import { Module } from '@medusajs/framework/utils' + +export const PAGE_BUILDER_MODULE = 'page-builder' + +export default Module(PAGE_BUILDER_MODULE, { + service: PageBuilderService, +}) diff --git a/plugins/page-builder/src/modules/page-builder/migrations/.snapshot-medusa-page-builder.json b/plugins/page-builder/src/modules/page-builder/migrations/.snapshot-medusa-page-builder.json new file mode 100644 index 00000000..7954db7b --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/migrations/.snapshot-medusa-page-builder.json @@ -0,0 +1,1488 @@ +{ + "namespaces": [ + "public" + ], + "name": "public", + "tables": [ + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "label": { + "name": "label", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "location": { + "name": "location", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "enumItems": [ + "header", + "footer" + ], + "mappedType": "enum" + }, + "url": { + "name": "url", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "new_tab": { + "name": "new_tab", + "type": "boolean", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "false", + "mappedType": "boolean" + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "mappedType": "integer" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "navigation_item", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_navigation_item_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_navigation_item_deleted_at\" ON \"navigation_item\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "navigation_item_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": {}, + "nativeEnums": {} + }, + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "type": { + "name": "type", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "enumItems": [ + "page", + "post" + ], + "mappedType": "enum" + }, + "title": { + "name": "title", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "handle": { + "name": "handle", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "excerpt": { + "name": "excerpt", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "content": { + "name": "content", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "status": { + "name": "status", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "'draft'", + "enumItems": [ + "draft", + "published", + "archived" + ], + "mappedType": "enum" + }, + "content_mode": { + "name": "content_mode", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "enumItems": [ + "basic", + "advanced" + ], + "mappedType": "enum" + }, + "seo": { + "name": "seo", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "published_at": { + "name": "published_at", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "archived_at": { + "name": "archived_at", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "is_home_page": { + "name": "is_home_page", + "type": "boolean", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "false", + "mappedType": "boolean" + }, + "root_id": { + "name": "root_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "post", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_post_handle_unique", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_post_handle_unique\" ON \"post\" (handle) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_post_root_id", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_root_id\" ON \"post\" (root_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_post_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_deleted_at\" ON \"post\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "post_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "post_root_id_foreign": { + "constraintName": "post_root_id_foreign", + "columnNames": [ + "root_id" + ], + "localTableName": "public.post", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post", + "deleteRule": "set null", + "updateRule": "cascade" + } + }, + "nativeEnums": {} + }, + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "name": { + "name": "name", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "medusa_user_id": { + "name": "medusa_user_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "post_author", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_post_author_medusa_user_id_unique", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_post_author_medusa_user_id_unique\" ON \"post_author\" (medusa_user_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_post_author_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_author_deleted_at\" ON \"post_author\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "post_author_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": {}, + "nativeEnums": {} + }, + { + "columns": { + "post_id": { + "name": "post_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "post_author_id": { + "name": "post_author_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + } + }, + "name": "post_post_authors", + "schema": "public", + "indexes": [ + { + "keyName": "post_post_authors_pkey", + "columnNames": [ + "post_id", + "post_author_id" + ], + "composite": true, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "post_post_authors_post_id_foreign": { + "constraintName": "post_post_authors_post_id_foreign", + "columnNames": [ + "post_id" + ], + "localTableName": "public.post_post_authors", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post", + "deleteRule": "cascade", + "updateRule": "cascade" + }, + "post_post_authors_post_author_id_foreign": { + "constraintName": "post_post_authors_post_author_id_foreign", + "columnNames": [ + "post_author_id" + ], + "localTableName": "public.post_post_authors", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post_author", + "deleteRule": "cascade", + "updateRule": "cascade" + } + }, + "nativeEnums": {} + }, + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "label": { + "name": "label", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "handle": { + "name": "handle", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "description": { + "name": "description", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "created_by_id": { + "name": "created_by_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "post_tag", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_post_tag_handle_unique", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_post_tag_handle_unique\" ON \"post_tag\" (handle) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_post_tag_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_tag_deleted_at\" ON \"post_tag\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "post_tag_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": {}, + "nativeEnums": {} + }, + { + "columns": { + "post_id": { + "name": "post_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "post_tag_id": { + "name": "post_tag_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + } + }, + "name": "post_post_tags", + "schema": "public", + "indexes": [ + { + "keyName": "post_post_tags_pkey", + "columnNames": [ + "post_id", + "post_tag_id" + ], + "composite": true, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "post_post_tags_post_id_foreign": { + "constraintName": "post_post_tags_post_id_foreign", + "columnNames": [ + "post_id" + ], + "localTableName": "public.post_post_tags", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post", + "deleteRule": "cascade", + "updateRule": "cascade" + }, + "post_post_tags_post_tag_id_foreign": { + "constraintName": "post_post_tags_post_tag_id_foreign", + "columnNames": [ + "post_tag_id" + ], + "localTableName": "public.post_post_tags", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post_tag", + "deleteRule": "cascade", + "updateRule": "cascade" + } + }, + "nativeEnums": {} + }, + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "title": { + "name": "title", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "status": { + "name": "status", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "'draft'", + "enumItems": [ + "draft", + "published", + "archived" + ], + "mappedType": "enum" + }, + "type": { + "name": "type", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "enumItems": [ + "page", + "post" + ], + "mappedType": "enum" + }, + "description": { + "name": "description", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "0", + "mappedType": "integer" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "post_template", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_post_template_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_template_deleted_at\" ON \"post_template\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "post_template_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": {}, + "nativeEnums": {} + }, + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "type": { + "name": "type", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "enumItems": [ + "button_list", + "cta", + "header", + "hero", + "product_carousel", + "product_grid", + "image_gallery", + "raw_html", + "rich_text", + "blog_list" + ], + "mappedType": "enum" + }, + "status": { + "name": "status", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "'draft'", + "enumItems": [ + "draft", + "published", + "archived" + ], + "mappedType": "enum" + }, + "name": { + "name": "name", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "content": { + "name": "content", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "json" + }, + "settings": { + "name": "settings", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "json" + }, + "styles": { + "name": "styles", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "is_reusable": { + "name": "is_reusable", + "type": "boolean", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "false", + "mappedType": "boolean" + }, + "usage_count": { + "name": "usage_count", + "type": "integer", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "default": "1", + "mappedType": "integer" + }, + "sort_order": { + "name": "sort_order", + "type": "integer", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "integer" + }, + "post_id": { + "name": "post_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "post_template_id": { + "name": "post_template_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "post_section", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_post_section_post_id", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_section_post_id\" ON \"post_section\" (post_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_post_section_post_template_id", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_section_post_template_id\" ON \"post_section\" (post_template_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_post_section_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_post_section_deleted_at\" ON \"post_section\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "post_section_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "post_section_post_id_foreign": { + "constraintName": "post_section_post_id_foreign", + "columnNames": [ + "post_id" + ], + "localTableName": "public.post_section", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post", + "deleteRule": "set null", + "updateRule": "cascade" + }, + "post_section_post_template_id_foreign": { + "constraintName": "post_section_post_template_id_foreign", + "columnNames": [ + "post_template_id" + ], + "localTableName": "public.post_section", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post_template", + "deleteRule": "set null", + "updateRule": "cascade" + } + }, + "nativeEnums": {} + }, + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "description": { + "name": "description", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "header_code": { + "name": "header_code", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "footer_code": { + "name": "footer_code", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "storefront_url": { + "name": "storefront_url", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "primary_theme_colors": { + "name": "primary_theme_colors", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "accent_theme_colors": { + "name": "accent_theme_colors", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "highlight_theme_colors": { + "name": "highlight_theme_colors", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "display_font": { + "name": "display_font", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "body_font": { + "name": "body_font", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "include_site_name_beside_logo": { + "name": "include_site_name_beside_logo", + "type": "boolean", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "boolean" + }, + "social_instagram": { + "name": "social_instagram", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "social_youtube": { + "name": "social_youtube", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "social_facebook": { + "name": "social_facebook", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "social_twitter": { + "name": "social_twitter", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "social_linkedin": { + "name": "social_linkedin", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "social_pinterest": { + "name": "social_pinterest", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "social_tiktok": { + "name": "social_tiktok", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "social_snapchat": { + "name": "social_snapchat", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "global_css": { + "name": "global_css", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "ga_property_id": { + "name": "ga_property_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "shipping_sort": { + "name": "shipping_sort", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "site_settings", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_site_settings_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_site_settings_deleted_at\" ON \"site_settings\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "site_settings_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": {}, + "nativeEnums": {} + }, + { + "columns": { + "id": { + "name": "id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "url": { + "name": "url", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "json" + }, + "post_id": { + "name": "post_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "site_settings_id": { + "name": "site_settings_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, + "created_at": { + "name": "created_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "length": 6, + "default": "now()", + "mappedType": "datetime" + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamptz", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "length": 6, + "mappedType": "datetime" + } + }, + "name": "image", + "schema": "public", + "indexes": [ + { + "keyName": "IDX_image_post_id_unique", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_image_post_id_unique\" ON \"image\" (post_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_image_site_settings_id_unique", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_image_site_settings_id_unique\" ON \"image\" (site_settings_id) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_image_deleted_at", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_image_deleted_at\" ON \"image\" (deleted_at) WHERE deleted_at IS NULL" + }, + { + "keyName": "IDX_product_image_url", + "columnNames": [], + "composite": false, + "constraint": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_product_image_url\" ON \"image\" (url) WHERE deleted_at IS NULL" + }, + { + "keyName": "image_pkey", + "columnNames": [ + "id" + ], + "composite": false, + "constraint": true, + "primary": true, + "unique": true + } + ], + "checks": [], + "foreignKeys": { + "image_post_id_foreign": { + "constraintName": "image_post_id_foreign", + "columnNames": [ + "post_id" + ], + "localTableName": "public.image", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.post", + "deleteRule": "set null", + "updateRule": "cascade" + }, + "image_site_settings_id_foreign": { + "constraintName": "image_site_settings_id_foreign", + "columnNames": [ + "site_settings_id" + ], + "localTableName": "public.image", + "referencedColumnNames": [ + "id" + ], + "referencedTableName": "public.site_settings", + "deleteRule": "set null", + "updateRule": "cascade" + } + }, + "nativeEnums": {} + } + ], + "nativeEnums": {} +} diff --git a/plugins/page-builder/src/modules/page-builder/migrations/Migration20250305164601.ts b/plugins/page-builder/src/modules/page-builder/migrations/Migration20250305164601.ts new file mode 100644 index 00000000..914a57ed --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/migrations/Migration20250305164601.ts @@ -0,0 +1,103 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20250305164601 extends Migration { + + override async up(): Promise { + this.addSql(`alter table if exists "image" drop constraint if exists "image_site_settings_id_unique";`); + this.addSql(`alter table if exists "image" drop constraint if exists "image_post_id_unique";`); + this.addSql(`alter table if exists "post_tag" drop constraint if exists "post_tag_handle_unique";`); + this.addSql(`alter table if exists "post_author" drop constraint if exists "post_author_medusa_user_id_unique";`); + this.addSql(`alter table if exists "post" drop constraint if exists "post_handle_unique";`); + this.addSql(`create table if not exists "navigation_item" ("id" text not null, "label" text not null, "location" text check ("location" in ('header', 'footer')) not null, "url" text not null, "new_tab" boolean not null default false, "sort_order" integer not null default 0, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "navigation_item_pkey" primary key ("id"));`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_navigation_item_deleted_at" ON "navigation_item" (deleted_at) WHERE deleted_at IS NULL;`); + + this.addSql(`create table if not exists "post" ("id" text not null, "type" text check ("type" in ('page', 'post')) not null, "title" text not null, "handle" text not null, "excerpt" text null, "content" jsonb null, "status" text check ("status" in ('draft', 'published', 'archived')) not null default 'draft', "content_mode" text check ("content_mode" in ('basic', 'advanced')) not null, "seo" jsonb null, "published_at" text null, "archived_at" text null, "is_home_page" boolean not null default false, "root_id" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "post_pkey" primary key ("id"));`); + this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_post_handle_unique" ON "post" (handle) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_root_id" ON "post" (root_id) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_deleted_at" ON "post" (deleted_at) WHERE deleted_at IS NULL;`); + + this.addSql(`create table if not exists "post_author" ("id" text not null, "name" text not null, "medusa_user_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "post_author_pkey" primary key ("id"));`); + this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_post_author_medusa_user_id_unique" ON "post_author" (medusa_user_id) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_author_deleted_at" ON "post_author" (deleted_at) WHERE deleted_at IS NULL;`); + + this.addSql(`create table if not exists "post_post_authors" ("post_id" text not null, "post_author_id" text not null, constraint "post_post_authors_pkey" primary key ("post_id", "post_author_id"));`); + + this.addSql(`create table if not exists "post_tag" ("id" text not null, "label" text not null, "handle" text not null, "description" text not null, "created_by_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "post_tag_pkey" primary key ("id"));`); + this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_post_tag_handle_unique" ON "post_tag" (handle) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_tag_deleted_at" ON "post_tag" (deleted_at) WHERE deleted_at IS NULL;`); + + this.addSql(`create table if not exists "post_post_tags" ("post_id" text not null, "post_tag_id" text not null, constraint "post_post_tags_pkey" primary key ("post_id", "post_tag_id"));`); + + this.addSql(`create table if not exists "post_template" ("id" text not null, "title" text not null, "status" text check ("status" in ('draft', 'published', 'archived')) not null default 'draft', "type" text check ("type" in ('page', 'post')) not null, "description" text null, "sort_order" integer not null default 0, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "post_template_pkey" primary key ("id"));`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_template_deleted_at" ON "post_template" (deleted_at) WHERE deleted_at IS NULL;`); + + this.addSql(`create table if not exists "post_section" ("id" text not null, "type" text check ("type" in ('button_list', 'cta', 'header', 'hero', 'product_carousel', 'product_grid', 'image_gallery', 'raw_html', 'rich_text', 'blog_list')) not null, "status" text check ("status" in ('draft', 'published', 'archived')) not null default 'draft', "name" text not null, "content" jsonb not null, "settings" jsonb not null, "styles" jsonb null, "is_reusable" boolean not null default false, "usage_count" integer not null default 1, "sort_order" integer not null, "post_id" text null, "post_template_id" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "post_section_pkey" primary key ("id"));`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_section_post_id" ON "post_section" (post_id) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_section_post_template_id" ON "post_section" (post_template_id) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_post_section_deleted_at" ON "post_section" (deleted_at) WHERE deleted_at IS NULL;`); + + this.addSql(`create table if not exists "site_settings" ("id" text not null, "description" text null, "header_code" text null, "footer_code" text null, "storefront_url" text null, "primary_theme_colors" jsonb null, "accent_theme_colors" jsonb null, "highlight_theme_colors" jsonb null, "display_font" jsonb null, "body_font" jsonb null, "include_site_name_beside_logo" boolean not null, "social_instagram" text null, "social_youtube" text null, "social_facebook" text null, "social_twitter" text null, "social_linkedin" text null, "social_pinterest" text null, "social_tiktok" text null, "social_snapchat" text null, "global_css" text null, "ga_property_id" text null, "shipping_sort" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "site_settings_pkey" primary key ("id"));`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_site_settings_deleted_at" ON "site_settings" (deleted_at) WHERE deleted_at IS NULL;`); + + this.addSql(`create table if not exists "image" ("id" text not null, "url" text not null, "metadata" jsonb null, "post_id" text null, "site_settings_id" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "image_pkey" primary key ("id"));`); + this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_image_post_id_unique" ON "image" (post_id) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE UNIQUE INDEX IF NOT EXISTS "IDX_image_site_settings_id_unique" ON "image" (site_settings_id) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_image_deleted_at" ON "image" (deleted_at) WHERE deleted_at IS NULL;`); + this.addSql(`CREATE INDEX IF NOT EXISTS "IDX_product_image_url" ON "image" (url) WHERE deleted_at IS NULL;`); + + this.addSql(`alter table if exists "post" add constraint "post_root_id_foreign" foreign key ("root_id") references "post" ("id") on update cascade on delete set null;`); + + this.addSql(`alter table if exists "post_post_authors" add constraint "post_post_authors_post_id_foreign" foreign key ("post_id") references "post" ("id") on update cascade on delete cascade;`); + this.addSql(`alter table if exists "post_post_authors" add constraint "post_post_authors_post_author_id_foreign" foreign key ("post_author_id") references "post_author" ("id") on update cascade on delete cascade;`); + + this.addSql(`alter table if exists "post_post_tags" add constraint "post_post_tags_post_id_foreign" foreign key ("post_id") references "post" ("id") on update cascade on delete cascade;`); + this.addSql(`alter table if exists "post_post_tags" add constraint "post_post_tags_post_tag_id_foreign" foreign key ("post_tag_id") references "post_tag" ("id") on update cascade on delete cascade;`); + + this.addSql(`alter table if exists "post_section" add constraint "post_section_post_id_foreign" foreign key ("post_id") references "post" ("id") on update cascade on delete set null;`); + this.addSql(`alter table if exists "post_section" add constraint "post_section_post_template_id_foreign" foreign key ("post_template_id") references "post_template" ("id") on update cascade on delete set null;`); + + this.addSql(`alter table if exists "image" add constraint "image_post_id_foreign" foreign key ("post_id") references "post" ("id") on update cascade on delete set null;`); + this.addSql(`alter table if exists "image" add constraint "image_site_settings_id_foreign" foreign key ("site_settings_id") references "site_settings" ("id") on update cascade on delete set null;`); + } + + override async down(): Promise { + this.addSql(`alter table if exists "post" drop constraint if exists "post_root_id_foreign";`); + + this.addSql(`alter table if exists "post_post_authors" drop constraint if exists "post_post_authors_post_id_foreign";`); + + this.addSql(`alter table if exists "post_post_tags" drop constraint if exists "post_post_tags_post_id_foreign";`); + + this.addSql(`alter table if exists "post_section" drop constraint if exists "post_section_post_id_foreign";`); + + this.addSql(`alter table if exists "image" drop constraint if exists "image_post_id_foreign";`); + + this.addSql(`alter table if exists "post_post_authors" drop constraint if exists "post_post_authors_post_author_id_foreign";`); + + this.addSql(`alter table if exists "post_post_tags" drop constraint if exists "post_post_tags_post_tag_id_foreign";`); + + this.addSql(`alter table if exists "post_section" drop constraint if exists "post_section_post_template_id_foreign";`); + + this.addSql(`alter table if exists "image" drop constraint if exists "image_site_settings_id_foreign";`); + + this.addSql(`drop table if exists "navigation_item" cascade;`); + + this.addSql(`drop table if exists "post" cascade;`); + + this.addSql(`drop table if exists "post_author" cascade;`); + + this.addSql(`drop table if exists "post_post_authors" cascade;`); + + this.addSql(`drop table if exists "post_tag" cascade;`); + + this.addSql(`drop table if exists "post_post_tags" cascade;`); + + this.addSql(`drop table if exists "post_template" cascade;`); + + this.addSql(`drop table if exists "post_section" cascade;`); + + this.addSql(`drop table if exists "site_settings" cascade;`); + + this.addSql(`drop table if exists "image" cascade;`); + } + +} diff --git a/plugins/page-builder/src/modules/page-builder/models/image.ts b/plugins/page-builder/src/modules/page-builder/models/image.ts new file mode 100644 index 00000000..f372a293 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/image.ts @@ -0,0 +1,30 @@ +import { model } from '@medusajs/framework/utils' +import { Post } from './post' +import { SiteSettings } from './site-settings' + +export const Image = model + .define('image', { + id: model.id({ prefix: 'img' }).primaryKey(), + url: model.text(), + metadata: model.json().nullable(), + + // relations fields + post: model + .belongsTo(() => Post, { + mappedBy: 'featured_image', + }) + .nullable(), + site_settings: model + .belongsTo(() => SiteSettings, { + mappedBy: 'favicon', + }) + .nullable(), + }) + .indexes([ + { + name: 'IDX_product_image_url', + on: ['url'], + unique: false, + where: 'deleted_at IS NULL', + }, + ]) diff --git a/plugins/page-builder/src/modules/page-builder/models/index.ts b/plugins/page-builder/src/modules/page-builder/models/index.ts new file mode 100644 index 00000000..e7009779 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/index.ts @@ -0,0 +1,8 @@ +export * from './post-author' +export * from './post' +export * from './post-section' +export * from './post-tag' +export * from './post-template' +export * from './image' +export * from './site-settings' +export * from './navigation-item' diff --git a/plugins/page-builder/src/modules/page-builder/models/navigation-item.ts b/plugins/page-builder/src/modules/page-builder/models/navigation-item.ts new file mode 100644 index 00000000..471f5db8 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/navigation-item.ts @@ -0,0 +1,10 @@ +import { model } from '@medusajs/framework/utils' + +export const NavigationItem = model.define('navigation_item', { + id: model.id({ prefix: 'nav_item' }).primaryKey(), + label: model.text(), + location: model.enum(['header', 'footer']), + url: model.text(), + new_tab: model.boolean().default(false), + sort_order: model.number().default(0), +}) diff --git a/plugins/page-builder/src/modules/page-builder/models/post-author.ts b/plugins/page-builder/src/modules/page-builder/models/post-author.ts new file mode 100644 index 00000000..00b0fbc2 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/post-author.ts @@ -0,0 +1,13 @@ +import { model } from '@medusajs/framework/utils' +import { Post } from './post' + +export const PostAuthor = model.define('post_author', { + id: model.id({ prefix: 'post_author' }).primaryKey(), + name: model.text(), + + // relations fields + medusa_user_id: model.text().unique(), + posts: model.manyToMany(() => Post, { + mappedBy: 'authors', + }), +}) diff --git a/plugins/page-builder/src/modules/page-builder/models/post-section.ts b/plugins/page-builder/src/modules/page-builder/models/post-section.ts new file mode 100644 index 00000000..eae96fe6 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/post-section.ts @@ -0,0 +1,39 @@ +import { model } from '@medusajs/framework/utils' +import { Post } from './post' +import { PostTemplate } from './post-template' + +export const PostSection = model.define('post_section', { + id: model.id({ prefix: 'postsec' }).primaryKey(), + type: model.enum([ + 'button_list', + 'cta', + 'header', + 'hero', + 'product_carousel', + 'product_grid', + 'image_gallery', + 'raw_html', + 'rich_text', + 'blog_list', + ]), + status: model.enum(['draft', 'published', 'archived']).default('draft'), + name: model.text(), + content: model.json(), + settings: model.json(), + styles: model.json().nullable(), + is_reusable: model.boolean().default(false), + usage_count: model.number().default(1), + sort_order: model.number(), + + // relations fields + post: model + .belongsTo(() => Post, { + mappedBy: 'sections', + }) + .nullable(), + post_template: model + .belongsTo(() => PostTemplate, { + mappedBy: 'sections', + }) + .nullable(), +}) diff --git a/plugins/page-builder/src/modules/page-builder/models/post-tag.ts b/plugins/page-builder/src/modules/page-builder/models/post-tag.ts new file mode 100644 index 00000000..582276d9 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/post-tag.ts @@ -0,0 +1,15 @@ +import { model } from '@medusajs/framework/utils' +import { Post } from './post' + +export const PostTag = model.define('post_tag', { + id: model.id({ prefix: 'post_tag' }).primaryKey(), + label: model.text(), + handle: model.text().unique(), + description: model.text(), + + // relations fields + created_by_id: model.text(), + posts: model.manyToMany(() => Post, { + mappedBy: 'tags', + }), +}) diff --git a/plugins/page-builder/src/modules/page-builder/models/post-template.ts b/plugins/page-builder/src/modules/page-builder/models/post-template.ts new file mode 100644 index 00000000..5ab7a7d4 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/post-template.ts @@ -0,0 +1,14 @@ +import { model } from '@medusajs/framework/utils' +import { PostSection } from './post-section' + +export const PostTemplate = model.define('post_template', { + id: model.id({ prefix: 'post_temp' }).primaryKey(), + title: model.text(), + status: model.enum(['draft', 'published', 'archived']).default('draft'), + type: model.enum(['page', 'post']), + description: model.text().nullable(), + sort_order: model.number().default(0), + + // relations fields + sections: model.hasMany(() => PostSection), +}) diff --git a/plugins/page-builder/src/modules/page-builder/models/post.ts b/plugins/page-builder/src/modules/page-builder/models/post.ts new file mode 100644 index 00000000..0844912c --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/post.ts @@ -0,0 +1,36 @@ +import { model } from '@medusajs/framework/utils' +import { PostSection } from './post-section' +import { PostTag } from './post-tag' +import { PostAuthor } from './post-author' +import { Image } from './image' + +export const Post = model.define('post', { + id: model.id({ prefix: 'post' }).primaryKey(), + type: model.enum(['page', 'post']), + title: model.text(), + handle: model.text().unique(), + excerpt: model.text().nullable(), + content: model.json().nullable(), + status: model.enum(['draft', 'published', 'archived']).default('draft'), + content_mode: model.enum(['basic', 'advanced']), + seo: model.json().nullable(), + published_at: model.text().nullable(), + archived_at: model.text().nullable(), + is_home_page: model.boolean().default(false), + + // relations fields + featured_image: model.hasOne(() => Image, { + mappedBy: 'post', + }), + authors: model.manyToMany(() => PostAuthor, { + mappedBy: 'posts', + }), + + root: model.belongsTo(() => Post).nullable(), + + sections: model.hasMany(() => PostSection), + + tags: model.manyToMany(() => PostTag, { + mappedBy: 'posts', + }), +}) diff --git a/plugins/page-builder/src/modules/page-builder/models/site-settings.ts b/plugins/page-builder/src/modules/page-builder/models/site-settings.ts new file mode 100644 index 00000000..461fb055 --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/models/site-settings.ts @@ -0,0 +1,32 @@ +import { model } from '@medusajs/framework/utils' +import { Image } from './image' + +export const SiteSettings = model.define('site_settings', { + id: model.id({ prefix: 'site_sett' }).primaryKey(), + description: model.text().nullable(), + header_code: model.text().nullable(), + footer_code: model.text().nullable(), + storefront_url: model.text().nullable(), + primary_theme_colors: model.json().nullable(), + accent_theme_colors: model.json().nullable(), + highlight_theme_colors: model.json().nullable(), + display_font: model.json().nullable(), + body_font: model.json().nullable(), + include_site_name_beside_logo: model.boolean(), + social_instagram: model.text().nullable(), + social_youtube: model.text().nullable(), + social_facebook: model.text().nullable(), + social_twitter: model.text().nullable(), + social_linkedin: model.text().nullable(), + social_pinterest: model.text().nullable(), + social_tiktok: model.text().nullable(), + social_snapchat: model.text().nullable(), + global_css: model.text().nullable(), + ga_property_id: model.text().nullable(), + shipping_sort: model.text().nullable(), + + // relations + favicon: model.hasOne(() => Image, { + mappedBy: 'site_settings', + }), +}) diff --git a/plugins/page-builder/src/modules/page-builder/service.ts b/plugins/page-builder/src/modules/page-builder/service.ts new file mode 100644 index 00000000..46dac9fb --- /dev/null +++ b/plugins/page-builder/src/modules/page-builder/service.ts @@ -0,0 +1,24 @@ +import { MedusaService } from '@medusajs/framework/utils' +import { + PostAuthor, + Post, + PostTemplate, + PostTag, + PostSection, + Image, + SiteSettings, + NavigationItem, +} from './models' + +class PageBuilderService extends MedusaService({ + PostAuthor, + Post, + PostTemplate, + PostTag, + PostSection, + Image, + SiteSettings, + NavigationItem, +}) {} + +export default PageBuilderService