diff --git a/db/migrations/1681393317164-Data.js b/db/migrations/1681393317164-Data.js new file mode 100644 index 00000000..e66826c7 --- /dev/null +++ b/db/migrations/1681393317164-Data.js @@ -0,0 +1,15 @@ +module.exports = class Data1681393317164 { + name = 'Data1681393317164' + + async up(db) { + await db.query(`CREATE TABLE "theme" ("id" character varying NOT NULL, "name" text NOT NULL, "theme_color1" text, "theme_color2" text, "theme_color3" text, "theme_color4" text, "base_id" character varying, CONSTRAINT "PK_c1934d0b4403bf10c1ab0c18166" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_52c219cbfa98d6011518283433" ON "theme" ("base_id") `) + await db.query(`ALTER TABLE "theme" ADD CONSTRAINT "FK_52c219cbfa98d6011518283433d" FOREIGN KEY ("base_id") REFERENCES "base"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + } + + async down(db) { + await db.query(`DROP TABLE "theme"`) + await db.query(`DROP INDEX "public"."IDX_52c219cbfa98d6011518283433"`) + await db.query(`ALTER TABLE "theme" DROP CONSTRAINT "FK_52c219cbfa98d6011518283433d"`) + } +} diff --git a/schema.graphql b/schema.graphql index 42686644..fed04d76 100644 --- a/schema.graphql +++ b/schema.graphql @@ -141,12 +141,22 @@ type Base @entity { meta: MetadataEntity metadata: String # parts: [BasePart!] @derivedFrom(field: "base") - # themes: [BaseTheme!] @derivedFrom(field: "base") + themes: [Theme!] @derivedFrom(field: "base") # attachedToResources: [Resource!] @derivedFrom (field: "base") # logs: [Call!] @derivedFrom (field: "base") // Rename to event } +type Theme @entity { + id: ID! + name: String! + base: Base! + themeColor1: String + themeColor2: String + themeColor3: String + themeColor4: String +} + # https://github.com/rmrk-team/rmrk-spec/blob/master/standards/rmrk2.0.0/entities/nft.md#resources-and-resource type Resource @entity { id: ID! diff --git a/src/mappings/v2/addTheme.ts b/src/mappings/v2/addTheme.ts index 84c4b6c2..efed82c8 100644 --- a/src/mappings/v2/addTheme.ts +++ b/src/mappings/v2/addTheme.ts @@ -2,10 +2,13 @@ import { Optional } from '@kodadot1/metasquid/types' import { ThemeAdd, toThemeId } from '@kodadot1/minimark/v2' import { getOrFail as get } from '@kodadot1/metasquid/entity' -import { Base } from '../../model' +import { Base, Theme } from '../../model' import { unwrap } from '../utils' -import logger, { logError } from '../utils/logger' +import { isOwnerOrElseError } from '../utils/consolidator' +import { camelCase } from '../utils/helper' +import logger, { logError, success } from '../utils/logger' import { Action, Context } from '../utils/types' +import { createUnlessNotExist } from '../utils/verbose' import { getThemeAdd } from './getters' const OPERATION = Action.THEMEADD @@ -18,29 +21,28 @@ export async function addTheme(context: Context) { const { value: interaction, caller, timestamp, blockNumber, version } = unwrap(context, getter) const base = await get(context.store, Base, interaction.base_id) + isOwnerOrElseError(base, caller) const id = toThemeId(interaction.base_id, interaction.name) - // const final = await createUnlessNotExist(id, Base, context) + const final = await createUnlessNotExist(id, Theme, context) - - // theme_color_1: String - // theme_color_2: String - // theme_color_3: String - // theme_color_4: String - const keys = [ 'theme_color_1', 'theme_color_2', 'theme_color_3', 'theme_color_4' ] + final.name = interaction.name + final.base = base + + const keys = ['theme_color_1', 'theme_color_2', 'theme_color_3', 'theme_color_4'] for (const key of keys) { const value = interaction.value[key] - // base[key] = interaction[key] + if (value && key !== 'base') { + const camelKey = camelCase(key) as keyof Omit + final[camelKey] = value } - + } // logger.success(`[${OPERATION}] NEW PRIORITY ${interaction.value} for ${nft.id} from ${caller}`) - // TODO: add logic for accepting resource - - logger.info(`[${OPERATION}] < ${interaction.name}, ${interaction.value} > for ${interaction.base_id} from ${caller}`) - // await context.store.save(nft) + success(OPERATION, `< ${interaction.name}, ${interaction.value} > for ${interaction.base_id} from ${caller}`) + await context.store.save(final) // await createEvent(nft, OPERATION, { blockNumber, caller, timestamp, version }, `${interaction.value.at(0)}`, context.store) } catch (e) { logError(e, (e) => logger.warn(`[${OPERATION}] ${e.message} ${JSON.stringify(interaction)}`)) diff --git a/src/mappings/v2/index.ts b/src/mappings/v2/index.ts index 82e73d46..52e59899 100644 --- a/src/mappings/v2/index.ts +++ b/src/mappings/v2/index.ts @@ -15,6 +15,7 @@ import { lockCollection } from './lock' import { mintItem } from './mint' import { send } from './send' import { setPriority } from './setpriority' +import { addTheme } from './addTheme' export async function mainFrame(remark: string, context: Context): Promise { const base = unwrap(context, (_: Context) => ({ value: remark })) @@ -63,8 +64,10 @@ export async function mainFrame(remark: string, context: Context): Promise case Interaction.LOCK: await lockCollection(context) break - case Interaction.DESTROY: case Interaction.THEMEADD: + await addTheme(context) + break + case Interaction.DESTROY: case Interaction.EQUIPPABLE: case Interaction.SETPROPERTY: case Interaction.EQUIP: diff --git a/src/model/generated/base.model.ts b/src/model/generated/base.model.ts index 7da46c7c..697dd438 100644 --- a/src/model/generated/base.model.ts +++ b/src/model/generated/base.model.ts @@ -1,6 +1,7 @@ -import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_, OneToMany as OneToMany_} from "typeorm" import {BaseType} from "./_baseType" import {MetadataEntity} from "./metadataEntity.model" +import {Theme} from "./theme.model" @Entity_() export class Base { @@ -29,4 +30,7 @@ export class Base { @Column_("text", {nullable: true}) metadata!: string | undefined | null + + @OneToMany_(() => Theme, e => e.base) + themes!: Theme[] } diff --git a/src/model/generated/index.ts b/src/model/generated/index.ts index 949fefd4..fc2e73c3 100644 --- a/src/model/generated/index.ts +++ b/src/model/generated/index.ts @@ -8,6 +8,7 @@ export * from "./_interaction" export * from "./emote.model" export * from "./base.model" export * from "./_baseType" +export * from "./theme.model" export * from "./resource.model" export * from "./series.model" export * from "./spotlight.model" diff --git a/src/model/generated/theme.model.ts b/src/model/generated/theme.model.ts new file mode 100644 index 00000000..19cbcfb9 --- /dev/null +++ b/src/model/generated/theme.model.ts @@ -0,0 +1,31 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import {Base} from "./base.model" + +@Entity_() +export class Theme { + constructor(props?: Partial) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Column_("text", {nullable: false}) + name!: string + + @Index_() + @ManyToOne_(() => Base, {nullable: true}) + base!: Base + + @Column_("text", {nullable: true}) + themeColor1!: string | undefined | null + + @Column_("text", {nullable: true}) + themeColor2!: string | undefined | null + + @Column_("text", {nullable: true}) + themeColor3!: string | undefined | null + + @Column_("text", {nullable: true}) + themeColor4!: string | undefined | null +}