├── .gitignore ├── client ├── custom.d.ts ├── src │ ├── pages │ │ ├── _dev │ │ │ └── index.ts │ │ ├── home │ │ │ ├── index.ts │ │ │ ├── select-menu │ │ │ │ ├── index.ts │ │ │ │ ├── hooks │ │ │ │ │ └── index.ts │ │ │ │ └── components │ │ │ │ │ └── index.ts │ │ │ └── home-page.tsx │ │ ├── sheet │ │ │ ├── index.ts │ │ │ └── components │ │ │ │ ├── index.ts │ │ │ │ ├── controls │ │ │ │ └── index.ts │ │ │ │ └── inventory │ │ │ │ └── index.ts │ │ ├── stream │ │ │ └── index.ts │ │ ├── signup │ │ │ └── index.ts │ │ ├── onboarding │ │ │ └── index.ts │ │ ├── ruleset │ │ │ ├── items │ │ │ │ └── index.ts │ │ │ ├── charts │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ │ ├── templates │ │ │ │ └── index.ts │ │ │ ├── archetypes │ │ │ │ └── index.ts │ │ │ ├── page-templates │ │ │ │ └── index.ts │ │ │ ├── attributes │ │ │ │ ├── components │ │ │ │ │ └── index.ts │ │ │ │ ├── attribute-store │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── evaluation │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── evaluation-functions │ │ │ │ │ │ │ ├── set.ts │ │ │ │ │ │ │ ├── announce.ts │ │ │ │ │ │ │ ├── side-effect.ts │ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ │ ├── return.ts │ │ │ │ │ │ │ └── inventory.ts │ │ │ │ │ └── attribute-store.ts │ │ │ │ └── index.ts │ │ │ ├── components │ │ │ │ ├── quick-create │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── rulebook │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── settings │ │ │ ├── index.ts │ │ │ ├── ruleset-settings │ │ │ │ ├── modules │ │ │ │ │ ├── index.ts │ │ │ │ │ └── create-module.tsx │ │ │ │ └── index.ts │ │ │ ├── user-settings │ │ │ │ └── index.ts │ │ │ ├── character-settings │ │ │ │ └── index.ts │ │ │ └── settings-button.tsx │ │ ├── marketplace │ │ │ └── index.ts │ │ ├── characters │ │ │ ├── character-page │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ └── character-journal.tsx │ │ ├── index.ts │ │ └── navigation │ │ │ └── components │ │ │ └── client-side-link.tsx │ ├── vite-env.d.ts │ ├── components │ │ ├── share │ │ │ ├── index.ts │ │ │ ├── players │ │ │ │ └── index.ts │ │ │ └── publish │ │ │ │ ├── index.ts │ │ │ │ └── not-published.tsx │ │ ├── log-panel │ │ │ ├── index.ts │ │ │ └── log-panel-button.tsx │ │ ├── rulebook-loading.tsx │ │ ├── error-boundary.tsx │ │ └── description-modal.tsx │ ├── libs │ │ ├── compass-planes │ │ │ ├── custom.d.ts │ │ │ ├── common │ │ │ │ ├── nodes │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── chart-node │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── line-node │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── canvas-node │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── player-canvas-node.css │ │ │ │ │ └── inventory-node │ │ │ │ │ │ └── index.ts │ │ │ │ ├── index.ts │ │ │ │ ├── components │ │ │ │ │ ├── edit-bar │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── edit-actions │ │ │ │ │ │ │ ├── common-actions │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ └── hooks │ │ │ │ │ ├── use-selections.ts │ │ │ │ │ ├── use-node-size.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── use-subscribe-component-changes.ts │ │ │ │ │ └── use-navigate-tabs.ts │ │ │ ├── sheet-editor │ │ │ │ ├── components │ │ │ │ │ ├── index.ts │ │ │ │ │ └── tabs-row │ │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── logic-editor │ │ │ │ ├── index.ts │ │ │ │ ├── node-data │ │ │ │ │ ├── index.ts │ │ │ │ │ └── edge-types.tsx │ │ │ │ ├── logic-editor.css │ │ │ │ ├── hooks │ │ │ │ │ ├── index.ts │ │ │ │ │ └── use-filter-changes.ts │ │ │ │ ├── components │ │ │ │ │ └── index.ts │ │ │ │ └── nodes │ │ │ │ │ ├── items │ │ │ │ │ └── index.ts │ │ │ │ │ ├── not-node.tsx │ │ │ │ │ ├── if-node.tsx │ │ │ │ │ ├── boolean-comparison-node.tsx │ │ │ │ │ ├── set-node.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ └── dice-node.tsx │ │ │ ├── sortable-list │ │ │ │ └── index.ts │ │ │ └── index.ts │ │ ├── compass-api │ │ │ ├── hooks │ │ │ │ ├── email │ │ │ │ │ └── index.ts │ │ │ │ ├── metrics │ │ │ │ │ └── index.ts │ │ │ │ ├── storage │ │ │ │ │ ├── index.ts │ │ │ │ │ └── images │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── use-get-images.ts │ │ │ │ ├── official-content │ │ │ │ │ ├── index.ts │ │ │ │ │ └── use-official-content.ts │ │ │ │ ├── dddice │ │ │ │ │ └── index.ts │ │ │ │ ├── charts │ │ │ │ │ └── index.ts │ │ │ │ ├── sheets │ │ │ │ │ └── index.ts │ │ │ │ ├── archetypes │ │ │ │ │ └── index.ts │ │ │ │ ├── components │ │ │ │ │ └── index.ts │ │ │ │ ├── characters │ │ │ │ │ └── index.ts │ │ │ │ ├── pages │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── use-pages.ts │ │ │ │ │ └── use-page-templates.ts │ │ │ │ ├── user │ │ │ │ │ ├── index.ts │ │ │ │ │ └── use-sign-out.ts │ │ │ │ ├── attributes │ │ │ │ │ └── index.ts │ │ │ │ ├── documents │ │ │ │ │ ├── index.ts │ │ │ │ │ └── use-documents.ts │ │ │ │ ├── index.ts │ │ │ │ └── rulesets │ │ │ │ │ ├── index.ts │ │ │ │ │ └── use-rulesets.ts │ │ │ ├── components │ │ │ │ ├── index.ts │ │ │ │ └── sign-up-form │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── form-validation.ts │ │ │ │ │ └── social-links.tsx │ │ │ ├── gql │ │ │ │ ├── types.ts │ │ │ │ ├── index.ts │ │ │ │ ├── queries │ │ │ │ │ ├── storage.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── documents.ts │ │ │ │ │ ├── charts.ts │ │ │ │ │ └── archetypes.ts │ │ │ │ └── mutations │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── characters.ts │ │ │ │ │ ├── charts.ts │ │ │ │ │ └── users.ts │ │ │ ├── types │ │ │ │ ├── permissions.ts │ │ │ │ ├── character.ts │ │ │ │ ├── index.ts │ │ │ │ ├── planes │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── component-types.tsx │ │ │ │ │ └── inventory-component-types.tsx │ │ │ │ ├── chat.ts │ │ │ │ └── apollo.ts │ │ │ ├── providers │ │ │ │ ├── index.ts │ │ │ │ └── rulebook-provider.tsx │ │ │ ├── utils │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ │ └── index.ts │ │ ├── compass-core-composites │ │ │ ├── index.ts │ │ │ ├── custom.d.ts │ │ │ └── composites │ │ │ │ ├── grid │ │ │ │ ├── index.ts │ │ │ │ └── grid.css │ │ │ │ ├── sheets │ │ │ │ ├── sheet-attribute-control │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── animated-update-msg.tsx │ │ │ │ │ └── text-attribute-node.tsx │ │ │ │ ├── index.ts │ │ │ │ └── form-validation.ts │ │ │ │ ├── sortable-tree │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ │ ├── image-gallery │ │ │ │ └── index.ts │ │ │ │ ├── entity-card │ │ │ │ └── index.ts │ │ │ │ ├── rulesets │ │ │ │ └── index.ts │ │ │ │ ├── client-side-link.tsx │ │ │ │ └── index.ts │ │ ├── compass-core-ui │ │ │ ├── animations │ │ │ │ ├── wrappers │ │ │ │ │ ├── index.ts │ │ │ │ │ └── fade-in.tsx │ │ │ │ ├── index.ts │ │ │ │ └── animated-monogram.tsx │ │ │ ├── hooks │ │ │ │ ├── use-theme.ts │ │ │ │ ├── index.ts │ │ │ │ ├── use-device-size.ts │ │ │ │ └── use-mobile.ts │ │ │ ├── public-utils │ │ │ │ ├── svg-icon.ts │ │ │ │ ├── css-baseline.ts │ │ │ │ ├── portal.ts │ │ │ │ ├── styled.ts │ │ │ │ ├── click-away-listener.ts │ │ │ │ └── index.ts │ │ │ ├── composites │ │ │ │ ├── logo │ │ │ │ │ └── index.ts │ │ │ │ ├── form │ │ │ │ │ ├── index.ts │ │ │ │ │ └── radio.tsx │ │ │ │ ├── color-picker.css │ │ │ │ ├── loading.tsx │ │ │ │ ├── page.tsx │ │ │ │ └── index.ts │ │ │ ├── assets │ │ │ │ ├── discord-icon.png │ │ │ │ ├── instagram-icon.png │ │ │ │ ├── index.ts │ │ │ │ ├── discord-icon.tsx │ │ │ │ ├── instagram-icon.tsx │ │ │ │ ├── logo-b.tsx │ │ │ │ ├── logo-q.tsx │ │ │ │ ├── logo-dark.tsx │ │ │ │ ├── logo-text.tsx │ │ │ │ ├── logo-icon.tsx │ │ │ │ └── qb-q.svg │ │ │ ├── utils │ │ │ │ ├── icon-type.ts │ │ │ │ ├── index.ts │ │ │ │ └── base-props.ts │ │ │ ├── theme │ │ │ │ ├── typography.ts │ │ │ │ ├── components.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── components │ │ │ │ ├── fab │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── chip │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── link │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── badge │ │ │ │ │ └── index.tsx │ │ │ │ ├── paper │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── radio │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── app-bar │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── avatar │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── drawer │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── slider │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── popper │ │ │ │ │ └── index.tsx │ │ │ │ ├── text │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── box │ │ │ │ │ └── index.tsx │ │ │ │ ├── loader │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── divider │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── progress │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── toolbar │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── backdrop │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── skeleton │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── stack │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── icon-button │ │ │ │ │ └── index.tsx │ │ │ │ ├── breadcrumbs │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── tooltip │ │ │ │ │ ├── theme.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── snackbar │ │ │ │ │ ├── theme.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── speed-dial │ │ │ │ │ ├── theme.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── autocomplete │ │ │ │ │ ├── theme.ts │ │ │ │ │ └── index.tsx │ │ │ │ ├── tabs │ │ │ │ │ └── index.tsx │ │ │ │ ├── dialog │ │ │ │ │ └── theme.ts │ │ │ │ ├── accordion │ │ │ │ │ └── theme.ts │ │ │ │ ├── menu │ │ │ │ │ └── index.tsx │ │ │ │ ├── select │ │ │ │ │ └── theme.ts │ │ │ │ ├── checkbox │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── image-list │ │ │ │ │ └── index.tsx │ │ │ │ ├── button │ │ │ │ │ └── index.tsx │ │ │ │ ├── toggle-button │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ │ ├── stepper │ │ │ │ │ ├── theme.ts │ │ │ │ │ └── index.tsx │ │ │ │ └── switch │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── theme.ts │ │ │ └── v2 │ │ │ │ └── ui │ │ │ │ ├── aspect-ratio.tsx │ │ │ │ ├── skeleton.tsx │ │ │ │ ├── spinner.tsx │ │ │ │ ├── label.tsx │ │ │ │ ├── progress.tsx │ │ │ │ ├── separator.tsx │ │ │ │ └── textarea.tsx │ │ ├── compass-web-journal │ │ │ ├── providers │ │ │ │ ├── index.ts │ │ │ │ └── journal-provider.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── components │ │ │ │ ├── toolbar │ │ │ │ ├── index.ts │ │ │ │ └── style-map.ts │ │ │ │ ├── index.ts │ │ │ │ ├── decorators │ │ │ │ └── index.ts │ │ │ │ ├── loading-journal-page.tsx │ │ │ │ └── editor.css │ │ └── compass-web-utils │ │ │ ├── providers │ │ │ ├── index.ts │ │ │ └── env-provider.tsx │ │ │ ├── index.ts │ │ │ ├── utils │ │ │ └── event-emitter.ts │ │ │ └── hooks │ │ │ ├── index.ts │ │ │ └── use-keyboard-override.ts │ ├── hooks │ │ ├── index.ts │ │ └── use-quick-create.ts │ ├── stores │ │ └── index.ts │ ├── assets │ │ ├── dddice.png │ │ └── CygnitoMonoPro-BoldR.otf │ ├── main.tsx │ └── types.ts ├── .gitignore ├── .dockerignore ├── .prettierignore ├── .eslintignore ├── .prettierrc.cjs ├── tsconfig.node.json ├── jest.config.js ├── index.html ├── Dockerfile ├── buildspec.yml ├── components.json ├── .eslintrc.js └── tsconfig.json ├── server ├── .dockerignore ├── src │ ├── database │ │ ├── index.ts │ │ └── prisma │ │ │ └── migrations │ │ │ ├── 20240107022246_stream_tab_id_not_unique │ │ │ └── migration.sql │ │ │ ├── 20231018223100_pub_rs_id │ │ │ └── migration.sql │ │ │ ├── 20240516140149_archetype_category │ │ │ └── migration.sql │ │ │ ├── 20231220003011_character_stream_ids │ │ │ └── migration.sql │ │ │ ├── 20231016163637_chart_data │ │ │ └── migration.sql │ │ │ ├── 20230924153255_archetype_size │ │ │ └── migration.sql │ │ │ ├── 20240107001130_ruleset_approved │ │ │ └── migration.sql │ │ │ ├── 20240216235140_item_sort_index │ │ │ └── migration.sql │ │ │ ├── 20240508212324_optional_character_rs_title │ │ │ └── migration.sql │ │ │ ├── 20231018155902_pub_chart_data │ │ │ └── migration.sql │ │ │ ├── 20240101203508_attribute_modifiers │ │ │ └── migration.sql │ │ │ ├── 20240508212133_character_rs_title_defaults │ │ │ └── migration.sql │ │ │ ├── 20240515131425_user_membership_expiration │ │ │ └── migration.sql │ │ │ ├── 20231017234917_character_descriptions │ │ │ └── migration.sql │ │ │ ├── 20240323125245_companion_model │ │ │ └── migration.sql │ │ │ ├── 20230918224146_ruleset_images │ │ │ └── migration.sql │ │ │ ├── 20231123161513_publish_approval │ │ │ └── migration.sql │ │ │ ├── 20240506134428_playtester_permissions │ │ │ └── migration.sql │ │ │ ├── migration_lock.toml │ │ │ ├── 20240505202307_pub_rs_shelved │ │ │ └── migration.sql │ │ │ ├── 20240101204334_published_attribute_modifiers │ │ │ └── migration.sql │ │ │ ├── 20240508205353_published_rs_explicit_flag │ │ │ └── migration.sql │ │ │ ├── 20231012193904_page_arch_id │ │ │ └── migration.sql │ │ │ ├── 20240114164143_attr_categories │ │ │ └── migration.sql │ │ │ ├── 20231026180615_rs_parent_titles │ │ │ └── migration.sql │ │ │ ├── 20240228185133_attribute_sorting │ │ │ └── migration.sql │ │ │ ├── 20231016221858_character_rs_association │ │ │ └── migration.sql │ │ │ ├── 20240508161516_published_ruleset_disclaimers │ │ │ └── migration.sql │ │ │ ├── 20231026183428_rs_created_by_id │ │ │ └── migration.sql │ │ │ ├── 20240421142252_attribute_meta_data │ │ │ └── migration.sql │ │ │ ├── 20231103162332_arch_attr_variation_type │ │ │ └── migration.sql │ │ │ ├── 20231115235256_page_bootstrap_bool │ │ │ └── migration.sql │ │ │ ├── 20231114195415_document_module_ids │ │ │ └── migration.sql │ │ │ ├── 20230924145632_archetype_image │ │ │ └── migration.sql │ │ │ ├── 20240126145308_character_pages │ │ │ └── migration.sql │ │ │ ├── 20231026201350_sheet_cascade_delete │ │ │ └── migration.sql │ │ │ ├── 20230926173558_archetypal_inheritance │ │ │ └── migration.sql │ │ │ ├── 20231015214855_ruleset_ruleset_id │ │ │ └── migration.sql │ │ │ ├── 20240217004529_item_linked_list │ │ │ └── migration.sql │ │ │ ├── 20240128171233_delete_char_on_user_delete │ │ │ └── migration.sql │ │ │ ├── 20240217152936_item_sort_child_index │ │ │ └── migration.sql │ │ │ ├── 20240506190129_character_rs_titles │ │ │ └── migration.sql │ │ │ ├── 20231220010650_unique_stream_tabs │ │ │ └── migration.sql │ │ │ ├── 20240215201935_item_parents │ │ │ └── migration.sql │ │ │ ├── 20230919163841_ruleset_listing │ │ │ └── migration.sql │ │ │ ├── 20230919224026_pubsheet_cascade_delete │ │ │ └── migration.sql │ │ │ ├── 20231010183105_official_content_unique_entity_id │ │ │ └── migration.sql │ │ │ ├── 20230919173309_remove_pubrs_user │ │ │ └── migration.sql │ │ │ ├── 20231018161520_module_permissions │ │ │ └── migration.sql │ │ │ ├── 20231005184900_official_content │ │ │ └── migration.sql │ │ │ ├── 20251213160508_prisma_update │ │ │ └── migration.sql │ │ │ ├── 20230920172108_ │ │ │ └── migration.sql │ │ │ ├── 20240421162442_remove_item_model │ │ │ └── migration.sql │ │ │ ├── 20230918220657_ruleset_images │ │ │ └── migration.sql │ │ │ ├── 20231004182823_ │ │ │ └── migration.sql │ │ │ ├── 20240404123954_archetype_dimensions │ │ │ └── migration.sql │ │ │ ├── 20230924012725_attribute_archetype_ids │ │ │ └── migration.sql │ │ │ ├── 20240426133016_attribute_images │ │ │ └── migration.sql │ │ │ ├── 20240229200107_license_key │ │ │ └── migration.sql │ │ │ ├── 20240120194409_rs_playtesters │ │ │ └── migration.sql │ │ │ ├── 20240125232127_ │ │ │ └── migration.sql │ │ │ ├── 20231015223941_character_archetypes │ │ │ └── migration.sql │ │ │ ├── 20240514212700_user_role_update │ │ │ └── migration.sql │ │ │ ├── 20240218002305_character_items │ │ │ └── migration.sql │ │ │ ├── 20240508135008_published_ruleset_properties │ │ │ └── migration.sql │ │ │ ├── 20240506160659_character_created_from_pub │ │ │ └── migration.sql │ │ │ ├── 20240214155718_items │ │ │ └── migration.sql │ │ │ ├── 20231011163901_public_dependencies │ │ │ └── migration.sql │ │ │ └── 20231017152235_pub_rs_created_by │ │ │ └── migration.sql │ ├── infrastructure │ │ ├── rest │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── services │ │ │ │ ├── email │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── email-templates.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── metrics │ │ │ │ │ └── index.ts │ │ │ │ ├── storage │ │ │ │ │ ├── bootstrap-storage.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── import-export │ │ │ │ │ └── index.ts │ │ │ │ └── signin │ │ │ │ │ └── index.ts │ │ │ └── endpoints.ts │ │ ├── graphql │ │ │ ├── index.ts │ │ │ ├── services │ │ │ │ ├── rulesets │ │ │ │ │ ├── modules │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── sharing │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── publishing │ │ │ │ │ │ └── index.ts │ │ │ │ ├── test-connection │ │ │ │ │ ├── test-connection.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── _shared │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── entity-ids.ts │ │ │ │ │ └── add-module-util.ts │ │ │ │ ├── index.ts │ │ │ │ ├── user │ │ │ │ │ └── index.ts │ │ │ │ ├── chart │ │ │ │ │ └── index.ts │ │ │ │ ├── image │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── images.ts │ │ │ │ │ └── create-image.ts │ │ │ │ ├── sheet │ │ │ │ │ └── index.ts │ │ │ │ ├── component │ │ │ │ │ ├── index.ts │ │ │ │ │ └── delete-components.ts │ │ │ │ ├── archetype │ │ │ │ │ └── index.ts │ │ │ │ ├── character │ │ │ │ │ ├── index.ts │ │ │ │ │ └── delete-character.ts │ │ │ │ ├── page │ │ │ │ │ ├── index.ts │ │ │ │ │ └── create-page.ts │ │ │ │ ├── attribute │ │ │ │ │ ├── index.ts │ │ │ │ │ └── utils.ts │ │ │ │ ├── document │ │ │ │ │ └── index.ts │ │ │ │ └── pubsub.ts │ │ │ ├── limits.ts │ │ │ └── .graphqlconfig.yml │ │ ├── authorization │ │ │ ├── index.ts │ │ │ └── types.ts │ │ └── cache.ts │ └── local-utils │ │ └── index.ts ├── .gitignore ├── .prettierrc.js ├── buildspec.yml ├── .vscode │ └── settings.json ├── prisma.config.ts ├── Dockerfile ├── .eslintrc.js ├── .eslintignore ├── .prettierignore └── .env ├── .github └── ISSUE_TEMPLATE │ ├── feature-request.md │ └── bug_report.md └── .env /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /client/custom.d.ts: -------------------------------------------------------------------------------- 1 | import 'vite/client'; 2 | -------------------------------------------------------------------------------- /server/.dockerignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | .env -------------------------------------------------------------------------------- /server/src/database/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client'; 2 | -------------------------------------------------------------------------------- /client/src/pages/_dev/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dev-page'; 2 | -------------------------------------------------------------------------------- /client/src/pages/home/index.ts: -------------------------------------------------------------------------------- 1 | export * from './home-page'; 2 | -------------------------------------------------------------------------------- /client/src/pages/sheet/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sheet'; 2 | -------------------------------------------------------------------------------- /client/src/pages/stream/index.ts: -------------------------------------------------------------------------------- 1 | export * from './stream'; 2 | -------------------------------------------------------------------------------- /client/src/pages/signup/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sign-in-page'; 2 | -------------------------------------------------------------------------------- /client/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /client/src/components/share/index.ts: -------------------------------------------------------------------------------- 1 | export * from './share-menu'; 2 | -------------------------------------------------------------------------------- /client/src/pages/onboarding/index.ts: -------------------------------------------------------------------------------- 1 | export * from './onboarding'; 2 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/items/index.ts: -------------------------------------------------------------------------------- 1 | export * from './item-form'; 2 | -------------------------------------------------------------------------------- /client/src/pages/settings/index.ts: -------------------------------------------------------------------------------- 1 | export * from './settings-modal'; 2 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/index.ts: -------------------------------------------------------------------------------- 1 | export * from './endpoints'; 2 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /dist 3 | .env 4 | .DS_Store 5 | .npmrc 6 | -------------------------------------------------------------------------------- /client/src/components/share/players/index.ts: -------------------------------------------------------------------------------- 1 | export * from './players'; 2 | -------------------------------------------------------------------------------- /client/src/components/share/publish/index.ts: -------------------------------------------------------------------------------- 1 | export * from './publish'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.module.css'; 2 | -------------------------------------------------------------------------------- /client/src/pages/home/select-menu/index.ts: -------------------------------------------------------------------------------- 1 | export * from './select-menu'; 2 | -------------------------------------------------------------------------------- /client/src/pages/sheet/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './controls'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/email/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-email'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/metrics/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-error'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/storage/index.ts: -------------------------------------------------------------------------------- 1 | export * from './images'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/index.ts: -------------------------------------------------------------------------------- 1 | export * from './composites'; 2 | -------------------------------------------------------------------------------- /client/src/pages/marketplace/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ruleset-sales-page'; 2 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/charts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './charts-entity-page'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.module.css'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/nodes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './node-types'; 2 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/templates/index.ts: -------------------------------------------------------------------------------- 1 | export * from './templates-entity-page'; 2 | -------------------------------------------------------------------------------- /client/src/pages/sheet/components/controls/index.ts: -------------------------------------------------------------------------------- 1 | export * from './edit-controls'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/grid/index.ts: -------------------------------------------------------------------------------- 1 | export * from './grid'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/animations/wrappers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './fade-in'; 2 | -------------------------------------------------------------------------------- /client/src/pages/characters/character-page/index.ts: -------------------------------------------------------------------------------- 1 | export * from './character-page'; 2 | -------------------------------------------------------------------------------- /client/src/pages/home/select-menu/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-filter-content'; 2 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/archetypes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './archetypes-entity-page'; 2 | -------------------------------------------------------------------------------- /client/src/pages/sheet/components/inventory/index.ts: -------------------------------------------------------------------------------- 1 | export * from './inventory-panel'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/hooks/use-theme.ts: -------------------------------------------------------------------------------- 1 | export { useTheme } from '@mui/system'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/nodes/chart-node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './chart-node'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/nodes/line-node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './line-node'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/sheet-editor/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tabs-row'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './journal-provider'; 2 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/page-templates/index.ts: -------------------------------------------------------------------------------- 1 | export * from './page-templates-entity-page'; 2 | -------------------------------------------------------------------------------- /client/src/pages/settings/ruleset-settings/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './module-settings'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/official-content/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-official-content'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/public-utils/svg-icon.ts: -------------------------------------------------------------------------------- 1 | export { SvgIcon } from '@mui/material'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/nodes/canvas-node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './canvas-node'; 2 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './logic-editor-controls'; 2 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/components/quick-create/index.ts: -------------------------------------------------------------------------------- 1 | export * from './quick-create-modal'; 2 | -------------------------------------------------------------------------------- /server/src/local-utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./types"; 2 | export * from "./local-db-client"; 3 | -------------------------------------------------------------------------------- /client/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-quick-create'; 2 | export * from './use-reduce-cache'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './nodes'; 2 | export * from './utils'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/sheet-editor/components/tabs-row/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tabs-row'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | export * from './types'; 3 | -------------------------------------------------------------------------------- /client/src/stores/index.ts: -------------------------------------------------------------------------------- 1 | export * from './event-log-store'; 2 | export * from './notification-store'; 3 | -------------------------------------------------------------------------------- /client/src/components/log-panel/index.ts: -------------------------------------------------------------------------------- 1 | export * from './log-panel'; 2 | export * from './log-panel-button'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/dddice/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './use-dice'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/public-utils/css-baseline.ts: -------------------------------------------------------------------------------- 1 | export { CssBaseline } from '@mui/material'; 2 | -------------------------------------------------------------------------------- /client/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | Dockerfile 4 | .dockerignore 5 | .git 6 | .gitignore 7 | .env -------------------------------------------------------------------------------- /client/src/assets/dddice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curtmorgan3/quest-bound/HEAD/client/src/assets/dddice.png -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/index.ts: -------------------------------------------------------------------------------- 1 | export * from './logic-editor'; 2 | export * from './types'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/types.ts: -------------------------------------------------------------------------------- 1 | export { convertFromRaw, convertToRaw, EditorState } from 'draft-js'; 2 | -------------------------------------------------------------------------------- /client/src/pages/characters/index.ts: -------------------------------------------------------------------------------- 1 | export * from './character-journal'; 2 | export * from './character-page'; 3 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/rulebook/index.ts: -------------------------------------------------------------------------------- 1 | export * from './edit-page-template'; 2 | export * from './rulebook'; 3 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /dist 3 | /src/storage 4 | .DS_Store 5 | .npmrc 6 | src/database/prisma/generated -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/index.ts: -------------------------------------------------------------------------------- 1 | export * from './gql-server'; 2 | export * from './generated-types'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './set-username'; 2 | export * from './sign-up-form'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/node-data/index.ts: -------------------------------------------------------------------------------- 1 | export * from './io'; 2 | export * from './node-types'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/composites/logo/index.ts: -------------------------------------------------------------------------------- 1 | export * from './splash-card'; 2 | export * from './splash-title'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/public-utils/portal.ts: -------------------------------------------------------------------------------- 1 | import { Portal } from '@mui/material'; 2 | 3 | export { Portal }; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/public-utils/styled.ts: -------------------------------------------------------------------------------- 1 | import { styled } from '@mui/material/styles'; 2 | export { styled }; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/sortable-list/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sortable-item'; 2 | export * from './sortable-list'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/components/toolbar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './style-map'; 2 | export * from './toolbar'; 3 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './quick-create'; 2 | export * from './render-entity-content'; 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/authorization/index.ts: -------------------------------------------------------------------------------- 1 | export * from './authorizer'; 2 | export * from './restful-authorizer'; 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/types.ts: -------------------------------------------------------------------------------- 1 | export type RestfulResponse = { 2 | statusCode: number; 3 | body: string; 4 | }; 5 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-utils/providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './env-provider'; 2 | export * from './settings-provider'; 3 | -------------------------------------------------------------------------------- /client/src/pages/home/select-menu/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-ruleset'; 2 | export * from './selection-card'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/sheets/sheet-attribute-control/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sheet-attribute-control'; 2 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './decorators/bootstrap-content'; 2 | export * from './journal'; 3 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/index.ts: -------------------------------------------------------------------------------- 1 | export * from './evaluation'; 2 | export * from './use-attribute-state'; 3 | -------------------------------------------------------------------------------- /client/src/pages/settings/ruleset-settings/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ruleset-details'; 2 | export * from './ruleset-settings-nav'; 3 | -------------------------------------------------------------------------------- /client/src/pages/settings/user-settings/index.ts: -------------------------------------------------------------------------------- 1 | export * from './settings-notifications'; 2 | export * from './settings-profile'; 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/email/constants.ts: -------------------------------------------------------------------------------- 1 | export const SUBSCRIBERS_LIST_ID = 'b7f6f88c-f348-11ed-a1cc-6d7234740485'; 2 | -------------------------------------------------------------------------------- /client/src/assets/CygnitoMonoPro-BoldR.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curtmorgan3/quest-bound/HEAD/client/src/assets/CygnitoMonoPro-BoldR.otf -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/sortable-tree/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sortable-tree'; 2 | export * from './types'; 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/rulesets/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from './add-module'; 2 | export * from './remove-module'; 3 | -------------------------------------------------------------------------------- /client/.prettierignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | .prettierignore 3 | yarn.lock 4 | yarn-error.log 5 | package-lock.json 6 | dist 7 | coverage 8 | pnpm-lock.yaml -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/components/edit-bar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './component-edit-actions'; 2 | export * from './edit-bar'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/components/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './bootstrap-content'; 2 | export * from './render-decorator'; 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/rulesets/sharing/index.ts: -------------------------------------------------------------------------------- 1 | export * from './add-playtester'; 2 | export * from './remove-playtester'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/types.ts: -------------------------------------------------------------------------------- 1 | export enum Viewport { 2 | DESKTOP = 'DESKTOP', 3 | MOBILE = 'MOBILE', 4 | TABLET = 'TABLET', 5 | } 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-device-size'; 2 | export * from './use-mobile'; 3 | export * from './use-theme'; 4 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240107022246_stream_tab_id_not_unique/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropIndex 2 | DROP INDEX "Character_streamTabId_key"; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/permissions.ts: -------------------------------------------------------------------------------- 1 | export enum PermissionType { 2 | OWNER = 'OWNER', 3 | READ = 'READ', 4 | WRITE = 'WRITE', 5 | } 6 | -------------------------------------------------------------------------------- /server/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | printWidth: 100, 3 | singleQuote: true, 4 | bracketSpacing: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /client/.eslintignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | .prettierignore 3 | yarn.lock 4 | yarn-error.log 5 | package-lock.json 6 | dist 7 | coverage 8 | pnpm-lock.yaml 9 | node_modules -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/animations/index.ts: -------------------------------------------------------------------------------- 1 | export * from './animated-monogram'; 2 | export * from './animated-text'; 3 | export * from './wrappers'; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/public-utils/click-away-listener.ts: -------------------------------------------------------------------------------- 1 | import { ClickAwayListener } from '@mui/material'; 2 | 3 | export { ClickAwayListener }; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/components/edit-bar/edit-actions/common-actions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './font-size'; 2 | export * from './text-align'; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231018223100_pub_rs_id/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRuleset" ADD COLUMN "rulesetId" TEXT; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240516140149_archetype_category/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Archetype" ADD COLUMN "category" TEXT; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/components/sign-up-form/index.ts: -------------------------------------------------------------------------------- 1 | export * from './join-discord'; 2 | export * from './sign-up-form'; 3 | export * from './social-links'; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './base-editor'; 2 | export * from './context-menu'; 3 | export * from './editor-loading'; 4 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231220003011_character_stream_ids/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Character" ADD COLUMN "streamTabId" TEXT; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/index.ts: -------------------------------------------------------------------------------- 1 | export * from './generated-types'; 2 | export * from './mutations'; 3 | export * from './queries'; 4 | export * from './types'; 5 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/providers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './archetype-provider'; 2 | export * from './attribute-provider'; 3 | export * from './rulebook-provider'; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/discord-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curtmorgan3/quest-bound/HEAD/client/src/libs/compass-core-ui/assets/discord-icon.png -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/instagram-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/curtmorgan3/quest-bound/HEAD/client/src/libs/compass-core-ui/assets/instagram-icon.png -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231016163637_chart_data/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Chart" ADD COLUMN "data" JSONB NOT NULL DEFAULT '[[]]'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/nodes/inventory-node/index.ts: -------------------------------------------------------------------------------- 1 | export * from './inventory-item'; 2 | export * from './inventory-node'; 3 | export * from './item-node'; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './logic-editor'; 2 | export * from './sheet-editor'; 3 | export * from './sortable-list'; 4 | export * from './types'; 5 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './hooks'; 2 | export * from './providers'; 3 | export * from './utils'; 4 | export * from './utils/event-emitter'; 5 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230924153255_archetype_size/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Archetype" ADD COLUMN "size" INTEGER NOT NULL DEFAULT 1; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240107001130_ruleset_approved/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Ruleset" ADD COLUMN "approved" BOOLEAN DEFAULT false; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240216235140_item_sort_index/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Item" ADD COLUMN "sortIndex" INTEGER NOT NULL DEFAULT 0; 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/authorization/types.ts: -------------------------------------------------------------------------------- 1 | export interface AuthorizerParams { 2 | token?: string; 3 | optionalAuth?: boolean; 4 | ignoreCache?: boolean; 5 | } 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/image-gallery/index.ts: -------------------------------------------------------------------------------- 1 | export * from './image-with-upload'; 2 | export * from './img'; 3 | export * from './select-image-modal'; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/utils/icon-type.ts: -------------------------------------------------------------------------------- 1 | export enum IconType { 2 | Home = 'Home', 3 | Space = 'Space', 4 | } 5 | 6 | export type IconPropType = 'Home' | 'Space'; 7 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-utils/utils/event-emitter.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from 'eventemitter3'; 2 | 3 | const emitter = new EventEmitter(); 4 | 5 | export { emitter }; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240508212324_optional_character_rs_title/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Character" ALTER COLUMN "rulesetTitle" DROP NOT NULL; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/entity-card/index.ts: -------------------------------------------------------------------------------- 1 | export * from './entity-card'; 2 | export * from './entity-card-slider'; 3 | export * from './entity-preview'; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/logic-editor.css: -------------------------------------------------------------------------------- 1 | .react-flow__handle-connecting { 2 | color: #E74323; 3 | } 4 | 5 | .react-flow__handle-valid { 6 | color: #36A800; 7 | } -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231018155902_pub_chart_data/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedChart" ADD COLUMN "data" JSONB NOT NULL DEFAULT '[[]]'; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240101203508_attribute_modifiers/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Attribute" ADD COLUMN "modifiers" JSONB NOT NULL DEFAULT '[]'; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240508212133_character_rs_title_defaults/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Character" ALTER COLUMN "rulesetTitle" SET DEFAULT ''; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240515131425_user_membership_expiration/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "User" ADD COLUMN "membershipExpiration" TIMESTAMP(3); 3 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/test-connection/test-connection.ts: -------------------------------------------------------------------------------- 1 | export const testConnection = () => { 2 | return { 3 | message: 'Hello, World!', 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231017234917_character_descriptions/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Character" ADD COLUMN "description" TEXT NOT NULL DEFAULT ''; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240323125245_companion_model/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Companion" ADD COLUMN "model" TEXT NOT NULL DEFAULT 'gpt-3.5-turbo'; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-filter-changes'; 2 | export * from './use-move-nodes'; 3 | export * from './use-update-operation-coordinates'; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/node-data/edge-types.tsx: -------------------------------------------------------------------------------- 1 | import { CustomEdge } from '../components/edge'; 2 | 3 | export const edgeTypes = { 4 | 'custom-edge': CustomEdge, 5 | }; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/sheet-editor/index.ts: -------------------------------------------------------------------------------- 1 | export * from '../common/nodes/inventory-node/inventory-item'; 2 | export * from './read-only-sheet'; 3 | export * from './sheet-editor'; 4 | -------------------------------------------------------------------------------- /client/src/pages/settings/character-settings/index.ts: -------------------------------------------------------------------------------- 1 | export * from './character-details'; 2 | export * from './character-settings-nav'; 3 | export * from './select-character-sheet-template'; 4 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230918224146_ruleset_images/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropIndex 2 | DROP INDEX "Ruleset_imageId_key"; 3 | 4 | -- DropIndex 5 | DROP INDEX "Sheet_imageId_key"; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231123161513_publish_approval/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRuleset" ADD COLUMN "approved" BOOLEAN NOT NULL DEFAULT false; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240506134428_playtester_permissions/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PlayTester" ADD COLUMN "permission" TEXT NOT NULL DEFAULT 'READ'; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (e.g., Git) 3 | provider = "postgresql" 4 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/evaluation/index.ts: -------------------------------------------------------------------------------- 1 | export * from './evaluation-functions/utils'; 2 | export * from './use-evaluate-logic'; 3 | export * from './use-logic-state'; 4 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './attribute-chart'; 2 | export * from './attribute-form'; 3 | export * from './attributes-entity-page'; 4 | export * from './logic-editor'; 5 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240505202307_pub_rs_shelved/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRulesetPermission" ADD COLUMN "shelved" BOOLEAN NOT NULL DEFAULT true; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './context-menu'; 2 | export * from './editor-controls'; 3 | export * from './handle'; 4 | export * from './node-wrapper'; 5 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/index.ts: -------------------------------------------------------------------------------- 1 | export * from './attributes/logic-editor'; 2 | export * from './rulebook/edit-page-template'; 3 | export * from './rulebook/rulebook'; 4 | export * from './ruleset-page'; 5 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240101204334_published_attribute_modifiers/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedAttribute" ADD COLUMN "modifiers" JSONB NOT NULL DEFAULT '[]'; 3 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240508205353_published_rs_explicit_flag/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRuleset" ADD COLUMN "explicit" BOOLEAN NOT NULL DEFAULT false; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/character.ts: -------------------------------------------------------------------------------- 1 | export interface UpdateCharacterItem { 2 | id: string; 3 | propertyId?: string; 4 | value?: string; 5 | name?: string; 6 | description?: string; 7 | } 8 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/test-connection/index.ts: -------------------------------------------------------------------------------- 1 | import { testConnection } from './test-connection'; 2 | 3 | export const testResolvers = { 4 | Query: { 5 | testConnection, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './defaults'; 2 | export * from './tree-helpers'; 3 | export * from './use-apollo-helpers'; 4 | export * from './utils'; 5 | export * from './wrapped-apollo-hooks'; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/public-utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './click-away-listener'; 2 | export * from './css-baseline'; 3 | export * from './portal'; 4 | export * from './styled'; 5 | export * from './svg-icon'; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-utils/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-key-listeners'; 2 | export * from './use-keyboard-override'; 3 | export * from './use-mouse-listeners'; 4 | export * from './use-replace-variable-text'; 5 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './apollo'; 2 | export * from './character'; 3 | export * from './chat'; 4 | export * from './json-types'; 5 | export * from './permissions'; 6 | export * from './planes'; 7 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/theme/typography.ts: -------------------------------------------------------------------------------- 1 | import { TypographyOptions } from '@mui/material/styles/createTypography'; 2 | 3 | export const typography: TypographyOptions = { 4 | fontFamily: 'Roboto Condensed', 5 | }; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/charts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-chart'; 2 | export * from './use-charts'; 3 | export * from './use-create-chart'; 4 | export * from './use-delete-chart'; 5 | export * from './use-update-chart'; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231012193904_page_arch_id/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Page" ADD COLUMN "archetypeId" TEXT; 3 | 4 | -- AlterTable 5 | ALTER TABLE "PublishedPage" ADD COLUMN "archetypeId" TEXT; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/sheets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-create-sheet'; 2 | export * from './use-delete-sheet'; 3 | export * from './use-get-sheet'; 4 | export * from './use-sheet-templates'; 5 | export * from './use-update-sheet'; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/nodes/items/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ability-node'; 2 | export * from './get-item-node'; 3 | export * from './inventory-node'; 4 | export * from './property-node'; 5 | export * from './set-item-node'; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240114164143_attr_categories/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Attribute" ADD COLUMN "category" TEXT; 3 | 4 | -- AlterTable 5 | ALTER TABLE "PublishedAttribute" ADD COLUMN "category" TEXT; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/index.ts: -------------------------------------------------------------------------------- 1 | export * from './components'; 2 | export * from './gql'; 3 | export * from './hooks'; 4 | export * from './provider'; 5 | export * from './providers'; 6 | export * from './types'; 7 | export * from './utils/defaults'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/planes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './base-component-types'; 2 | export * from './component-types'; 3 | export * from './defaults'; 4 | export * from './logic-component-types'; 5 | export * from './manage-component-types'; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231026180615_rs_parent_titles/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRuleset" ADD COLUMN "rulesetTitle" TEXT; 3 | 4 | -- AlterTable 5 | ALTER TABLE "Ruleset" ADD COLUMN "rulesetTitle" TEXT; 6 | -------------------------------------------------------------------------------- /client/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: ["prettier-plugin-organize-imports"], 3 | printWidth: 100, 4 | singleQuote: true, 5 | bracketSpacing: true, 6 | trailingComma: "all", 7 | jsxSingleQuote: true, 8 | bracketSameLine: true, 9 | } -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/archetypes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-archetype'; 2 | export * from './use-archetypes'; 3 | export * from './use-create-archetype'; 4 | export * from './use-delete-archetype'; 5 | export * from './use-update-archetype'; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240228185133_attribute_sorting/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Attribute" ADD COLUMN "sortChildId" TEXT; 3 | 4 | -- AlterTable 5 | ALTER TABLE "PublishedAttribute" ADD COLUMN "sortChildId" TEXT; 6 | -------------------------------------------------------------------------------- /server/src/infrastructure/cache.ts: -------------------------------------------------------------------------------- 1 | import NodeCache from 'node-cache'; 2 | 3 | let cache: NodeCache | null = null; 4 | 5 | export const getCache = () => { 6 | if (!cache) { 7 | cache = new NodeCache(); 8 | } 9 | return cache; 10 | }; 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/components/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-components'; 2 | export * from './use-create-component'; 3 | export * from './use-delete-components'; 4 | export * from './use-stream-components'; 5 | export * from './use-update-component'; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/theme/components.ts: -------------------------------------------------------------------------------- 1 | import { Components } from '@mui/material/styles'; 2 | 3 | export const components: Components = { 4 | MuiButtonBase: { 5 | defaultProps: { 6 | disableRipple: true, 7 | }, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231016221858_character_rs_association/migration.sql: -------------------------------------------------------------------------------- 1 | -- AddForeignKey 2 | ALTER TABLE "Character" ADD CONSTRAINT "Character_rulesetId_fkey" FOREIGN KEY ("rulesetId") REFERENCES "Ruleset"("id") ON DELETE CASCADE ON UPDATE CASCADE; 3 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/index.ts: -------------------------------------------------------------------------------- 1 | export * from './animations'; 2 | export * from './assets/index'; 3 | export * from './components'; 4 | export * from './composites'; 5 | export * from './hooks'; 6 | export * from './providers'; 7 | export * from './public-utils'; 8 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240508161516_published_ruleset_disclaimers/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRuleset" ADD COLUMN "includesAI" BOOLEAN NOT NULL DEFAULT false, 3 | ADD COLUMN "includesPDF" BOOLEAN NOT NULL DEFAULT false; 4 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './discord-icon'; 2 | export * from './instagram-icon'; 3 | export * from './logo-b'; 4 | export * from './logo-dark'; 5 | export * from './logo-icon'; 6 | export * from './logo-q'; 7 | export * from './logo-text'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/storage/images/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-create-image'; 2 | export * from './use-create-images'; 3 | export * from './use-delete-image'; 4 | export * from './use-get-images'; 5 | export * from './use-images'; 6 | export * from './use-update-image'; 7 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231026183428_rs_created_by_id/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRuleset" ADD COLUMN "createdById" TEXT NOT NULL DEFAULT ''; 3 | 4 | -- AlterTable 5 | ALTER TABLE "Ruleset" ADD COLUMN "createdById" TEXT NOT NULL DEFAULT ''; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240421142252_attribute_meta_data/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Attribute" ADD COLUMN "data" JSONB NOT NULL DEFAULT '{}'; 3 | 4 | -- AlterTable 5 | ALTER TABLE "PublishedAttribute" ADD COLUMN "data" JSONB NOT NULL DEFAULT '{}'; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/composites/form/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkbox'; 2 | export * from './form'; 3 | export * from './input'; 4 | export * from './radio'; 5 | export * from './radio-group'; 6 | export * from './select'; 7 | export * from './switch'; 8 | export * from './wizard'; 9 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/characters/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-character'; 2 | export * from './use-characters'; 3 | export * from './use-create-character'; 4 | export * from './use-delete-character'; 5 | export * from './use-stream-character'; 6 | export * from './use-update-character'; 7 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231103162332_arch_attr_variation_type/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "ArchetypeAttributes" ALTER COLUMN "variation" SET DATA TYPE TEXT; 3 | 4 | -- AlterTable 5 | ALTER TABLE "PublishedArchetypeAttributes" ALTER COLUMN "variation" SET DATA TYPE TEXT; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231115235256_page_bootstrap_bool/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Page" ADD COLUMN "bootstrapped" BOOLEAN NOT NULL DEFAULT false; 3 | 4 | -- AlterTable 5 | ALTER TABLE "PublishedPage" ADD COLUMN "bootstrapped" BOOLEAN NOT NULL DEFAULT false; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/chat.ts: -------------------------------------------------------------------------------- 1 | export type ChatMessage = { 2 | role: 'assistant' | 'user' | 'system'; 3 | content: string; 4 | }; 5 | 6 | export type ChatRequest = { 7 | messages: ChatMessage[]; 8 | }; 9 | 10 | export type ChatResponse = { 11 | messages: ChatMessage[]; 12 | }; 13 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/sheets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sheet-attribute-control'; 2 | export * from './sheet-card'; 3 | export * from './sheet-card-select'; 4 | export * from './sheet-card-slider'; 5 | export * from './sheet-details-modal'; 6 | export * from './sheet-preview'; 7 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/providers/journal-provider.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | type IJournalContext = { 4 | readOnly: boolean; 5 | }; 6 | 7 | export const JournalContext = createContext(null!); 8 | export const JournalProvider = JournalContext.Provider; 9 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/fab/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIFab, { FabProps as MUIFabProps } from '@mui/material/Fab'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type FabProps = MUIFabProps; 6 | 7 | export const Fab = ({ ...baseProps }: FabProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/queries/storage.ts: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client/core/index.js'; 2 | 3 | export const images = gql` 4 | query Images { 5 | images { 6 | id 7 | src 8 | name 9 | parentId 10 | details 11 | sortIndex 12 | } 13 | } 14 | `; 15 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/pages/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-create-page'; 2 | export * from './use-create-page-template'; 3 | export * from './use-delete-page'; 4 | export * from './use-page'; 5 | export * from './use-page-templates'; 6 | export * from './use-pages'; 7 | export * from './use-update-page'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/chip/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIChip, { ChipProps as MUIChipProps } from '@mui/material/Chip'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type ChipProps = MUIChipProps; 6 | 7 | export const Chip = ({ ...baseProps }: ChipProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/link/index.tsx: -------------------------------------------------------------------------------- 1 | import MUILink, { LinkProps as MUILinkProps } from '@mui/material/Link'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type LinkProps = MUILinkProps; 6 | 7 | export const Link = ({ ...baseProps }: LinkProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /server/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | phases: 4 | build: 5 | commands: 6 | - npm install 7 | - npm run build 8 | post_build: 9 | commands: 10 | - cp -R node_modules/ dist/node_modules 11 | artifacts: 12 | type: zip 13 | base-directory: 'dist' 14 | files: 15 | - '**/*' 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/user/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-alpha-users'; 2 | export * from './use-current-user'; 3 | export * from './use-search-users'; 4 | export * from './use-session-token'; 5 | export * from './use-sign-out'; 6 | export * from './use-update-current-user'; 7 | export * from './use-upgrade-user'; 8 | -------------------------------------------------------------------------------- /client/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "nodenext", 5 | "moduleResolution": "nodenext", 6 | "allowSyntheticDefaultImports": true, 7 | "maxNodeModuleJsDepth": 0, 8 | "skipLibCheck": true, 9 | }, 10 | "include": ["vite.config.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231114195415_document_module_ids/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Document" ADD COLUMN "moduleId" TEXT, 3 | ADD COLUMN "moduleTitle" TEXT; 4 | 5 | -- AlterTable 6 | ALTER TABLE "PublishedDocument" ADD COLUMN "moduleId" TEXT, 7 | ADD COLUMN "moduleTitle" TEXT; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/badge/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIBadge, { BadgeProps as MUIBadgeProps } from '@mui/material/Badge'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type BadgeProps = MUIBadgeProps; 6 | 7 | export const Badge = ({ ...baseProps }: BadgeProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/paper/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIPaper, { PaperProps as MUIPaperProps } from '@mui/material/Paper'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type PaperProps = MUIPaperProps; 6 | 7 | export const Paper = ({ ...baseProps }: PaperProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/radio/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIRadio, { RadioProps as MUIRadioProps } from '@mui/material/Radio'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type RadioProps = MUIRadioProps; 6 | 7 | export const Radio = ({ ...baseProps }: RadioProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/rulesets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './archetype-lookup'; 2 | export * from './attribute-lookup'; 3 | export * from './chart-lookup'; 4 | export * from './document-lookup'; 5 | export * from './page-lookup'; 6 | export * from './select-sheet-template'; 7 | export * from './template-lookup'; 8 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230924145632_archetype_image/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Archetype" ADD COLUMN "imageId" TEXT; 3 | 4 | -- AddForeignKey 5 | ALTER TABLE "Archetype" ADD CONSTRAINT "Archetype_imageId_fkey" FOREIGN KEY ("imageId") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240126145308_character_pages/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Page" ADD COLUMN "characterId" TEXT; 3 | 4 | -- AddForeignKey 5 | ALTER TABLE "Page" ADD CONSTRAINT "Page_characterId_fkey" FOREIGN KEY ("characterId") REFERENCES "Character"("id") ON DELETE SET NULL ON UPDATE CASCADE; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/attributes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-attribute'; 2 | export * from './use-attributes'; 3 | export * from './use-create-attribute'; 4 | export * from './use-delete-attribute'; 5 | export * from './use-get-attributes'; 6 | export * from './use-import-attributes'; 7 | export * from './use-update-attribute'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/documents/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-bootstrap-rulebook'; 2 | export * from './use-create-document'; 3 | export * from './use-delete-bootstrap'; 4 | export * from './use-delete-document'; 5 | export * from './use-document'; 6 | export * from './use-documents'; 7 | export * from './use-update-document'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/app-bar/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIAppBar, { AppBarProps as MUIAppBarProps } from '@mui/material/AppBar'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type AppBarProps = MUIAppBarProps; 6 | 7 | export const AppBar = ({ ...baseProps }: AppBarProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/avatar/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIAvatar, { AvatarProps as MUIAvatarProps } from '@mui/material/Avatar'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type AvatarProps = MUIAvatarProps; 6 | 7 | export const Avatar = ({ ...baseProps }: AvatarProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/drawer/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIDrawer, { DrawerProps as MUIDrawerProps } from '@mui/material/Drawer'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type DrawerProps = MUIDrawerProps; 6 | 7 | export const Drawer = ({ ...baseProps }: DrawerProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/slider/index.tsx: -------------------------------------------------------------------------------- 1 | import MUISlider, { SliderProps as MUISliderProps } from '@mui/material/Slider'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type SliderProps = MUISliderProps; 6 | 7 | export const Slider = ({ ...baseProps }: SliderProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/pages/index.ts: -------------------------------------------------------------------------------- 1 | export * from './characters'; 2 | export * from './home'; 3 | export * from './marketplace'; 4 | export * from './navigation'; 5 | export * from './ruleset'; 6 | export * from './settings'; 7 | export * from './sheet'; 8 | export * from './signup'; 9 | export * from './stream'; 10 | export * from './_dev'; 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/popper/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIPopper, { PopoverProps as MUIPopperProps } from '@mui/material/Popover'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type PopperProps = MUIPopperProps; 6 | 7 | export const Popper = ({ ...baseProps }: PopperProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/text/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIText, { TypographyProps as MUITypographyProps } from '@mui/material/Typography'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type TextProps = MUITypographyProps; 6 | 7 | export const Text = ({ ...baseProps }: TextProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-utils/providers/env-provider.tsx: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | type EnvContext = { 4 | environment: string; 5 | domain: string; 6 | maintenance: string[]; 7 | }; 8 | 9 | export const EnvContext = createContext(null!); 10 | export const EnvProvider = EnvContext.Provider; 11 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231026201350_sheet_cascade_delete/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropForeignKey 2 | ALTER TABLE "Sheet" DROP CONSTRAINT "Sheet_rulesetId_fkey"; 3 | 4 | -- AddForeignKey 5 | ALTER TABLE "Sheet" ADD CONSTRAINT "Sheet_rulesetId_fkey" FOREIGN KEY ("rulesetId") REFERENCES "Ruleset"("id") ON DELETE CASCADE ON UPDATE CASCADE; 6 | -------------------------------------------------------------------------------- /server/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "questbound", 4 | ], 5 | "emeraldwalk.runonsave": { 6 | "commands": [ 7 | { 8 | "match": "src\/infrastructure\/graphql\/schema.graphql", 9 | "cmd": "npm run gql:generate && npm run gql:copyTypes" 10 | }, 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /server/prisma.config.ts: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import { defineConfig, env } from 'prisma/config'; 3 | 4 | export default defineConfig({ 5 | schema: 'src/database/prisma/schema.prisma', 6 | migrations: { 7 | path: 'src/database/prisma/migrations', 8 | }, 9 | datasource: { 10 | url: env('DATABASE_URL'), 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230926173558_archetypal_inheritance/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Archetype" ADD COLUMN "parentId" TEXT; 3 | 4 | -- AddForeignKey 5 | ALTER TABLE "Archetype" ADD CONSTRAINT "Archetype_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Archetype"("id") ON DELETE SET NULL ON UPDATE CASCADE; 6 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231015214855_ruleset_ruleset_id/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `entityId` on the `Ruleset` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE "Ruleset" DROP COLUMN "entityId", 9 | ADD COLUMN "rulesetId" TEXT; 10 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240217004529_item_linked_list/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `sortIndex` on the `Item` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE "Item" DROP COLUMN "sortIndex", 9 | ADD COLUMN "sortParentId" TEXT; 10 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/_shared/index.ts: -------------------------------------------------------------------------------- 1 | export * from './create-sheet-from-template'; 2 | export * from './entity-ids'; 3 | export * from './add-module-util'; 4 | export * from './create-template-from-sheet'; 5 | export * from './check-user-permissions'; 6 | export * from './add-to-shelf-util'; 7 | export * from './create-page'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/sheets/form-validation.ts: -------------------------------------------------------------------------------- 1 | import * as yup from 'yup'; 2 | 3 | export type FormValues = { 4 | title: string; 5 | description: string; 6 | }; 7 | 8 | export const validationSchema = yup.object({ 9 | title: yup.string().required('Title is required'), 10 | description: yup.string(), 11 | }); 12 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240128171233_delete_char_on_user_delete/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropForeignKey 2 | ALTER TABLE "Character" DROP CONSTRAINT "Character_userId_fkey"; 3 | 4 | -- AddForeignKey 5 | ALTER TABLE "Character" ADD CONSTRAINT "Character_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; 6 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/rulesets/publishing/index.ts: -------------------------------------------------------------------------------- 1 | export * from './add-permission'; 2 | export * from './add-to-shelf'; 3 | export * from './delete-published-ruleset'; 4 | export * from './publish-ruleset'; 5 | export * from './remove-permission'; 6 | export * from './update-permission'; 7 | export * from './update-published-ruleset'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/box/index.tsx: -------------------------------------------------------------------------------- 1 | import MuiBox, { BoxProps as MuiBoxProps } from '@mui/material/Box'; 2 | import { forwardRef, type JSX } from 'react'; 3 | 4 | export type BoxProps = MuiBoxProps; 5 | 6 | export const Box = forwardRef( 7 | ({ ...baseProps }: BoxProps, ref): JSX.Element => , 8 | ); 9 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/loader/index.tsx: -------------------------------------------------------------------------------- 1 | import MUILoader, { CircularProgressProps as MUILoaderProps } from '@mui/material/CircularProgress'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type LoaderProps = MUILoaderProps; 6 | 7 | export const Loader = ({ ...baseProps }: LoaderProps): JSX.Element => ; 8 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/evaluation/evaluation-functions/set.ts: -------------------------------------------------------------------------------- 1 | import { Logic, Operation } from '@/libs/compass-planes'; 2 | import { getValueOfInputIfShouldExecute } from './utils'; 3 | 4 | export function evaluateSetOperation(operation: Operation, logic: Logic) { 5 | return getValueOfInputIfShouldExecute(operation, logic); 6 | } 7 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240217152936_item_sort_child_index/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `sortParentId` on the `Item` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE "Item" DROP COLUMN "sortParentId", 9 | ADD COLUMN "sortChildId" TEXT; 10 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240506190129_character_rs_titles/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - Added the required column `rulesetTitle` to the `Character` table without a default value. This is not possible if the table is not empty. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE "Character" ADD COLUMN "rulesetTitle" TEXT NOT NULL; 9 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/_shared/entity-ids.ts: -------------------------------------------------------------------------------- 1 | export function convertEntityId(rulesetId?: string) { 2 | const fromEntity = (entityId: string) => (rulesetId ? `${entityId}-${rulesetId}` : entityId); 3 | const toEntity = (fullId: string) => fullId.replace(`-${rulesetId}`, ''); 4 | return { 5 | fromEntity, 6 | toEntity, 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/evaluation/evaluation-functions/announce.ts: -------------------------------------------------------------------------------- 1 | import { Logic, Operation } from '@/libs/compass-planes'; 2 | import { getValueOfInputIfShouldExecute } from './utils'; 3 | 4 | export function evaluateAnnounceOperation(operation: Operation, logic: Logic) { 5 | return getValueOfInputIfShouldExecute(operation, logic); 6 | } 7 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/divider/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIDivider, { DividerProps as MUIDividerProps } from '@mui/material/Divider'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type DividerProps = MUIDividerProps; 6 | 7 | export const Divider = ({ ...baseProps }: DividerProps): JSX.Element => ( 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/evaluation/evaluation-functions/side-effect.ts: -------------------------------------------------------------------------------- 1 | import { Logic, Operation } from '@/libs/compass-planes'; 2 | import { getValueOfInputIfShouldExecute } from './utils'; 3 | 4 | export function evaluateSideEffectOperation(operation: Operation, logic: Logic) { 5 | return getValueOfInputIfShouldExecute(operation, logic); 6 | } 7 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/progress/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIProgress, { LinearProgressProps } from '@mui/material/LinearProgress'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type ProgressProps = LinearProgressProps; 6 | 7 | export const Progress = ({ ...baseProps }: ProgressProps): JSX.Element => ( 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/toolbar/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIToolbar, { ToolbarProps as MUIToolbarProps } from '@mui/material/Toolbar'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type ToolbarProps = MUIToolbarProps; 6 | 7 | export const Toolbar = ({ ...baseProps }: MUIToolbarProps): JSX.Element => ( 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/hooks/use-device-size.ts: -------------------------------------------------------------------------------- 1 | import { useMediaQuery } from '@mui/material'; 2 | 3 | export const useDeviceSize = () => { 4 | const mobile = useMediaQuery('(max-width:500px)'); 5 | const tablet = useMediaQuery('(max-width:1200px)'); 6 | 7 | return { 8 | mobile, 9 | tablet, 10 | desktop: !mobile && !tablet, 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /client/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './App'; 4 | import './index.css'; 5 | 6 | localStorage.setItem('chakra-ui-color-mode', 'dark'); 7 | 8 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 9 | 10 | 11 | , 12 | ); 13 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231220010650_unique_stream_tabs/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - A unique constraint covering the columns `[streamTabId]` on the table `Character` will be added. If there are existing duplicate values, this will fail. 5 | 6 | */ 7 | -- CreateIndex 8 | CREATE UNIQUE INDEX "Character_streamTabId_key" ON "Character"("streamTabId"); 9 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240215201935_item_parents/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Item" ADD COLUMN "attributeData" JSONB NOT NULL DEFAULT '[]', 3 | ADD COLUMN "parentId" TEXT; 4 | 5 | -- AddForeignKey 6 | ALTER TABLE "Item" ADD CONSTRAINT "Item_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Item"("id") ON DELETE SET NULL ON UPDATE CASCADE; 7 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/backdrop/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIBackdrop, { BackdropProps as MUIBackdropProps } from '@mui/material/Backdrop'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type BackdropProps = MUIBackdropProps; 6 | 7 | export const Backdrop = ({ ...baseProps }: BackdropProps): JSX.Element => ( 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/skeleton/index.tsx: -------------------------------------------------------------------------------- 1 | import MUISkeleton, { SkeletonProps as MUISkeletonProps } from '@mui/material/Skeleton'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type SkeletonProps = MUISkeletonProps; 6 | 7 | export const Skeleton = ({ ...baseProps }: SkeletonProps): JSX.Element => ( 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/v2/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 4 | 5 | function AspectRatio({ 6 | ...props 7 | }: React.ComponentProps) { 8 | return 9 | } 10 | 11 | export { AspectRatio } 12 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230919163841_ruleset_listing/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `published` on the `PublishedRuleset` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE "PublishedRuleset" DROP COLUMN "published", 9 | ADD COLUMN "listed" BOOLEAN NOT NULL DEFAULT false; 10 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/stack/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIStack, { StackProps as MUIStackProps } from '@mui/material/Stack'; 2 | import { forwardRef, type JSX } from 'react'; 3 | 4 | export type StackProps = MUIStackProps; 5 | 6 | export const Stack = forwardRef( 7 | ({ ...baseProps }, ref): JSX.Element => , 8 | ); 9 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/stack/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Stack' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiStack = { 8 | variants: [], 9 | }; 10 | }; 11 | 12 | export default injectTheme; 13 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230919224026_pubsheet_cascade_delete/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropForeignKey 2 | ALTER TABLE "PublishedSheet" DROP CONSTRAINT "PublishedSheet_rulesetId_fkey"; 3 | 4 | -- AddForeignKey 5 | ALTER TABLE "PublishedSheet" ADD CONSTRAINT "PublishedSheet_rulesetId_fkey" FOREIGN KEY ("rulesetId") REFERENCES "PublishedRuleset"("id") ON DELETE CASCADE ON UPDATE CASCADE; 6 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/discord-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import DiscordImage from './discord-icon.png'; 3 | 4 | interface DiscordIconProps { 5 | style?: React.CSSProperties; 6 | } 7 | 8 | export const DiscordIcon = ({ style }: DiscordIconProps) => { 9 | return Discord; 10 | }; 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/composites/color-picker.css: -------------------------------------------------------------------------------- 1 | .color-picker-input { 2 | display: block; 3 | box-sizing: border-box; 4 | width: 90px; 5 | margin: 20px 55px 0; 6 | padding: 6px; 7 | border: 1px solid #ddd; 8 | border-radius: 4px; 9 | background: #eee; 10 | outline: none; 11 | font: inherit; 12 | text-transform: uppercase; 13 | text-align: center; 14 | } 15 | -------------------------------------------------------------------------------- /client/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | setupFilesAfterEnv: ['./setupTests.ts'], 4 | projects: [ 5 | { 6 | preset: 'ts-jest', 7 | testEnvironment: 'node', 8 | displayName: 'api', 9 | setupFilesAfterEnv: ['./packages/compass-api/setupTests.ts'], 10 | testMatch: ['/packages/compass-api/**/*.test.tsx'], 11 | }, 12 | ], 13 | }; -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/icon-button/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIIconButton, { IconButtonProps as MUIIconButtonProps } from '@mui/material/IconButton'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type IconButtonProps = MUIIconButtonProps; 6 | 7 | export const IconButton = ({ ...baseProps }: IconButtonProps): JSX.Element => ( 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/v2/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/libs/compass-core-ui/utils'; 2 | 3 | function Skeleton({ className, ...props }: React.ComponentProps<'div'>) { 4 | return ( 5 |
10 | ); 11 | } 12 | 13 | export { Skeleton }; 14 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231010183105_official_content_unique_entity_id/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - A unique constraint covering the columns `[entityId]` on the table `OfficialContent` will be added. If there are existing duplicate values, this will fail. 5 | 6 | */ 7 | -- CreateIndex 8 | CREATE UNIQUE INDEX "OfficialContent_entityId_key" ON "OfficialContent"("entityId"); 9 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/email/email-templates.ts: -------------------------------------------------------------------------------- 1 | export const sharedRuleset = ({ 2 | username, 3 | rulesetTitle, 4 | }: { 5 | username: string; 6 | rulesetTitle?: string; 7 | }) => ` 8 |

${username} has shared ${rulesetTitle ?? 'a ruleset'} with you.

9 |

Login to add the ruleset to your shelf.

10 | `; 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/instagram-icon.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import InstagramImage from './instagram-icon.png'; 3 | 4 | interface InstagramIconProps { 5 | style?: React.CSSProperties; 6 | } 7 | 8 | export const InstagramIcon = ({ style }: InstagramIconProps) => { 9 | return Instagram; 10 | }; 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/breadcrumbs/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIBreadcrumbs, { BreadcrumbsProps as MUIBreadcrumbsProps } from '@mui/material/Breadcrumbs'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export type BreadcrumbsProps = MUIBreadcrumbsProps; 6 | 7 | export const Breadcrumbs = ({ ...baseProps }: BreadcrumbsProps): JSX.Element => ( 8 | 9 | ); 10 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/composites/loading.tsx: -------------------------------------------------------------------------------- 1 | import { AnimatedMonogram } from '../animations'; 2 | import { Stack } from '../components'; 3 | 4 | import type { JSX } from "react"; 5 | 6 | export const Loading = (): JSX.Element => { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | }; 13 | -------------------------------------------------------------------------------- /server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:23.5.0 2 | WORKDIR server/build 3 | COPY package*.json ./ 4 | 5 | RUN npm install 6 | COPY . . 7 | RUN npm run build:docker 8 | COPY . . 9 | 10 | 11 | RUN mkdir ./dist/storage 12 | RUN mkdir ./dist/storage/images 13 | RUN mkdir ./dist/storage/charts 14 | RUN mkdir ./dist/storage/documents 15 | RUN mkdir ./dist/storage/uploads 16 | 17 | EXPOSE 8000 18 | CMD ["npm", "run", "start:docker"] -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/tooltip/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Tooltip' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiTooltip = { 8 | variants: [], 9 | styleOverrides: {}, 10 | }; 11 | }; 12 | 13 | export default injectTheme; 14 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/attribute-store.ts: -------------------------------------------------------------------------------- 1 | import { ContextualAttribute, ContextualItem } from '@/libs/compass-api'; 2 | import { create } from 'zustand'; 3 | 4 | type AttributeStore = { 5 | attributes: ContextualAttribute[]; 6 | items: ContextualItem[]; 7 | }; 8 | 9 | export const useAttributeStore = create()((set) => ({ 10 | attributes: [], 11 | items: [], 12 | })); 13 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/mutations/index.ts: -------------------------------------------------------------------------------- 1 | export * from './archetypes'; 2 | export * from './attributes'; 3 | export * from './characters'; 4 | export * from './charts'; 5 | export * from './components'; 6 | export * from './documents'; 7 | export * from './items'; 8 | export * from './pages'; 9 | export * from './rulesets'; 10 | export * from './sheets'; 11 | export * from './storage'; 12 | export * from './users'; 13 | -------------------------------------------------------------------------------- /client/src/types.ts: -------------------------------------------------------------------------------- 1 | import { TreeItem } from '@/libs/compass-core-composites'; 2 | 3 | export type RulesetEntity = 4 | | 'sheet-templates' 5 | | 'page-templates' 6 | | 'charts' 7 | | 'attributes' 8 | | 'archetypes' 9 | | 'documents' 10 | | 'items'; 11 | 12 | export type PageTreeItem = Omit & { 13 | parentId: string | null; 14 | sortIndex: number; 15 | children: PageTreeItem[]; 16 | }; 17 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230919173309_remove_pubrs_user/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `userId` on the `PublishedRuleset` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- DropForeignKey 8 | ALTER TABLE "PublishedRuleset" DROP CONSTRAINT "PublishedRuleset_userId_fkey"; 9 | 10 | -- AlterTable 11 | ALTER TABLE "PublishedRuleset" DROP COLUMN "userId"; 12 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Quest Bound 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/queries/index.ts: -------------------------------------------------------------------------------- 1 | export * from './archetypes'; 2 | export * from './attributes'; 3 | export * from './characters'; 4 | export * from './charts'; 5 | export * from './components'; 6 | export * from './documents'; 7 | export * from './official-content'; 8 | export * from './pages'; 9 | export * from './rulesets'; 10 | export * from './sheets'; 11 | export * from './storage'; 12 | export * from './users'; 13 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/fab/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Fab' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiFab = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/composites/page.tsx: -------------------------------------------------------------------------------- 1 | import { CSSProperties, ReactNode } from 'react'; 2 | import { Stack } from '../components'; 3 | 4 | interface PageProps { 5 | children: ReactNode; 6 | style?: CSSProperties; 7 | } 8 | 9 | export const Page = ({ children, style }: PageProps) => { 10 | return ( 11 | 12 | {children} 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /client/src/pages/navigation/components/client-side-link.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link, LinkProps } from 'react-router-dom'; 3 | 4 | /** 5 | * Pass to Button to render an as tag and use React Router. 6 | */ 7 | export const ClientSideLink = React.forwardRef< 8 | HTMLAnchorElement, 9 | Omit & { href: LinkProps['to'] } 10 | >((props, ref) => ); 11 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231018161520_module_permissions/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "PublishedRuleset" ADD COLUMN "modulePermissions" JSONB NOT NULL DEFAULT '{}', 3 | ADD COLUMN "rulesetPermissions" JSONB NOT NULL DEFAULT '{}'; 4 | 5 | -- AlterTable 6 | ALTER TABLE "Ruleset" ADD COLUMN "modulePermissions" JSONB NOT NULL DEFAULT '{}', 7 | ADD COLUMN "rulesetPermissions" JSONB NOT NULL DEFAULT '{}'; 8 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/providers/rulebook-provider.tsx: -------------------------------------------------------------------------------- 1 | import { Document, Page, pdfjs } from 'react-pdf'; 2 | import 'react-pdf/dist/Page/AnnotationLayer.css'; 3 | import 'react-pdf/dist/Page/TextLayer.css'; 4 | 5 | pdfjs.GlobalWorkerOptions.workerSrc = new URL( 6 | 'pdfjs-dist/build/pdf.worker.min.js', 7 | import.meta.url, 8 | ).toString(); 9 | 10 | export { Document as RulebookDocumentContext, Page as RulebookDocumentPage }; 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/logo-b.tsx: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from 'react'; 2 | import LogoBSvg from './qb-b.svg'; 3 | 4 | interface LogoProps { 5 | style?: CSSProperties; 6 | } 7 | 8 | export const LogoB = ({ style }: LogoProps) => { 9 | return ( 10 | B monogram from the logo 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/logo-q.tsx: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from 'react'; 2 | import LogoQSvg from './qb-q.svg'; 3 | 4 | interface LogoProps { 5 | style?: CSSProperties; 6 | } 7 | 8 | export const LogoQ = ({ style }: LogoProps) => { 9 | return ( 10 | Q monogram from the logo 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/chip/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Chip' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiChip = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/link/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Link' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiLink = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/client-side-link.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link, LinkProps } from 'react-router-dom'; 3 | 4 | /** 5 | * Pass to Button to render an as tag and use React Router. 6 | */ 7 | export const ClientSideLink = React.forwardRef< 8 | HTMLAnchorElement, 9 | Omit & { href: LinkProps['to'] } 10 | >((props, ref) => ); 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/index.ts: -------------------------------------------------------------------------------- 1 | export * from './client-side-link'; 2 | export * from './editable-text'; 3 | export * from './entity-card'; 4 | export * from './file-upload'; 5 | export * from './grid'; 6 | export * from './icon-color-picker'; 7 | export * from './image-gallery'; 8 | export * from './notification'; 9 | export * from './rulesets'; 10 | export * from './sheets'; 11 | export * from './sortable-tree'; 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/logo-dark.tsx: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from 'react'; 2 | import LogoDarkSvg from './logo-dark.svg'; 3 | 4 | interface LogoProps { 5 | style?: CSSProperties; 6 | } 7 | 8 | export const LogoDark = ({ style }: LogoProps) => { 9 | return ( 10 | Quest Bound 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/logo-text.tsx: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from 'react'; 2 | import LogoTextSvg from './qb-text.svg'; 3 | 4 | interface LogoProps { 5 | style?: CSSProperties; 6 | } 7 | 8 | export const LogoText = ({ style }: LogoProps) => { 9 | return ( 10 | Quest Bound 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/paper/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Paper' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiPaper = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/slider/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Slider' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiSlider = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/drawer/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Drawer' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiDrawer = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/snackbar/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Snackbar' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiSnackbar = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/toolbar/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Toolbar' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiToolbar = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/backdrop/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Backdrop' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiBackdrop = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/skeleton/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Skeleton' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiSkeleton = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/limits.ts: -------------------------------------------------------------------------------- 1 | import { ResourceLimit } from '../types'; 2 | 3 | export const freeLimits = new Map([ 4 | [ResourceLimit.CHARACTER, 1], 5 | [ResourceLimit.PLAYER, 5], 6 | [ResourceLimit.RULESET, 1], 7 | [ResourceLimit.PUBLICATION, 0], 8 | ]); 9 | 10 | export const creatorLimits = new Map([ 11 | [ResourceLimit.PLAYER, 15], 12 | [ResourceLimit.PUBLICATION, 1], 13 | ]); 14 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/speed-dial/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/SpeedDial' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiSpeedDial = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/hooks/use-selections.ts: -------------------------------------------------------------------------------- 1 | import { SheetComponent } from '@/libs/compass-api'; 2 | import { useNodes } from 'reactflow'; 3 | 4 | export const useSelections = (components: SheetComponent[]) => { 5 | const nodes = useNodes(); 6 | const selectedNodes = nodes.filter((node) => node.selected); 7 | 8 | return { 9 | selectedComponents: components.filter((c) => selectedNodes.some((n) => n.id === c.id)), 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/autocomplete/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Autocomplete' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiAutocomplete = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/breadcrumbs/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Breadcrumbs' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiBreadcrumbs = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/progress/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/LinearProgress' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiLinearProgress = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/v2/ui/spinner.tsx: -------------------------------------------------------------------------------- 1 | import { Loader2Icon } from 'lucide-react'; 2 | 3 | import { cn } from '@/libs/compass-core-ui/utils'; 4 | 5 | function Spinner({ className, ...props }: React.ComponentProps<'svg'>) { 6 | return ( 7 | 13 | ); 14 | } 15 | 16 | export { Spinner }; 17 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231005184900_official_content/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "OfficialContent" ( 3 | "id" TEXT NOT NULL, 4 | "title" TEXT NOT NULL, 5 | "key" TEXT NOT NULL, 6 | "type" TEXT NOT NULL, 7 | "entityId" TEXT NOT NULL, 8 | 9 | CONSTRAINT "OfficialContent_pkey" PRIMARY KEY ("id") 10 | ); 11 | 12 | -- CreateIndex 13 | CREATE UNIQUE INDEX "OfficialContent_key_key" ON "OfficialContent"("key"); 14 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/index.ts: -------------------------------------------------------------------------------- 1 | export * from './test-connection'; 2 | export * from './user'; 3 | export * from './image'; 4 | export * from './rulesets'; 5 | export * from './archetype'; 6 | export * from './attribute'; 7 | export * from './character'; 8 | export * from './chart'; 9 | export * from './component'; 10 | export * from './document'; 11 | export * from './page'; 12 | export * from './sheet'; 13 | export * from './subscriptions'; 14 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/loader/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/CircularProgress' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiCircularProgress = { 8 | variants: [], 9 | styleOverrides: { 10 | root: {}, 11 | }, 12 | }; 13 | }; 14 | 15 | export default injectTheme; 16 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/user/index.ts: -------------------------------------------------------------------------------- 1 | import { currentUser } from './current-user'; 2 | import { earlyAccessUser } from './early-access-user'; 3 | import { searchUsers } from './search-users'; 4 | import { updateCurrentUser } from './update-current-user'; 5 | 6 | export const userResolvers = { 7 | Query: { 8 | currentUser, 9 | earlyAccessUser, 10 | searchUsers, 11 | }, 12 | Mutation: { 13 | updateCurrentUser, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /client/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:23.5.0 2 | 3 | # Set the working directory inside the container 4 | WORKDIR /build 5 | 6 | # Copy package.json and package-lock.json 7 | COPY package*.json ./ 8 | 9 | # Install dependencies 10 | RUN npm install 11 | 12 | # Copy the rest of your application files 13 | COPY . . 14 | 15 | RUN npm run build 16 | 17 | # Expose the port your app runs on 18 | EXPOSE 5173 19 | 20 | # Define the command to run your app 21 | CMD ["npm", "run", "start"] -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/logo-icon.tsx: -------------------------------------------------------------------------------- 1 | import { CSSProperties } from 'react'; 2 | import LogoIconSvg from './qb-monogram.svg'; 3 | 4 | interface LogoProps { 5 | style?: CSSProperties; 6 | } 7 | 8 | export const LogoIcon = ({ style }: LogoProps) => { 9 | return ( 10 | QB monogram in the shape of an open book 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/snackbar/index.tsx: -------------------------------------------------------------------------------- 1 | import MUISnackbar, { SnackbarProps as MUISnackbarProps } from '@mui/material/Snackbar'; 2 | import { motion } from 'framer-motion'; 3 | import { forwardRef } from 'react'; 4 | 5 | export type SnackbarProps = MUISnackbarProps; 6 | 7 | const AnimatedSnackbar = forwardRef((props: SnackbarProps, ref) => ( 8 | 9 | )); 10 | 11 | export const Snackbar = motion(AnimatedSnackbar); 12 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20251213160508_prisma_update/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "_PublishedRulesetModules" ADD CONSTRAINT "_PublishedRulesetModules_AB_pkey" PRIMARY KEY ("A", "B"); 3 | 4 | -- DropIndex 5 | DROP INDEX "_PublishedRulesetModules_AB_unique"; 6 | 7 | -- AlterTable 8 | ALTER TABLE "_RulesetModules" ADD CONSTRAINT "_RulesetModules_AB_pkey" PRIMARY KEY ("A", "B"); 9 | 10 | -- DropIndex 11 | DROP INDEX "_RulesetModules_AB_unique"; 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/components/sign-up-form/form-validation.ts: -------------------------------------------------------------------------------- 1 | import * as yup from 'yup'; 2 | 3 | export type FormValues = { 4 | email: string; 5 | password?: string; 6 | token: string; 7 | }; 8 | 9 | export const initialValues: FormValues = { 10 | email: '', 11 | password: '', 12 | token: '', 13 | }; 14 | 15 | export const signUpValidationSchema = yup.object({ 16 | email: yup.string().email('Enter a valid email').required('Email is required'), 17 | }); 18 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/chart/index.ts: -------------------------------------------------------------------------------- 1 | import { chart } from './chart'; 2 | import { charts } from './charts'; 3 | import { createChart } from './create-chart'; 4 | import { deleteChart } from './delete-chart'; 5 | import { updateChart } from './update-chart'; 6 | 7 | export const chartResolvers = { 8 | Query: { 9 | charts, 10 | chart, 11 | }, 12 | Mutation: { 13 | createChart, 14 | updateChart, 15 | deleteChart, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/metrics/index.ts: -------------------------------------------------------------------------------- 1 | import { Express } from 'express'; 2 | import { buildRestfulRoutes } from '@helpers/build-restful-route'; 3 | import { metricsProxy } from './proxy'; 4 | 5 | export const initializeMetricsEndpoints = (app: Express) => { 6 | buildRestfulRoutes([ 7 | { 8 | app, 9 | path: 'metrics', 10 | method: 'post', 11 | authRequired: false, 12 | handler: metricsProxy, 13 | }, 14 | ]); 15 | }; 16 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/storage/bootstrap-storage.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | const storageDir = path.join(__dirname.split('server')[0], 'server', 'dist', 'storage'); 5 | 6 | if (!fs.existsSync(storageDir)) { 7 | fs.mkdirSync(storageDir); 8 | fs.mkdirSync(`${storageDir}/uploads`); 9 | fs.mkdirSync(`${storageDir}/documents`); 10 | fs.mkdirSync(`${storageDir}/images`); 11 | fs.mkdirSync(`${storageDir}/charts`); 12 | } 13 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/components/sign-up-form/social-links.tsx: -------------------------------------------------------------------------------- 1 | import { Stack } from '@/libs/compass-core-ui'; 2 | import React from 'react'; 3 | import { JoinDiscord } from './join-discord'; 4 | 5 | interface SocialLinksProps { 6 | style?: React.CSSProperties; 7 | } 8 | 9 | export const SocialLinks = ({ style }: SocialLinksProps) => ( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/text/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Typography' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiTypography = { 8 | variants: [], 9 | styleOverrides: { 10 | root: { 11 | color: 'inherit', 12 | }, 13 | }, 14 | }; 15 | }; 16 | 17 | export default injectTheme; 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/components/edit-bar/edit-actions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './announcement-edit'; 2 | export * from './archetype-edit'; 3 | export * from './box-edit'; 4 | export * from './chart-edit'; 5 | export * from './checkbox-edit'; 6 | export * from './css-edit'; 7 | export * from './image-edit'; 8 | export * from './input-edit'; 9 | export * from './inventory-edit'; 10 | export * from './layer-edit'; 11 | export * from './pdf-edit'; 12 | export * from './text-edit'; 13 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/email/types.ts: -------------------------------------------------------------------------------- 1 | export type EmailOctopusEmailResponse = { 2 | email_address: string; 3 | id: string; 4 | fields: { 5 | email_address: string; 6 | }; 7 | tags: string[]; 8 | }; 9 | 10 | export type EmailOctopusResponse = { 11 | data: EmailOctopusEmailResponse[]; 12 | }; 13 | 14 | export type Subscriber = { 15 | memberId: string; 16 | email: string; 17 | free: boolean; 18 | creator: boolean; 19 | ignoreUpdates: boolean; 20 | }; 21 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/image/index.ts: -------------------------------------------------------------------------------- 1 | import { createImage } from './create-image'; 2 | import { deleteImage } from './delete-image'; 3 | import { images } from './images'; 4 | import { updateImage } from './update-image'; 5 | import { updateImages } from './update-images'; 6 | 7 | export const imageResolvers = { 8 | Query: { 9 | images, 10 | }, 11 | Mutation: { 12 | createImage, 13 | updateImage, 14 | updateImages, 15 | deleteImage, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/evaluation/evaluation-functions/index.ts: -------------------------------------------------------------------------------- 1 | export * from './action'; 2 | export * from './boolean'; 3 | export * from './chart'; 4 | export * from './comparison'; 5 | export * from './dice'; 6 | export * from './get-item'; 7 | export * from './if'; 8 | export * from './inventory'; 9 | export * from './math'; 10 | export * from './not'; 11 | export * from './return'; 12 | export * from './set'; 13 | export * from './utils'; 14 | export * from './variable'; 15 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/sheet/index.ts: -------------------------------------------------------------------------------- 1 | import { createSheet } from './create-sheet'; 2 | import { deleteSheet } from './delete-sheet'; 3 | import { sheet } from './sheet'; 4 | import { sheetTemplates } from './sheet-templates'; 5 | import { updateSheet } from './update-sheet'; 6 | 7 | export const sheetResolvers = { 8 | Query: { 9 | sheet, 10 | sheetTemplates, 11 | }, 12 | Mutation: { 13 | createSheet, 14 | updateSheet, 15 | deleteSheet, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/import-export/index.ts: -------------------------------------------------------------------------------- 1 | import { Express } from 'express'; 2 | import { buildRestfulRoutes } from '@helpers/build-restful-route'; 3 | import { importAttributes } from './import'; 4 | 5 | export const initializeImportExportEndpoints = (app: Express) => { 6 | buildRestfulRoutes([ 7 | { 8 | app, 9 | path: 'import/attributes', 10 | method: 'post', 11 | authRequired: true, 12 | handler: importAttributes, 13 | }, 14 | ]); 15 | }; 16 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/signin/index.ts: -------------------------------------------------------------------------------- 1 | import { buildRestfulRoutes } from '@/infrastructure/server-helpers/build-restful-route'; 2 | import { loginOrSignup } from './login-or-signup'; 3 | import { Express } from 'express'; 4 | 5 | export const initializeSigninEndpoints = (app: Express) => { 6 | buildRestfulRoutes([ 7 | { 8 | app, 9 | path: 'signup', 10 | method: 'post', 11 | authRequired: false, 12 | handler: loginOrSignup, 13 | }, 14 | ]); 15 | }; 16 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/services/storage/index.ts: -------------------------------------------------------------------------------- 1 | import { buildRestfulRoutes } from '@/infrastructure/server-helpers/build-restful-route'; 2 | import { Express } from 'express'; 3 | import { uploadFile } from './file-upload'; 4 | 5 | export const initializeStorageEndpoints = (app: Express) => { 6 | buildRestfulRoutes([ 7 | { 8 | app, 9 | path: 'storage/upload', 10 | method: 'upload', 11 | handler: uploadFile, 12 | authRequired: false, 13 | }, 14 | ]); 15 | }; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/avatar/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Avatar' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiAvatar = { 8 | variants: [], 9 | defaultProps: { 10 | variant: 'rounded', 11 | }, 12 | styleOverrides: { 13 | root: {}, 14 | }, 15 | }; 16 | }; 17 | 18 | export default injectTheme; 19 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/evaluation/evaluation-functions/return.ts: -------------------------------------------------------------------------------- 1 | import { Logic, Operation } from '@/libs/compass-planes'; 2 | import { clampValueToAttributeMinMax, getValueOfInputIfShouldExecute } from './utils'; 3 | 4 | export function evaluateReturnOperation(operation: Operation, logic: Logic) { 5 | const shouldInverse = operation.data?.inverse; 6 | const value = getValueOfInputIfShouldExecute(operation, logic, shouldInverse); 7 | return clampValueToAttributeMinMax(value, logic); 8 | } 9 | -------------------------------------------------------------------------------- /client/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | phases: 4 | install: 5 | runtime-versions: 6 | nodejs: 18 7 | commands: 8 | - npm i @nrwl/nx-linux-x64-gnu && npm install 9 | build: 10 | on-failure: ABORT 11 | commands: 12 | - npm run build 13 | post_build: 14 | commands: 15 | - aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths '/*' 16 | artifacts: 17 | enable-symlinks: yes 18 | base-directory: 'dist' 19 | files: 20 | - '**/*' 21 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './archetypes'; 2 | export * from './attributes'; 3 | export * from './characters'; 4 | export * from './charts'; 5 | export * from './components'; 6 | export * from './dddice'; 7 | export * from './documents'; 8 | export * from './email'; 9 | export * from './metrics'; 10 | export * from './official-content'; 11 | export * from './pages'; 12 | export * from './rulesets'; 13 | export * from './sheets'; 14 | export * from './storage'; 15 | export * from './user'; 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest a feature for this project 4 | title: '' 5 | labels: Feature Request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem?** 11 | Use the Bug Report or Improvement template instead. 12 | 13 | **Describe the feature you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/queries/documents.ts: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client/core/index.js'; 2 | 3 | export const documents = gql` 4 | query Documents($rulesetId: String!) { 5 | documents(rulesetId: $rulesetId) { 6 | id 7 | rulesetId 8 | title 9 | } 10 | } 11 | `; 12 | 13 | export const document = gql` 14 | query Document($input: GetEntity!) { 15 | document(input: $input) { 16 | id 17 | rulesetId 18 | title 19 | fileKey 20 | } 21 | } 22 | `; 23 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/divider/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Divider' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiDivider = { 8 | variants: [], 9 | styleOverrides: { 10 | root: { 11 | borderColor: compassDarkTheme.palette.primary.light, 12 | }, 13 | }, 14 | }; 15 | }; 16 | 17 | export default injectTheme; 18 | -------------------------------------------------------------------------------- /server/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: '@typescript-eslint/parser', 4 | ignorePatterns: ['.eslintrc.js'], 5 | plugins: ['@typescript-eslint'], 6 | extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], 7 | rules: { 8 | 'no-console': ['error', { allow: ['warn', 'error', 'debug'] }], 9 | '@typescript-eslint/no-unused-vars': 'error', 10 | 'arrow-body-style': 'error', 11 | }, 12 | parserOptions: { 13 | sourceType: 'module', 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/utils/base-props.ts: -------------------------------------------------------------------------------- 1 | import { SxProps } from '@mui/material'; 2 | import { CSSProperties } from 'react'; 3 | 4 | export interface BaseProps { 5 | id?: string; 6 | 7 | className?: string; 8 | 9 | style?: CSSProperties; 10 | 11 | 'data-testid'?: string; 12 | 13 | 'aria-label'?: string; 14 | 15 | 'aria-live'?: 'off' | 'assertive' | 'polite'; 16 | 17 | 'aria-labelledby'?: string; 18 | 19 | 'aria-describedby'?: string; 20 | 21 | role?: string; 22 | 23 | sx?: SxProps; 24 | } 25 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/component/index.ts: -------------------------------------------------------------------------------- 1 | import { sheetComponents } from './components'; 2 | import { createSheetComponents } from './create-components'; 3 | import { deleteSheetComponents } from './delete-components'; 4 | import { updateSheetComponents } from './update-components'; 5 | 6 | export const componentResolvers = { 7 | Query: { 8 | sheetComponents, 9 | }, 10 | Mutation: { 11 | createSheetComponents, 12 | updateSheetComponents, 13 | deleteSheetComponents, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /client/src/components/log-panel/log-panel-button.tsx: -------------------------------------------------------------------------------- 1 | import { IconButton, Tooltip } from '@/libs/compass-core-ui'; 2 | import { useEventLog } from '@/stores'; 3 | import { ReceiptLong } from '@mui/icons-material'; 4 | 5 | export const LogPanelButton = () => { 6 | const { setLogPanelOpen } = useEventLog(); 7 | 8 | return ( 9 | 10 | setLogPanelOpen(true)}> 11 | 12 | 13 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/tabs/index.tsx: -------------------------------------------------------------------------------- 1 | import MUITab, { TabProps as MUITabProps } from '@mui/material/Tab'; 2 | import MUITabs, { TabsProps as MUITabsProps } from '@mui/material/Tabs'; 3 | 4 | import type { JSX } from "react"; 5 | 6 | export type TabsProps = MUITabsProps; 7 | export type TabProps = MUITabProps; 8 | 9 | export const Tabs = ({ ...baseProps }: TabsProps): JSX.Element => ; 10 | 11 | export const Tab = ({ ...baseProps }: TabProps): JSX.Element => ; 12 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230920172108_/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - Added the required column `userId` to the `PublishedRuleset` table without a default value. This is not possible if the table is not empty. 5 | - Added the required column `username` to the `PublishedRuleset` table without a default value. This is not possible if the table is not empty. 6 | 7 | */ 8 | -- AlterTable 9 | ALTER TABLE "PublishedRuleset" ADD COLUMN "userId" TEXT NOT NULL, 10 | ADD COLUMN "username" TEXT NOT NULL; 11 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/dialog/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Dialog' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiDialog = { 8 | variants: [], 9 | styleOverrides: { 10 | root: { 11 | '& .MuiPaper-root': { 12 | maxWidth: '100%', 13 | }, 14 | }, 15 | }, 16 | }; 17 | }; 18 | 19 | export default injectTheme; 20 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/hooks/use-node-size.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react'; 2 | import { useReactFlow } from 'reactflow'; 3 | 4 | export const useNodeSize = (id?: string) => { 5 | const reactFlow = useReactFlow(); 6 | const node = reactFlow.getNode(id ?? ''); 7 | 8 | const height = useMemo(() => node?.height ?? 0, [node]); 9 | const width = useMemo(() => node?.width ?? 0, [node]); 10 | 11 | return { 12 | height: height ? `${height}px` : '', 13 | width: width ? `${width}px` : '', 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/nodes/canvas-node/player-canvas-node.css: -------------------------------------------------------------------------------- 1 | .player-canvas-node .excalidraw.theme--dark { 2 | --theme-filter: none; 3 | } 4 | 5 | .player-canvas-node .excalidraw { 6 | border-radius: inherit; 7 | } 8 | 9 | 10 | .player-canvas-node .excalidraw .App-top-bar { 11 | display: none !important; 12 | } 13 | 14 | .player-canvas-node .excalidraw .App-toolbar-content { 15 | display: none !important; 16 | } 17 | 18 | .player-canvas-node .excalidraw .App-menu { 19 | display: none !important; 20 | } 21 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/apollo.ts: -------------------------------------------------------------------------------- 1 | import { MutationFetchPolicy } from '@apollo/client/core/watchQueryOptions'; 2 | import { WatchQueryFetchPolicy } from '@apollo/client'; 3 | 4 | export type QueryOptions = { 5 | fetchPolicy?: WatchQueryFetchPolicy; 6 | }; 7 | 8 | export type MutationOptions = { 9 | fetchPolicy?: MutationFetchPolicy; 10 | }; 11 | 12 | export type QueryFunction = (input: T, opts?: QueryOptions) => Promise; 13 | 14 | export type MutationFunction = (input: T, opts?: MutationOptions) => Promise; 15 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/planes/component-types.tsx: -------------------------------------------------------------------------------- 1 | import { baseComponentTypes, SheetComponentType } from './base-component-types'; 2 | import { inventoryComponentTypes } from './inventory-component-types'; 3 | import { logicComponentTypes } from './logic-component-types'; 4 | import { manageComponentTypes } from './manage-component-types'; 5 | 6 | export const componentTypes: SheetComponentType[] = [ 7 | ...baseComponentTypes, 8 | ...logicComponentTypes, 9 | ...manageComponentTypes, 10 | ...inventoryComponentTypes, 11 | ]; 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/app-bar/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme, compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/AppBar' {} 5 | 6 | const injectTheme = (): void => { 7 | [compassLightTheme, compassDarkTheme].forEach((theme) => { 8 | theme.components.MuiAppBar = { 9 | variants: [], 10 | styleOverrides: { 11 | root: {}, 12 | }, 13 | }; 14 | }); 15 | }; 16 | 17 | export default injectTheme; 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/autocomplete/index.tsx: -------------------------------------------------------------------------------- 1 | import AutoComplete, { 2 | AutocompleteProps as MUIAutocompleteProps, 3 | } from '@mui/material/Autocomplete'; 4 | 5 | export type AutoCompleteProps = MUIAutocompleteProps; 6 | 7 | export type AutoCompleteOption = { 8 | label: string; 9 | value: string; 10 | }; 11 | 12 | export { AutoComplete }; 13 | 14 | // export const AutoComplete = ({ ...baseProps }: AutoCompleteProps): JSX.Element => ( 15 | // 16 | // ); 17 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240421162442_remove_item_model/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the `Item` table. If the table is not empty, all the data it contains will be lost. 5 | 6 | */ 7 | -- DropForeignKey 8 | ALTER TABLE "Item" DROP CONSTRAINT "Item_imageId_fkey"; 9 | 10 | -- DropForeignKey 11 | ALTER TABLE "Item" DROP CONSTRAINT "Item_parentId_fkey"; 12 | 13 | -- DropForeignKey 14 | ALTER TABLE "Item" DROP CONSTRAINT "Item_rulesetId_fkey"; 15 | 16 | -- DropTable 17 | DROP TABLE "Item"; 18 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/archetype/index.ts: -------------------------------------------------------------------------------- 1 | import { archetype } from './archetype'; 2 | import { archetypes } from './archetypes'; 3 | import { createArchetype } from './create-archetype'; 4 | import { deleteArchetype } from './delete-archetype'; 5 | import { updateArchetype } from './update-archetype'; 6 | 7 | export const archetypeResolvers = { 8 | Query: { 9 | archetype, 10 | archetypes, 11 | }, 12 | Mutation: { 13 | createArchetype, 14 | updateArchetype, 15 | deleteArchetype, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/character/index.ts: -------------------------------------------------------------------------------- 1 | import { character } from './character'; 2 | import { characters } from './characters'; 3 | import { createCharacter } from './create-character'; 4 | import { deleteCharacter } from './delete-character'; 5 | import { updateCharacter } from './update-character'; 6 | 7 | export const characterResolvers = { 8 | Query: { 9 | characters, 10 | character, 11 | }, 12 | Mutation: { 13 | createCharacter, 14 | updateCharacter, 15 | deleteCharacter, 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/queries/charts.ts: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client/core/index.js'; 2 | 3 | export const charts = gql` 4 | query Charts($rulesetId: String!) { 5 | charts(rulesetId: $rulesetId) { 6 | id 7 | rulesetId 8 | title 9 | fileKey 10 | data 11 | } 12 | } 13 | `; 14 | 15 | export const chart = gql` 16 | query Chart($input: GetEntity!) { 17 | chart(input: $input) { 18 | id 19 | rulesetId 20 | title 21 | fileKey 22 | data 23 | } 24 | } 25 | `; 26 | -------------------------------------------------------------------------------- /client/src/components/rulebook-loading.tsx: -------------------------------------------------------------------------------- 1 | import { Skeleton, Stack } from '@/libs/compass-core-ui'; 2 | 3 | export const RulebookLoading = () => { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/animations/animated-monogram.tsx: -------------------------------------------------------------------------------- 1 | import { useLottie } from 'lottie-react'; 2 | import { useDeviceSize } from '../hooks'; 3 | import LoadingAnimation from './loading.json'; 4 | 5 | export const AnimatedMonogram = () => { 6 | const { mobile } = useDeviceSize(); 7 | const style = { height: mobile ? 250 : 500, width: mobile ? 250 : 500 }; 8 | 9 | const { View } = useLottie({ 10 | animationData: LoadingAnimation, 11 | loop: true, 12 | autoPlay: true, 13 | style, 14 | }); 15 | 16 | return View; 17 | }; 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/tooltip/index.tsx: -------------------------------------------------------------------------------- 1 | import MUITooltip, { TooltipProps as MUITooltipProps } from '@mui/material/Tooltip'; 2 | import { forwardRef, type JSX } from 'react'; 3 | 4 | // export { Tooltip }; 5 | 6 | export type TooltipProps = MUITooltipProps; 7 | 8 | export const Tooltip = forwardRef( 9 | ({ ...baseProps }: TooltipProps, ref): JSX.Element => ( 10 | 11 |
{baseProps.children}
12 |
13 | ), 14 | ); 15 | 16 | Tooltip.displayName = 'Tooltip'; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/sortable-tree/types.ts: -------------------------------------------------------------------------------- 1 | import type { MutableRefObject } from 'react'; 2 | 3 | export interface TreeItem { 4 | id: string; 5 | label: string; 6 | children: TreeItem[]; 7 | collapsed?: boolean; 8 | hidden?: boolean; 9 | leaf?: boolean; 10 | } 11 | 12 | export interface FlattenedItem extends TreeItem { 13 | parentId: string | null; 14 | depth: number; 15 | index: number; 16 | } 17 | 18 | export type SensorContext = MutableRefObject<{ 19 | items: FlattenedItem[]; 20 | offset: number; 21 | }>; 22 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230918220657_ruleset_images/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `imageId` on the `PublishedRuleset` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- DropForeignKey 8 | ALTER TABLE "PublishedRuleset" DROP CONSTRAINT "PublishedRuleset_imageId_fkey"; 9 | 10 | -- DropIndex 11 | DROP INDEX "PublishedRuleset_imageId_key"; 12 | 13 | -- DropIndex 14 | DROP INDEX "PublishedSheet_imageId_key"; 15 | 16 | -- AlterTable 17 | ALTER TABLE "PublishedRuleset" DROP COLUMN "imageId"; 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/storage/images/use-get-images.ts: -------------------------------------------------------------------------------- 1 | import { images, ImagesQuery } from '../../../gql'; 2 | import { useQuery } from '../../../utils'; 3 | import { useError } from '../../metrics'; 4 | 5 | export const useGetImages = () => { 6 | const { data, refetch, error, loading } = useQuery(images); 7 | 8 | useError({ 9 | error, 10 | message: 'Failed to load images.', 11 | location: 'useGetImages', 12 | }); 13 | 14 | return { 15 | images: data?.images ?? [], 16 | refetch, 17 | loading, 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-utils/hooks/use-keyboard-override.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | 3 | export const useKeyboardOverride = (key: string, callback: () => void) => { 4 | useEffect(() => { 5 | const handleEnter = (e: KeyboardEvent) => { 6 | if (e.key === key) { 7 | e.preventDefault(); 8 | e.stopImmediatePropagation(); 9 | callback(); 10 | } 11 | }; 12 | 13 | document.addEventListener('keydown', handleEnter); 14 | return () => document.removeEventListener('keydown', handleEnter); 15 | }, []); 16 | }; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/animations/wrappers/fade-in.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion'; 2 | import { ReactNode } from 'react'; 3 | 4 | interface FadeInProps { 5 | children: ReactNode; 6 | delay?: number; 7 | duration?: number; 8 | } 9 | 10 | export const FadeIn = ({ children, delay = 0, duration = 0.5 }: FadeInProps) => { 11 | return ( 12 | 16 | {children} 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /client/src/hooks/use-quick-create.ts: -------------------------------------------------------------------------------- 1 | import { useSearchParams } from 'react-router-dom'; 2 | 3 | export const useQuickCreate = () => { 4 | const [searchParams, setSearchParams] = useSearchParams(); 5 | 6 | const setQuickCreatePage = (page: string, others?: Record) => { 7 | searchParams.set('quick-create', page); 8 | if (others) { 9 | Object.entries(others).forEach(([key, value]) => { 10 | searchParams.set(key, value); 11 | }); 12 | } 13 | setSearchParams(searchParams); 14 | }; 15 | 16 | return { setQuickCreatePage }; 17 | }; 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/accordion/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Accordion' {} 5 | 6 | const injectTheme = (): void => { 7 | compassDarkTheme.components.MuiAccordion = { 8 | variants: [], 9 | }; 10 | 11 | compassDarkTheme.components.MuiAccordionSummary = { 12 | variants: [], 13 | }; 14 | 15 | compassDarkTheme.components.MuiAccordionDetails = { 16 | variants: [], 17 | }; 18 | }; 19 | 20 | export default injectTheme; 21 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/composites/index.ts: -------------------------------------------------------------------------------- 1 | export * from './card-view'; 2 | export * from './color-picker'; 3 | export * from './color-picker-popper'; 4 | export * from './confirm'; 5 | export * from './delete-button'; 6 | export * from './error-page'; 7 | export * from './font-select'; 8 | export * from './font-size-select'; 9 | export * from './form'; 10 | export * from './loading'; 11 | export * from './logo'; 12 | export * from './min-max-slider'; 13 | export * from './modal'; 14 | export * from './page'; 15 | export * from './panel'; 16 | export * from './user-details'; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/components/toolbar/style-map.ts: -------------------------------------------------------------------------------- 1 | import { FontFamilies } from '@/libs/compass-core-ui'; 2 | import { CSSProperties } from 'react'; 3 | 4 | export const styleMap: Record = { 5 | ALIGN_LEFT: { 6 | textAlign: 'left', 7 | }, 8 | ALIGN_RIGHT: { 9 | textAlign: 'right', 10 | }, 11 | }; 12 | 13 | FontFamilies.forEach((family) => { 14 | styleMap[family] = { 15 | fontFamily: family, 16 | }; 17 | }); 18 | 19 | for (let i = 10; i <= 144; i++) { 20 | styleMap[`${i}px`] = { 21 | fontSize: `${i}px`, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/.graphqlconfig.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | Codegen Project: 3 | schemaPath: ./schema.graphql 4 | includes: 5 | - ./queries/*.ts 6 | excludes: 7 | - ./amplify/** 8 | extensions: 9 | amplify: 10 | codeGenTarget: typescript 11 | generatedFileName: ./generated-types.ts 12 | docsFilePath: ./queries 13 | region: us-east-1 14 | apiId: x5v5kc2ccvcarncsv2kr7aqqum 15 | frontend: javascript 16 | framework: none 17 | maxDepth: 6 18 | extensions: 19 | amplify: 20 | version: 3 21 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231004182823_/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `userId` on the `Sheet` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- DropForeignKey 8 | ALTER TABLE "Sheet" DROP CONSTRAINT "Sheet_userId_fkey"; 9 | 10 | -- AlterTable 11 | ALTER TABLE "Character" ALTER COLUMN "attributeData" SET DEFAULT '[]'; 12 | 13 | -- AlterTable 14 | ALTER TABLE "PublishedSheet" ADD COLUMN "createdBy" TEXT; 15 | 16 | -- AlterTable 17 | ALTER TABLE "Sheet" DROP COLUMN "userId", 18 | ADD COLUMN "createdBy" TEXT; 19 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/menu/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIMenu, { MenuProps as MUIMenuProps } from '@mui/material/Menu'; 2 | import MUIMenuItem, { MenuItemProps as MUIMenuItemProps } from '@mui/material/MenuItem'; 3 | 4 | import type { JSX } from "react"; 5 | 6 | export type MenuProps = MUIMenuProps; 7 | 8 | export const Menu = ({ ...baseProps }: MUIMenuProps): JSX.Element => ; 9 | 10 | export type MenuItemProps = MUIMenuItemProps; 11 | 12 | export const MenuItem = ({ ...baseProps }: MenuItemProps): JSX.Element => ( 13 | 14 | ); 15 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240404123954_archetype_dimensions/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Archetype" ADD COLUMN "height" INTEGER NOT NULL DEFAULT 0, 3 | ADD COLUMN "width" INTEGER NOT NULL DEFAULT 0, 4 | ADD COLUMN "x" INTEGER NOT NULL DEFAULT 0, 5 | ADD COLUMN "y" INTEGER NOT NULL DEFAULT 0; 6 | 7 | -- AlterTable 8 | ALTER TABLE "PublishedArchetype" ADD COLUMN "height" INTEGER NOT NULL DEFAULT 0, 9 | ADD COLUMN "width" INTEGER NOT NULL DEFAULT 0, 10 | ADD COLUMN "x" INTEGER NOT NULL DEFAULT 0, 11 | ADD COLUMN "y" INTEGER NOT NULL DEFAULT 0; 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/grid/grid.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Roboto+Condensed'); 2 | .ag-theme-quartz-dark { 3 | --ag-font-family: Roboto Condensed !important; 4 | --ag-foreground-color: #faf7f2 !important; 5 | --ag-background-color: #2a2a2a !important; 6 | --ag-header-foreground-color: #faf7f2 !important; 7 | --ag-header-background-color: #42403d !important; 8 | --ag-active-color: #417090 !important; 9 | --ag-checkbox-checked-background-color: #e66a3c !important; 10 | --ag-checkbox-checked-border-color: #e66a3c !important; 11 | } 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/select/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme, compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Select' {} 5 | 6 | const injectTheme = (): void => { 7 | compassLightTheme.components.MuiSelect = { 8 | variants: [], 9 | styleOverrides: {}, 10 | }; 11 | 12 | compassDarkTheme.components.MuiSelect = { 13 | variants: [], 14 | defaultProps: { 15 | size: 'small', 16 | }, 17 | styleOverrides: {}, 18 | }; 19 | }; 20 | 21 | export default injectTheme; 22 | -------------------------------------------------------------------------------- /client/src/pages/settings/ruleset-settings/modules/create-module.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Modal } from '@/libs/compass-core-ui'; 2 | import { useState } from 'react'; 3 | 4 | export const CreateModule = () => { 5 | const [modalOpen, setModalOpen] = useState(false); 6 | 7 | return ( 8 | <> 9 | 12 | setModalOpen(false)} 15 | size='medium' 16 | title='Create Module'> 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20230924012725_attribute_archetype_ids/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - The primary key for the `ArchetypeAttributes` table will be changed. If it partially fails, the table could be left without primary key constraint. 5 | - You are about to drop the column `id` on the `ArchetypeAttributes` table. All the data in the column will be lost. 6 | 7 | */ 8 | -- AlterTable 9 | ALTER TABLE "ArchetypeAttributes" DROP CONSTRAINT "ArchetypeAttributes_pkey", 10 | DROP COLUMN "id", 11 | ADD CONSTRAINT "ArchetypeAttributes_pkey" PRIMARY KEY ("archetypeId", "attributeId"); 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/nodes/not-node.tsx: -------------------------------------------------------------------------------- 1 | import { Text } from '@chakra-ui/react'; 2 | import { useContext } from 'react'; 3 | import { useNodeId } from 'reactflow'; 4 | import { NodeWrapper } from '../components'; 5 | import { LogicContext } from '../provider'; 6 | 7 | export const NotNode = () => { 8 | const { getOperation } = useContext(LogicContext); 9 | const operation = getOperation(useNodeId() ?? ''); 10 | 11 | if (!operation) return null; 12 | 13 | return ( 14 | 15 | NOT 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-component-click-actions'; 2 | export * from './use-conditional-render'; 3 | export * from './use-copy-paste'; 4 | export * from './use-group-components'; 5 | export * from './use-hydrate-editor-store'; 6 | export * from './use-move-nodes'; 7 | export * from './use-node-size'; 8 | export * from './use-selections'; 9 | export * from './use-sheet-colors'; 10 | export * from './use-sheet-component-nodes'; 11 | export * from './use-sheet-crud'; 12 | export * from './use-subscribe-component-changes'; 13 | export * from './use-sync-components-with-nodes'; 14 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240426133016_attribute_images/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Attribute" ADD COLUMN "imageId" TEXT; 3 | 4 | -- AlterTable 5 | ALTER TABLE "PublishedAttribute" ADD COLUMN "imageId" TEXT; 6 | 7 | -- AddForeignKey 8 | ALTER TABLE "Attribute" ADD CONSTRAINT "Attribute_imageId_fkey" FOREIGN KEY ("imageId") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE; 9 | 10 | -- AddForeignKey 11 | ALTER TABLE "PublishedAttribute" ADD CONSTRAINT "PublishedAttribute_imageId_fkey" FOREIGN KEY ("imageId") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE; 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/common/hooks/use-subscribe-component-changes.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | import { editorEmitter } from '../utils'; 3 | 4 | export const useSubscribeComponentChanges = (id: string | null) => { 5 | const [key, setKey] = useState(0); 6 | const subscribed = useRef(false); 7 | 8 | useEffect(() => { 9 | if (subscribed.current || !id) return; 10 | editorEmitter.on(`component-${id}-update`, () => { 11 | setKey((prev) => prev + 1); 12 | }); 13 | subscribed.current = true; 14 | }, [id]); 15 | 16 | return `component-${id}-key-${key}`; 17 | }; 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/components/loading-journal-page.tsx: -------------------------------------------------------------------------------- 1 | import { Skeleton, Stack } from '@/libs/compass-core-ui'; 2 | 3 | import type { JSX } from "react"; 4 | 5 | export const LoadingJournalPage = (): JSX.Element => { 6 | return ( 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /client/src/pages/home/home-page.tsx: -------------------------------------------------------------------------------- 1 | import { useCurrentUser } from '@/libs/compass-api'; 2 | import { useDeviceSize } from '@/libs/compass-core-ui'; 3 | import { Navigate } from 'react-router-dom'; 4 | import { SelectMenu } from './select-menu'; 5 | 6 | export const HomePage = () => { 7 | const { isCreator } = useCurrentUser(); 8 | const { mobile } = useDeviceSize(); 9 | const lastRulesetId = localStorage.getItem('last-viewed-ruleset-id'); 10 | 11 | if (lastRulesetId && !mobile && isCreator) { 12 | return ; 13 | } 14 | 15 | return ; 16 | }; 17 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/page/index.ts: -------------------------------------------------------------------------------- 1 | import { createPage } from './create-page'; 2 | import { createPageTemplate } from './create-page-template'; 3 | import { deletePage } from './delete-page'; 4 | import { page } from './page'; 5 | import { pageTemplates } from './page-templates'; 6 | import { pages } from './pages'; 7 | import { updatePages } from './update-pages'; 8 | 9 | export const pageResolvers = { 10 | Query: { 11 | page, 12 | pages, 13 | pageTemplates, 14 | }, 15 | Mutation: { 16 | createPage, 17 | updatePages, 18 | deletePage, 19 | createPageTemplate, 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/nodes/if-node.tsx: -------------------------------------------------------------------------------- 1 | import { Text } from '@chakra-ui/react'; 2 | import { useContext } from 'react'; 3 | import { useNodeId } from 'reactflow'; 4 | import { NodeWrapper } from '../components'; 5 | import { LogicContext } from '../provider'; 6 | 7 | export const IfNode = () => { 8 | const { getOperation } = useContext(LogicContext); 9 | const operation = getOperation(useNodeId() ?? ''); 10 | if (!operation) return null; 11 | 12 | return ( 13 | 14 | IF 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/attribute/index.ts: -------------------------------------------------------------------------------- 1 | import { attribute } from './attribute'; 2 | import { attributes } from './attributes'; 3 | import { createAttribute } from './create-attribute'; 4 | import { deleteAttribute } from './delete-attribute'; 5 | import { updateAttribute } from './update-attribute'; 6 | import { updateAttributeOrder } from './update-attribute-order'; 7 | 8 | export const attributeResolvers = { 9 | Query: { 10 | attribute, 11 | attributes, 12 | }, 13 | Mutation: { 14 | createAttribute, 15 | updateAttribute, 16 | deleteAttribute, 17 | updateAttributeOrder, 18 | }, 19 | }; 20 | -------------------------------------------------------------------------------- /client/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "src/index.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "iconLibrary": "lucide", 14 | "aliases": { 15 | "components": "@/libs/compass-core-ui/v2/components", 16 | "utils": "@/libs/compass-core-ui/utils", 17 | "ui": "@/libs/compass-core-ui/v2/components/ui", 18 | "lib": "@/lib", 19 | "hooks": "@/libs/compass-core-ui/hooks" 20 | }, 21 | "registries": {} 22 | } 23 | -------------------------------------------------------------------------------- /server/.eslintignore: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # FOLDERS 3 | ######################################################################## 4 | 5 | node_modules/ 6 | bin 7 | build 8 | cdk.out 9 | .vscode 10 | .husky 11 | lib/infrastructure/prisma-layer 12 | 13 | ######################################################################## 14 | # FILES 15 | ######################################################################## 16 | *.env* 17 | *.ico 18 | *.jpg 19 | *.png 20 | *.rules 21 | *.svg 22 | *.txt 23 | .eslintignore 24 | .gitignore 25 | .gitkeep 26 | .nvmrc 27 | .npcrc 28 | .prettierignore 29 | .DS_Store -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/checkbox/index.tsx: -------------------------------------------------------------------------------- 1 | import { FormControlLabel } from '@mui/material'; 2 | import MUICheckbox, { CheckboxProps as MUICheckboxProps } from '@mui/material/Checkbox'; 3 | 4 | import type { JSX } from "react"; 5 | 6 | export type CheckboxProps = MUICheckboxProps & { 7 | label?: string; 8 | labelPlacement?: 'bottom' | 'end' | 'start' | 'top'; 9 | }; 10 | 11 | export const Checkbox = ({ label, labelPlacement, ...baseProps }: CheckboxProps): JSX.Element => ( 12 | } 16 | /> 17 | ); 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/radio/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme, compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Radio' {} 5 | 6 | const injectTheme = (): void => { 7 | [compassLightTheme, compassDarkTheme].forEach((theme) => { 8 | theme.components.MuiRadio = { 9 | variants: [], 10 | styleOverrides: { 11 | root: { 12 | '&.Mui-checked': { 13 | color: theme.palette.secondary.main, 14 | }, 15 | }, 16 | }, 17 | }; 18 | }); 19 | }; 20 | 21 | export default injectTheme; 22 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240229200107_license_key/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "LicenseKey" ( 3 | "key" TEXT NOT NULL, 4 | "email" TEXT NOT NULL, 5 | "userId" TEXT, 6 | 7 | CONSTRAINT "LicenseKey_pkey" PRIMARY KEY ("key") 8 | ); 9 | 10 | -- CreateIndex 11 | CREATE UNIQUE INDEX "LicenseKey_email_key" ON "LicenseKey"("email"); 12 | 13 | -- CreateIndex 14 | CREATE UNIQUE INDEX "LicenseKey_userId_key" ON "LicenseKey"("userId"); 15 | 16 | -- AddForeignKey 17 | ALTER TABLE "LicenseKey" ADD CONSTRAINT "LicenseKey_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; 18 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240120194409_rs_playtesters/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "PlayTester" ( 3 | "id" TEXT NOT NULL, 4 | "rulesetId" TEXT NOT NULL, 5 | "userId" TEXT NOT NULL, 6 | 7 | CONSTRAINT "PlayTester_pkey" PRIMARY KEY ("id") 8 | ); 9 | 10 | -- AddForeignKey 11 | ALTER TABLE "PlayTester" ADD CONSTRAINT "PlayTester_rulesetId_fkey" FOREIGN KEY ("rulesetId") REFERENCES "Ruleset"("id") ON DELETE RESTRICT ON UPDATE CASCADE; 12 | 13 | -- AddForeignKey 14 | ALTER TABLE "PlayTester" ADD CONSTRAINT "PlayTester_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; 15 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/_shared/add-module-util.ts: -------------------------------------------------------------------------------- 1 | import { TPrismaClient } from '@/database'; 2 | import { cloneUtil } from './clone-util'; 3 | 4 | interface AddModule { 5 | db: TPrismaClient; 6 | moduleId: string; 7 | rulesetId: string; 8 | userId: string; 9 | } 10 | 11 | export async function addModule({ db, rulesetId, moduleId }: AddModule) { 12 | // Clone the modules entities into the ruleset 13 | const { cloneAllEntities } = await cloneUtil({ 14 | db, 15 | rulesetId, 16 | originalRulesetId: moduleId, 17 | addingModule: true, 18 | }); 19 | 20 | await cloneAllEntities(); 21 | 22 | return 'success'; 23 | } 24 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240125232127_/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - The values [PLAYER,BUILDER] on the enum `Role` will be removed. If these variants are still used in the database, this will fail. 5 | 6 | */ 7 | -- AlterEnum 8 | BEGIN; 9 | CREATE TYPE "Role_new" AS ENUM ('USER', 'CREATOR', 'EARLY_ACCESS'); 10 | ALTER TABLE "User" ALTER COLUMN "role" DROP DEFAULT; 11 | ALTER TABLE "User" ALTER COLUMN "role" TYPE "Role_new" USING ("role"::text::"Role_new"); 12 | ALTER TYPE "Role" RENAME TO "Role_old"; 13 | ALTER TYPE "Role_new" RENAME TO "Role"; 14 | DROP TYPE "Role_old"; 15 | ALTER TABLE "User" ALTER COLUMN "role" SET DEFAULT 'USER'; 16 | COMMIT; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/rulesets/index.ts: -------------------------------------------------------------------------------- 1 | export * from './use-add-module'; 2 | export * from './use-add-playtester'; 3 | export * from './use-add-to-shelf'; 4 | export * from './use-cancel-publish-ruleset'; 5 | export * from './use-create-ruleset'; 6 | export * from './use-delete-ruleset'; 7 | export * from './use-permitted-rulesets'; 8 | export * from './use-publish-ruleset'; 9 | export * from './use-remove-module'; 10 | export * from './use-remove-playtester'; 11 | export * from './use-ruleset'; 12 | export * from './use-ruleset-permitted-users'; 13 | export * from './use-ruleset-sales-page'; 14 | export * from './use-rulesets'; 15 | export * from './use-update-ruleset'; 16 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20231015223941_character_archetypes/migration.sql: -------------------------------------------------------------------------------- 1 | -- DropForeignKey 2 | ALTER TABLE "_CharacterArchetypes" DROP CONSTRAINT "_CharacterArchetypes_A_fkey"; 3 | 4 | -- DropForeignKey 5 | ALTER TABLE "_CharacterArchetypes" DROP CONSTRAINT "_CharacterArchetypes_B_fkey"; 6 | 7 | -- AddForeignKey 8 | ALTER TABLE "_CharacterArchetypes" ADD CONSTRAINT "_CharacterArchetypes_A_fkey" FOREIGN KEY ("A") REFERENCES "Archetype"("id") ON DELETE CASCADE ON UPDATE CASCADE; 9 | 10 | -- AddForeignKey 11 | ALTER TABLE "_CharacterArchetypes" ADD CONSTRAINT "_CharacterArchetypes_B_fkey" FOREIGN KEY ("B") REFERENCES "Character"("id") ON DELETE CASCADE ON UPDATE CASCADE; 12 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/hooks/use-mobile.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240514212700_user_role_update/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - The values [EARLY_ACCESS] on the enum `Role` will be removed. If these variants are still used in the database, this will fail. 5 | 6 | */ 7 | -- AlterEnum 8 | BEGIN; 9 | CREATE TYPE "Role_new" AS ENUM ('USER', 'CREATOR', 'PUBLISHER'); 10 | ALTER TABLE "User" ALTER COLUMN "role" DROP DEFAULT; 11 | ALTER TABLE "User" ALTER COLUMN "role" TYPE "Role_new" USING ("role"::text::"Role_new"); 12 | ALTER TYPE "Role" RENAME TO "Role_old"; 13 | ALTER TYPE "Role_new" RENAME TO "Role"; 14 | DROP TYPE "Role_old"; 15 | ALTER TABLE "User" ALTER COLUMN "role" SET DEFAULT 'USER'; 16 | COMMIT; 17 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/official-content/use-official-content.ts: -------------------------------------------------------------------------------- 1 | import { officialContent, OfficialContentQuery } from '../../gql'; 2 | import { useQuery } from '../../utils'; 3 | import { useError } from '../metrics'; 4 | 5 | export const useOfficialContent = () => { 6 | const { data, loading, error } = useQuery(officialContent); 7 | 8 | useError({ 9 | error, 10 | message: 'Failed to load Quest Bound content', 11 | location: 'useOfficialContent', 12 | }); 13 | 14 | return { 15 | rulesets: data?.officialContent?.rulesets ?? [], 16 | modules: data?.officialContent?.modules ?? [], 17 | loading, 18 | error, 19 | }; 20 | }; 21 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/user/use-sign-out.ts: -------------------------------------------------------------------------------- 1 | import { EnvContext } from "@/libs/compass-web-utils"; 2 | import { useCallback, useContext } from "react"; 3 | import { useCurrentUser } from "./use-current-user"; 4 | 5 | interface UseSignOut { 6 | signOut: () => void; 7 | } 8 | 9 | export const useSignOut = (): UseSignOut => { 10 | const { revokeCurrentUser } = useCurrentUser(); 11 | const { domain } = useContext(EnvContext); 12 | 13 | const signOut = useCallback(async () => { 14 | localStorage.removeItem("last-viewed-ruleset-id"); 15 | revokeCurrentUser(); 16 | window.location.href = domain; 17 | }, []); 18 | 19 | return { 20 | signOut, 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/mutations/characters.ts: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client/core/index.js'; 2 | 3 | export const createCharacter = gql` 4 | mutation CreateCharacter($input: CreateCharacter!) { 5 | createCharacter(input: $input) { 6 | id 7 | name 8 | rulesetId 9 | } 10 | } 11 | `; 12 | 13 | export const deleteCharacter = gql` 14 | mutation DeleteCharacter($id: String!) { 15 | deleteCharacter(id: $id) 16 | } 17 | `; 18 | 19 | export const updateCharacter = gql` 20 | mutation UpdateCharacter($input: UpdateCharacter!) { 21 | updateCharacter(input: $input) { 22 | id 23 | name 24 | attributeData 25 | } 26 | } 27 | `; 28 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/mutations/charts.ts: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client/core/index.js'; 2 | 3 | export const createChart = gql` 4 | mutation CreateChart($input: CreateChart!) { 5 | createChart(input: $input) { 6 | id 7 | rulesetId 8 | title 9 | fileKey 10 | } 11 | } 12 | `; 13 | 14 | export const updateChart = gql` 15 | mutation UpdateChart($input: UpdateChart!) { 16 | updateChart(input: $input) { 17 | id 18 | rulesetId 19 | title 20 | fileKey 21 | } 22 | } 23 | `; 24 | 25 | export const deleteChart = gql` 26 | mutation DeleteChart($input: DeleteEntity!) { 27 | deleteChart(input: $input) 28 | } 29 | `; 30 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/character/delete-character.ts: -------------------------------------------------------------------------------- 1 | import { AuthorizationContext } from '@/infrastructure/types'; 2 | import { DeleteCharacterMutationVariables } from '../../generated-types'; 3 | import { dbClient } from '@/database'; 4 | 5 | export const deleteCharacter = async ( 6 | parent: any, 7 | args: DeleteCharacterMutationVariables, 8 | context: AuthorizationContext, 9 | ) => { 10 | const { userId } = context; 11 | 12 | const { id } = args; 13 | 14 | const db = dbClient(); 15 | 16 | await db.character.delete({ 17 | where: { 18 | id, 19 | userId, 20 | }, 21 | }); 22 | 23 | return `Successfully deleted character ${id}`; 24 | }; 25 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/document/index.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapRulebook } from './bootstrap-rulebook'; 2 | import { createDocument } from './create-document'; 3 | import { deleteBootstrap } from './delete-bootstrap'; 4 | import { deleteDocument } from './delete-document'; 5 | import { document } from './document'; 6 | import { documents } from './documents'; 7 | import { updateDocument } from './update-document'; 8 | 9 | export const documentResolvers = { 10 | Query: { 11 | document, 12 | documents, 13 | }, 14 | Mutation: { 15 | createDocument, 16 | updateDocument, 17 | deleteDocument, 18 | bootstrapRulebook, 19 | deleteBootstrap, 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /server/src/infrastructure/rest/endpoints.ts: -------------------------------------------------------------------------------- 1 | import { Express } from 'express'; 2 | import { initializeEmailEndpoints } from './services/email'; 3 | import { initializeMetricsEndpoints } from './services/metrics'; 4 | import { initializeImportExportEndpoints } from './services/import-export'; 5 | import { initializeSigninEndpoints } from './services/signin'; 6 | import { initializeStorageEndpoints } from './services/storage'; 7 | 8 | export const initializeRestfulEndpoints = (app: Express) => { 9 | initializeEmailEndpoints(app); 10 | initializeMetricsEndpoints(app); 11 | initializeImportExportEndpoints(app); 12 | initializeSigninEndpoints(app); 13 | initializeStorageEndpoints(app); 14 | }; 15 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/image-list/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIImageList, { ImageListProps as MUIImageListProps } from '@mui/material/ImageList'; 2 | import MUIImageListItem, { 3 | ImageListItemProps as MUIImageListItemProps, 4 | } from '@mui/material/ImageListItem'; 5 | 6 | import type { JSX } from "react"; 7 | 8 | export type ImageListProps = MUIImageListProps; 9 | export type ImageListItemProps = MUIImageListItemProps; 10 | 11 | export const ImageList = ({ ...baseProps }: ImageListProps): JSX.Element => ( 12 | 13 | ); 14 | export const ImageListItem = ({ ...baseProps }: ImageListItemProps): JSX.Element => ( 15 | 16 | ); 17 | -------------------------------------------------------------------------------- /client/src/pages/characters/character-journal.tsx: -------------------------------------------------------------------------------- 1 | import { Stack } from '@/libs/compass-core-ui'; 2 | import { useLocation } from 'react-router-dom'; 3 | import { RulebookPage } from '../ruleset/rulebook/components/rulebook-page'; 4 | 5 | interface CharacterJournalProps { 6 | viewMode?: boolean; 7 | } 8 | 9 | export const CharacterJournal = ({ viewMode }: CharacterJournalProps) => { 10 | const { search } = useLocation(); 11 | const queryParams = new URLSearchParams(search); 12 | const pageId = queryParams.get('page'); 13 | 14 | return ( 15 | 16 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240218002305_character_items/migration.sql: -------------------------------------------------------------------------------- 1 | -- AlterTable 2 | ALTER TABLE "Character" ADD COLUMN "itemData" JSONB NOT NULL DEFAULT '[]'; 3 | 4 | -- AlterTable 5 | ALTER TABLE "Item" ADD COLUMN "containerCapacity" INTEGER NOT NULL DEFAULT 100, 6 | ADD COLUMN "containerHeight" INTEGER NOT NULL DEFAULT 20, 7 | ADD COLUMN "containerWidth" INTEGER NOT NULL DEFAULT 20, 8 | ADD COLUMN "height" INTEGER NOT NULL DEFAULT 2, 9 | ADD COLUMN "isContainer" BOOLEAN NOT NULL DEFAULT false, 10 | ADD COLUMN "stackCapacity" INTEGER NOT NULL DEFAULT 1, 11 | ADD COLUMN "weight" INTEGER NOT NULL DEFAULT 0, 12 | ADD COLUMN "width" INTEGER NOT NULL DEFAULT 2; 13 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/hooks/use-filter-changes.ts: -------------------------------------------------------------------------------- 1 | import { Operation, OperationType } from '../types'; 2 | 3 | const operationsWhichShouldNotBeRemoved: OperationType[] = []; 4 | 5 | export const useFilterChanges = (getOperation: (id: string) => Operation | undefined) => { 6 | function filterChanges(changes: Array): any[] { 7 | return changes.filter((change) => { 8 | if (change.type === 'remove') { 9 | const operation = getOperation(change.id); 10 | if (operation && operationsWhichShouldNotBeRemoved.includes(operation?.type)) return false; 11 | } 12 | 13 | return true; 14 | }); 15 | } 16 | 17 | return { 18 | filterChanges, 19 | }; 20 | }; 21 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/assets/qb-q.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /client/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: "@typescript-eslint/parser", 4 | ignorePatterns: ['.eslintrc.js'], 5 | plugins: ["@typescript-eslint"], 6 | extends: [ 7 | "plugin:@typescript-eslint/recommended", 8 | "plugin:prettier/recommended", 9 | "plugin:react/recommended" 10 | ], 11 | rules: { 12 | "no-console": ["error", { "allow": ["warn", "error", "debug"] }], 13 | "@typescript-eslint/no-unused-vars": "error", 14 | "arrow-body-style": "error", 15 | '@typescript-eslint/no-var-requires': 'warn', 16 | "react/no-unknown-property": [0], 17 | "react/prop-types": ["off"] 18 | }, 19 | parserOptions: { 20 | sourceType: "module" 21 | } 22 | } -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/speed-dial/index.tsx: -------------------------------------------------------------------------------- 1 | import MUISpeedDial, { SpeedDialProps as MUISpeedDialProps } from '@mui/material/SpeedDial'; 2 | import MUISpeedDialAction, { 3 | SpeedDialActionProps as MUISpeedDialActionProps, 4 | } from '@mui/material/SpeedDialAction'; 5 | 6 | import type { JSX } from "react"; 7 | 8 | export type SpeedDialProps = MUISpeedDialProps; 9 | export type SpeedDialActionProps = MUISpeedDialActionProps; 10 | 11 | export const SpeedDial = ({ ...baseProps }: SpeedDialProps): JSX.Element => ( 12 | 13 | ); 14 | 15 | export const SpeedDialAction = ({ ...baseProps }: SpeedDialActionProps): JSX.Element => ( 16 | 17 | ); 18 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/utils/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Inserts the child ID in the sorted child ID array. If childIndex is -1, removes the child ID. 3 | * Pass Infinity for index to place new ID at the end. 4 | */ 5 | export function insertPageAt(childIds: string[], newChildId: string, index: number) { 6 | const pageOrder = childIds.filter((id) => id !== newChildId); 7 | 8 | if (index >= 0) { 9 | pageOrder.splice(index, 0, newChildId); 10 | } 11 | 12 | return [...new Set(pageOrder)]; 13 | } 14 | 15 | /** 16 | * Removes __typename from GraphQL response 17 | */ 18 | export function convertRawResponse(raw: Record) { 19 | const copy = { ...raw }; 20 | delete copy.__typename; 21 | return copy as T; 22 | } 23 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/nodes/boolean-comparison-node.tsx: -------------------------------------------------------------------------------- 1 | import { Text } from '@chakra-ui/react'; 2 | import { useContext } from 'react'; 3 | import { useNodeId } from 'reactflow'; 4 | import { NodeWrapper } from '../components'; 5 | import { LogicContext } from '../provider'; 6 | import { operationTypeToLabel } from '../types'; 7 | 8 | export const BooleanComparisonNode = () => { 9 | const { getOperation } = useContext(LogicContext); 10 | const operation = getOperation(useNodeId() ?? ''); 11 | 12 | if (!operation) return null; 13 | 14 | return ( 15 | 16 | {operationTypeToLabel.get(operation.type)} 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/nodes/set-node.tsx: -------------------------------------------------------------------------------- 1 | import { Stack, Text } from '@chakra-ui/react'; 2 | import { useContext } from 'react'; 3 | import { useNodeId } from 'reactflow'; 4 | import { NodeWrapper } from '../components'; 5 | import { LogicContext } from '../provider'; 6 | 7 | export const SetNode = () => { 8 | const { getOperation } = useContext(LogicContext); 9 | const operation = getOperation(useNodeId() ?? ''); 10 | if (!operation) return null; 11 | 12 | return ( 13 | 14 | 15 | Set 16 | 17 | 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240508135008_published_ruleset_properties/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the column `approved` on the `PublishedRuleset` table. All the data in the column will be lost. 5 | 6 | */ 7 | -- AlterTable 8 | ALTER TABLE "PublishedRuleset" DROP COLUMN "approved", 9 | ADD COLUMN "currentPrice" DOUBLE PRECISION NOT NULL DEFAULT 0, 10 | ADD COLUMN "live" BOOLEAN NOT NULL DEFAULT false; 11 | 12 | -- AlterTable 13 | ALTER TABLE "PublishedRulesetPermission" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, 14 | ADD COLUMN "salePrice" DOUBLE PRECISION NOT NULL DEFAULT 0, 15 | ADD COLUMN "tipAmount" DOUBLE PRECISION NOT NULL DEFAULT 0; 16 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/nodes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './action-node'; 2 | export * from './announce-node'; 3 | export * from './attribute-node'; 4 | export * from './boolean-comparison-node'; 5 | export * from './chart-node'; 6 | export * from './comment-node'; 7 | export * from './comparison-node'; 8 | export * from './default-value-node'; 9 | export * from './dice-node'; 10 | export * from './exponent-node'; 11 | export * from './if-node'; 12 | export * from './items'; 13 | export * from './math-operation-node'; 14 | export * from './not-node'; 15 | export * from './primitive-node'; 16 | export * from './return'; 17 | export * from './set-node'; 18 | export * from './side-effect-node'; 19 | export * from './variable-node'; 20 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/button/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIButton, { ButtonProps as MUIButtonProps } from '@mui/material/Button'; 2 | import { Loader } from '../loader'; 3 | 4 | import type { JSX } from "react"; 5 | 6 | export interface ButtonProps extends MUIButtonProps { 7 | loading?: boolean; 8 | target?: string; 9 | } 10 | 11 | export const Button = ({ loading, ...baseProps }: ButtonProps): JSX.Element => ( 12 | 13 | {loading ? ( 14 | 18 | ) : ( 19 | baseProps.children 20 | )} 21 | 22 | ); 23 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/theme/index.ts: -------------------------------------------------------------------------------- 1 | import { Components, createTheme, responsiveFontSizes, Theme } from '@mui/material/styles'; 2 | import { components } from './components'; 3 | import { darkPalette, lightPalette } from './palette'; 4 | import { typography } from './typography'; 5 | 6 | interface CompassTheme extends Theme { 7 | components: Components; 8 | } 9 | 10 | export const compassLightTheme = responsiveFontSizes( 11 | createTheme({ 12 | palette: lightPalette, 13 | typography, 14 | components, 15 | }), 16 | ) as CompassTheme; 17 | 18 | export const compassDarkTheme = responsiveFontSizes( 19 | createTheme({ 20 | palette: darkPalette, 21 | typography, 22 | components, 23 | }), 24 | ) as CompassTheme; 25 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/component/delete-components.ts: -------------------------------------------------------------------------------- 1 | import { AuthorizationContext } from '@/infrastructure/types'; 2 | import { DeleteSheetComponentsMutationVariables } from '../../generated-types'; 3 | import { dbClient } from '@/database'; 4 | 5 | export const deleteSheetComponents = async ( 6 | parent: any, 7 | args: DeleteSheetComponentsMutationVariables, 8 | context: AuthorizationContext, 9 | ) => { 10 | const { input } = args; 11 | 12 | const db = dbClient(); 13 | 14 | await db.sheetComponent.deleteMany({ 15 | where: { 16 | id: { in: input.map((input) => `${input.id}-${input.sheetId}-${input.rulesetId}`) }, 17 | }, 18 | }); 19 | 20 | return `Sheet components deleted successfully.`; 21 | }; 22 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/pages/use-pages.ts: -------------------------------------------------------------------------------- 1 | import { useParams } from 'react-router-dom'; 2 | import { Page, pages, PagesQuery, PagesQueryVariables } from '../../gql'; 3 | import { useQuery } from '../../utils'; 4 | import { useError } from '../metrics'; 5 | 6 | export const usePages = () => { 7 | const { rulesetId } = useParams(); 8 | 9 | const { data, loading, error } = useQuery(pages, { 10 | variables: { 11 | rulesetId: rulesetId ?? '', 12 | }, 13 | skip: !rulesetId, 14 | }); 15 | 16 | useError({ 17 | error, 18 | message: 'Failed to load pages', 19 | }); 20 | 21 | return { 22 | pages: (data?.pages ?? []) as Page[], 23 | loading, 24 | error, 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/mutations/users.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | 3 | /* eslint-disable */ 4 | // this is an auto generated file. This will be overwritten 5 | import { gql } from '@apollo/client/core/index.js'; 6 | 7 | export const updateCurrentUser = gql` 8 | mutation UpdateCurrentUser($input: CurrentUserUpdateInput!) { 9 | updateCurrentUser(input: $input) { 10 | id 11 | username 12 | onboarded 13 | avatarSrc 14 | preferences { 15 | emailShares 16 | emailUpdates 17 | emailUnsubscribe 18 | } 19 | companion { 20 | id 21 | name 22 | description 23 | animal 24 | color 25 | src 26 | model 27 | } 28 | } 29 | } 30 | `; 31 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/types/planes/inventory-component-types.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentTypes, SheetComponentType } from './base-component-types'; 2 | import { DEFAULT_GRID_SIZE, MAX_SIZE } from './defaults'; 3 | 4 | export const inventoryComponentTypes: SheetComponentType[] = [ 5 | { 6 | label: 'Item', 7 | description: 'Item', 8 | type: ComponentTypes.ITEM, 9 | minWidth: DEFAULT_GRID_SIZE, 10 | minHeight: DEFAULT_GRID_SIZE, 11 | defaultWidth: 10 * DEFAULT_GRID_SIZE, 12 | defaultHeight: 10 * DEFAULT_GRID_SIZE, 13 | maxHeight: MAX_SIZE * DEFAULT_GRID_SIZE, 14 | maxWidth: MAX_SIZE * DEFAULT_GRID_SIZE, 15 | defaultRotation: 0, 16 | defaultLayer: 2, 17 | transparent: true, 18 | scalable: true, 19 | }, 20 | ]; 21 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/v2/ui/label.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import * as LabelPrimitive from '@radix-ui/react-label'; 4 | import * as React from 'react'; 5 | 6 | import { cn } from '@/libs/compass-core-ui/utils'; 7 | 8 | function Label({ className, ...props }: React.ComponentProps) { 9 | return ( 10 | 18 | ); 19 | } 20 | 21 | export { Label }; 22 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/attributes/attribute-store/evaluation/evaluation-functions/inventory.ts: -------------------------------------------------------------------------------- 1 | import { ContextualItem } from '@/libs/compass-api'; 2 | import { LogicalValue, Operation } from '@/libs/compass-planes'; 3 | 4 | export const getInventory = ( 5 | operation: Operation, 6 | items: ContextualItem[], 7 | useTestValue: boolean, 8 | ): LogicalValue => { 9 | const weight = items 10 | .map((item) => { 11 | const itemQty = (item.properties.find((property) => property.id === 'quantity')?.value ?? 12 | 0) as number; 13 | return itemQty * item.data.weight; 14 | }) 15 | .reduce((acc, curr) => acc + curr, 0); 16 | 17 | if (useTestValue) return operation.data?.testValue ?? weight ?? ''; 18 | 19 | return weight; 20 | }; 21 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/attribute/utils.ts: -------------------------------------------------------------------------------- 1 | import { Attribute } from '../../generated-types'; 2 | 3 | /** 4 | * Injects the default value into the defaultValue operation 5 | * Filters out any corrupted operations 6 | */ 7 | export function syncAttributeLogic(attribute: any): Attribute { 8 | const injectedAttribute = { 9 | ...attribute, 10 | logic: JSON.stringify( 11 | JSON.parse(attribute.logic) 12 | .filter((op: any) => !!op.id) 13 | .map((op: any) => { 14 | if (op.type !== 'default-value') return op; 15 | return { 16 | ...op, 17 | value: attribute.defaultValue, 18 | }; 19 | }), 20 | ), 21 | }; 22 | 23 | return injectedAttribute; 24 | } 25 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/toggle-button/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIToggleButton, { 2 | ToggleButtonProps as MUIToggleButtonProps, 3 | } from '@mui/material/ToggleButton'; 4 | import MUIToggleButtonGroup, { 5 | ToggleButtonGroupProps as MUIGroupProps, 6 | } from '@mui/material/ToggleButtonGroup'; 7 | 8 | import type { JSX } from "react"; 9 | 10 | export type ToggleButtonProps = MUIToggleButtonProps; 11 | export type ToggleButtonGroupProps = MUIGroupProps; 12 | 13 | export const ToggleButton = ({ ...baseProps }: ToggleButtonProps): JSX.Element => ( 14 | 15 | ); 16 | 17 | export const ToggleButtonGroup = ({ ...baseProps }: ToggleButtonGroupProps): JSX.Element => ( 18 | 19 | ); 20 | -------------------------------------------------------------------------------- /server/.prettierignore: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # FOLDERS 3 | ######################################################################## 4 | 5 | 6 | .github/ 7 | .husky/ 8 | .next/ 9 | .vscode/ 10 | node_modules 11 | build 12 | cdk.out 13 | bin 14 | lib/infrastructure/prisma-layer/dist 15 | lib/infrastructure/prisma-layer/prisma 16 | lib/infrastructure/prisma-layer/node_modules 17 | 18 | ######################################################################## 19 | # FILES 20 | ######################################################################## 21 | *.env* 22 | *.ico 23 | *.jpg 24 | *.png 25 | *.rules 26 | *.svg 27 | *.txt 28 | .eslintignore 29 | .gitignore 30 | .gitkeep 31 | .nvmrc 32 | .npmrc 33 | .prettierignore 34 | .DS_Store 35 | -------------------------------------------------------------------------------- /client/src/libs/compass-planes/logic-editor/nodes/dice-node.tsx: -------------------------------------------------------------------------------- 1 | import { Stack, Text } from '@chakra-ui/react'; 2 | import { Casino } from '@mui/icons-material'; 3 | import { useContext } from 'react'; 4 | import { useNodeId } from 'reactflow'; 5 | import { NodeWrapper } from '../components'; 6 | import { LogicContext } from '../provider'; 7 | 8 | export const DiceNode = () => { 9 | const { getOperation } = useContext(LogicContext); 10 | const operation = getOperation(useNodeId() ?? ''); 11 | 12 | if (!operation) return null; 13 | 14 | return ( 15 | 16 | 17 | 18 | {operation.value} 19 | 20 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/sheets/sheet-attribute-control/animated-update-msg.tsx: -------------------------------------------------------------------------------- 1 | import { motion } from 'framer-motion'; 2 | import React from 'react'; 3 | 4 | export function AnimatedUpdateMsg({ 5 | value, 6 | isDerivedAttribute, 7 | children, 8 | }: { 9 | value: number | string | null; 10 | isDerivedAttribute: boolean; 11 | children: React.ReactNode; 12 | }) { 13 | if (!isDerivedAttribute) { 14 | return <>{children}; 15 | } 16 | 17 | return ( 18 | 24 | {children} 25 | 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/gql/queries/archetypes.ts: -------------------------------------------------------------------------------- 1 | import { gql } from '@apollo/client/core/index.js'; 2 | 3 | export const archetypes = gql` 4 | query Archetypes($rulesetId: String!) { 5 | archetypes(rulesetId: $rulesetId) { 6 | id 7 | rulesetId 8 | moduleId 9 | category 10 | moduleTitle 11 | title 12 | description 13 | image { 14 | id 15 | src 16 | } 17 | } 18 | } 19 | `; 20 | 21 | export const archetype = gql` 22 | query Archetype($input: GetEntity!) { 23 | archetype(input: $input) { 24 | id 25 | rulesetId 26 | moduleId 27 | category 28 | moduleTitle 29 | title 30 | description 31 | image { 32 | id 33 | src 34 | } 35 | } 36 | } 37 | `; 38 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/documents/use-documents.ts: -------------------------------------------------------------------------------- 1 | import { useParams } from 'react-router-dom'; 2 | import { Document, documents, DocumentsQuery, DocumentsQueryVariables } from '../../gql'; 3 | import { useQuery } from '../../utils'; 4 | import { useError } from '../metrics'; 5 | 6 | export const useDocuments = () => { 7 | const { rulesetId } = useParams(); 8 | const { data, loading, error } = useQuery(documents, { 9 | variables: { 10 | rulesetId: rulesetId ?? '', 11 | }, 12 | skip: !rulesetId, 13 | }); 14 | 15 | useError({ 16 | error, 17 | message: 'Failed to load documents', 18 | }); 19 | 20 | return { 21 | documents: (data?.documents ?? []) as Document[], 22 | loading, 23 | error, 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /client/src/libs/compass-api/hooks/rulesets/use-rulesets.ts: -------------------------------------------------------------------------------- 1 | import { Ruleset, rulesets, RulesetsQuery } from '../../gql'; 2 | import { useQuery } from '../../utils'; 3 | import { useError } from '../metrics'; 4 | 5 | export const useRulesets = (pollInterval = 0) => { 6 | const { data, loading, error } = useQuery(rulesets, { 7 | pollInterval, 8 | }); 9 | 10 | useError({ 11 | error, 12 | message: 'Failed to load rulesets', 13 | }); 14 | 15 | const userContent = (data?.rulesets ?? []) as Ruleset[]; 16 | const modules = userContent.filter((ruleset) => ruleset.isModule); 17 | const userRulesets = userContent.filter((ruleset) => !ruleset.isModule); 18 | 19 | return { 20 | rulesets: userRulesets, 21 | modules, 22 | loading, 23 | error, 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/toggle-button/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme, compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/ToggleButton' {} 5 | 6 | const injectTheme = (): void => { 7 | [compassLightTheme, compassDarkTheme].forEach((theme) => { 8 | theme.components.MuiToggleButton = { 9 | variants: [], 10 | styleOverrides: { 11 | root: { 12 | textTransform: 'none', 13 | '&:focus-visible': { 14 | outline: '1px solid', 15 | outlineColor: compassDarkTheme.palette.info.main, 16 | outlineOffset: '2px', 17 | }, 18 | }, 19 | }, 20 | }; 21 | }); 22 | }; 23 | 24 | export default injectTheme; 25 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/image/images.ts: -------------------------------------------------------------------------------- 1 | import { dbClient } from '@/database'; 2 | import { Image } from '@/infrastructure/graphql'; 3 | import { AuthorizationContext, ResolverInput } from '@/infrastructure/types'; 4 | 5 | export const images = async ( 6 | parent: any, 7 | args: ResolverInput, 8 | context: AuthorizationContext, 9 | ) => { 10 | const { userId } = context; 11 | const db = dbClient(); 12 | 13 | const images = await db.user 14 | .findUnique({ 15 | where: { 16 | id: userId, 17 | }, 18 | }) 19 | .images(); 20 | 21 | return (images ?? []) 22 | .filter((img: any) => !img.hidden) 23 | .map((image: any) => ({ 24 | ...image, 25 | details: image.details ? JSON.stringify(image.details) : undefined, 26 | })); 27 | }; 28 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/stepper/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Stepper' {} 5 | declare module '@mui/material/Step' {} 6 | declare module '@mui/material/StepLabel' {} 7 | 8 | const injectTheme = (): void => { 9 | compassLightTheme.components.MuiStepper = { 10 | variants: [], 11 | styleOverrides: { 12 | root: {}, 13 | }, 14 | }; 15 | compassLightTheme.components.MuiStep = { 16 | variants: [], 17 | styleOverrides: { 18 | root: {}, 19 | }, 20 | }; 21 | compassLightTheme.components.MuiStepLabel = { 22 | variants: [], 23 | styleOverrides: { 24 | root: {}, 25 | }, 26 | }; 27 | }; 28 | 29 | export default injectTheme; 30 | -------------------------------------------------------------------------------- /client/src/components/share/publish/not-published.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Stack, Text } from '@chakra-ui/react'; 2 | import { Newspaper } from '@mui/icons-material'; 3 | 4 | export const NotPublished = ({ 5 | onPublish, 6 | loading, 7 | }: { 8 | onPublish: () => void; 9 | loading?: boolean; 10 | }) => { 11 | return ( 12 | 13 | 14 | Publish your content 15 | 16 | Published content may be added to other users' shelves. You may unpublish at any time, but 17 | content on shelves will not be removed. 18 | 19 | 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/switch/index.tsx: -------------------------------------------------------------------------------- 1 | import { FormControl, FormControlLabel } from '@mui/material'; 2 | import MUISwitch, { SwitchProps as MUISwitchProps } from '@mui/material/Switch'; 3 | 4 | import type { JSX } from "react"; 5 | 6 | export type SwitchProps = MUISwitchProps & { 7 | label?: string; 8 | labelPlacement?: 'top' | 'bottom' | 'start' | 'end'; 9 | fullWidth?: boolean; 10 | }; 11 | 12 | export const Switch = ({ 13 | label, 14 | labelPlacement, 15 | fullWidth = false, 16 | ...baseProps 17 | }: SwitchProps): JSX.Element => ( 18 | 19 | } 24 | /> 25 | 26 | ); 27 | -------------------------------------------------------------------------------- /client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "esnext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx", 18 | "baseUrl": "./", 19 | "paths": { 20 | "@/*": ["src/*"], 21 | }, 22 | "maxNodeModuleJsDepth": 0 23 | }, 24 | "include": ["src", "./custom.d.ts"], 25 | "exclude": ["node_modules"], 26 | "references": [{ "path": "./tsconfig.node.json" }] 27 | } 28 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240506160659_character_created_from_pub/migration.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Warnings: 3 | 4 | - You are about to drop the `_CharacterArchetypes` table. If the table is not empty, all the data it contains will be lost. 5 | 6 | */ 7 | -- DropForeignKey 8 | ALTER TABLE "Character" DROP CONSTRAINT "Character_rulesetId_fkey"; 9 | 10 | -- DropForeignKey 11 | ALTER TABLE "_CharacterArchetypes" DROP CONSTRAINT "_CharacterArchetypes_A_fkey"; 12 | 13 | -- DropForeignKey 14 | ALTER TABLE "_CharacterArchetypes" DROP CONSTRAINT "_CharacterArchetypes_B_fkey"; 15 | 16 | -- AlterTable 17 | ALTER TABLE "Character" ADD COLUMN "archetypeIds" JSONB NOT NULL DEFAULT '[]', 18 | ADD COLUMN "createdFromPublishedRuleset" BOOLEAN NOT NULL DEFAULT false; 19 | 20 | -- DropTable 21 | DROP TABLE "_CharacterArchetypes"; 22 | -------------------------------------------------------------------------------- /client/src/libs/compass-web-journal/components/editor.css: -------------------------------------------------------------------------------- 1 | .DraftEditor-root { 2 | height: 100% !important; 3 | width: 100%; 4 | } 5 | 6 | .DraftEditor-root figure { 7 | margin: 0; 8 | } 9 | 10 | .text-align-left > .public-DraftStyleDefault-block { 11 | text-align: left; 12 | } 13 | 14 | .text-align-center > .public-DraftStyleDefault-block { 15 | text-align: center; 16 | } 17 | 18 | .text-align-right > .public-DraftStyleDefault-block { 19 | text-align: right; 20 | } 21 | 22 | .blockquote > .public-DraftStyleDefault-block { 23 | padding: 0.5rem 0.75rem; 24 | border-left: 4px solid rgba(125, 125, 125, 0.5); 25 | } 26 | 27 | 28 | .DraftEditor-editorContainer .journal-link { 29 | text-decoration: underline; 30 | color: inherit; 31 | } 32 | 33 | .DraftEditor-editorContainer .journal-link:hover { 34 | cursor: pointer 35 | } -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/page/create-page.ts: -------------------------------------------------------------------------------- 1 | import { AuthorizationContext } from '@/infrastructure/types'; 2 | import { CreatePageMutationVariables } from '../../generated-types'; 3 | import { convertEntityId, createPageUtil } from '../_shared'; 4 | import { dbClient } from '@/database'; 5 | 6 | export const createPage = async ( 7 | parent: any, 8 | args: CreatePageMutationVariables, 9 | context: AuthorizationContext, 10 | ) => { 11 | const { input } = args; 12 | const { toEntity } = convertEntityId(input.rulesetId); 13 | 14 | const db = dbClient(); 15 | 16 | const { page, sheet } = await createPageUtil({ db, input }); 17 | 18 | return { 19 | ...page, 20 | id: page.entityId, 21 | parentId: page.parentId ? toEntity(page.parentId) : undefined, 22 | sheetId: sheet.entityId, 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-composites/composites/sheets/sheet-attribute-control/text-attribute-node.tsx: -------------------------------------------------------------------------------- 1 | import { Stack, Tooltip } from '@chakra-ui/react'; 2 | 3 | interface Props { 4 | renderedAttributeValue: string | number | null; 5 | alwaysShowSign?: boolean; 6 | attributeDescription?: string; 7 | } 8 | 9 | export const TextAttributeNode = ({ 10 | alwaysShowSign, 11 | renderedAttributeValue, 12 | attributeDescription, 13 | }: Props) => { 14 | const numberIsPositive = parseFloat(`${renderedAttributeValue}`) >= 0; 15 | 16 | return ( 17 | 18 | 19 | {alwaysShowSign && numberIsPositive && +} 20 | {renderedAttributeValue} 21 | 22 | 23 | ); 24 | }; 25 | -------------------------------------------------------------------------------- /client/src/pages/settings/settings-button.tsx: -------------------------------------------------------------------------------- 1 | import { IconButton, Tooltip } from '@/libs/compass-core-ui'; 2 | import { SettingsContext } from '@/libs/compass-web-utils'; 3 | import { Settings } from '@mui/icons-material'; 4 | import { useContext } from 'react'; 5 | 6 | interface Props { 7 | defaultPage?: string; 8 | } 9 | 10 | export const SettingsButton = ({ defaultPage }: Props) => { 11 | const { openSettingsModal, setSettingsPage } = useContext(SettingsContext); 12 | 13 | const handleOpen = () => { 14 | if (defaultPage) { 15 | setSettingsPage(defaultPage); 16 | } 17 | 18 | openSettingsModal(true); 19 | }; 20 | 21 | return ( 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug, enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /client/src/components/error-boundary.tsx: -------------------------------------------------------------------------------- 1 | import { ErrorPage } from '@/libs/compass-core-ui'; 2 | import { ReactNode } from 'react'; 3 | import { ErrorBoundary as ReactErrorBoundary } from 'react-error-boundary'; 4 | 5 | interface ErrorBoundaryProps { 6 | children: ReactNode; 7 | } 8 | 9 | export const ErrorBoundary = ({ children }: ErrorBoundaryProps) => { 10 | const Fallback = ( 11 |
22 | 23 |
24 | ); 25 | 26 | return {children}; 27 | }; 28 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/checkbox/theme.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-empty-interface */ 2 | import { compassDarkTheme, compassLightTheme } from '../../theme'; 3 | 4 | declare module '@mui/material/Checkbox' {} 5 | 6 | const injectTheme = (): void => { 7 | [compassLightTheme, compassDarkTheme].forEach((theme) => { 8 | theme.components.MuiCheckbox = { 9 | variants: [], 10 | styleOverrides: { 11 | root: { 12 | '&.Mui-checked': { 13 | color: theme.palette.secondary.main, 14 | }, 15 | '&.Mui-focusVisible': { 16 | outline: '1px solid', 17 | outlineColor: compassDarkTheme.palette.info.main, 18 | outlineOffset: '2px', 19 | }, 20 | }, 21 | }, 22 | }; 23 | }); 24 | }; 25 | 26 | export default injectTheme; 27 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/composites/form/radio.tsx: -------------------------------------------------------------------------------- 1 | import { FormControlLabel, Radio, RadioProps } from '@mui/material'; 2 | import { useContext } from 'react'; 3 | import { FormContext } from './form'; 4 | 5 | interface FormRadioProps extends Partial { 6 | /** 7 | * Used to match input to formik values. 8 | */ 9 | id?: string; 10 | 11 | /** 12 | * Optionally renders a label 13 | */ 14 | label: string; 15 | } 16 | 17 | export const FormRadio = ({ label, id, ...others }: FormRadioProps) => { 18 | const { formDisabled } = useContext(FormContext); 19 | const genId = id ?? label.toLowerCase().replace(' ', '-'); 20 | 21 | return ( 22 | } 26 | /> 27 | ); 28 | }; 29 | -------------------------------------------------------------------------------- /server/src/infrastructure/graphql/services/pubsub.ts: -------------------------------------------------------------------------------- 1 | import { RedisPubSub } from 'graphql-redis-subscriptions'; 2 | import { Redis, RedisOptions } from 'ioredis'; 3 | 4 | const REDIS_URL = process.env.REDIS_URL || 'localhost'; 5 | const REDIS_PORT = process.env.REDIS_PORT || '6379'; 6 | const REDIS_USER = process.env.REDIS_USER || 'default'; 7 | const REDIS_PASSWORD = process.env.REDIS_PASSWORD; 8 | 9 | const options: RedisOptions = { 10 | host: REDIS_URL, 11 | port: parseInt(REDIS_PORT), 12 | username: REDIS_USER, 13 | password: REDIS_PASSWORD, 14 | retryStrategy: (times) => { 15 | // reconnect after 16 | return Math.min(times * 50, 2000); 17 | }, 18 | }; 19 | 20 | const sub = new Redis(options); 21 | const pub = new Redis(options); 22 | 23 | export const pubsub = new RedisPubSub({ 24 | publisher: pub, 25 | subscriber: sub, 26 | }); 27 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/components/stepper/index.tsx: -------------------------------------------------------------------------------- 1 | import MUIStep, { StepProps as MUIStepProps } from '@mui/material/Step'; 2 | import MUIStepLabel, { StepLabelProps as MUIStepLabelProps } from '@mui/material/StepLabel'; 3 | import MUIStepper, { StepperProps as MUIStepperProps } from '@mui/material/Stepper'; 4 | 5 | import type { JSX } from "react"; 6 | 7 | export type StepperProps = MUIStepperProps; 8 | export type StepProps = MUIStepProps; 9 | export type StepLabelProps = MUIStepLabelProps; 10 | 11 | export const Stepper = ({ ...baseProps }: StepperProps): JSX.Element => ( 12 | 13 | ); 14 | 15 | export const Step = ({ ...baseProps }: StepProps): JSX.Element => ; 16 | 17 | export const StepLabel = ({ ...baseProps }: StepLabelProps): JSX.Element => ( 18 | 19 | ); 20 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/v2/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | import * as ProgressPrimitive from '@radix-ui/react-progress'; 2 | import * as React from 'react'; 3 | 4 | import { cn } from '@/libs/compass-core-ui/utils'; 5 | 6 | function Progress({ 7 | className, 8 | value, 9 | ...props 10 | }: React.ComponentProps) { 11 | return ( 12 | 16 | 21 | 22 | ); 23 | } 24 | 25 | export { Progress }; 26 | -------------------------------------------------------------------------------- /client/src/pages/ruleset/charts/utils.ts: -------------------------------------------------------------------------------- 1 | import { GridColumn } from '@/libs/compass-core-composites'; 2 | import { generateId } from '@/libs/compass-web-utils'; 3 | 4 | interface IGenericGridRow {} 5 | 6 | export const getHeaderRow = (rows: string[], editable = true): GridColumn[] => { 7 | return rows.map((row) => ({ 8 | field: row, 9 | headerName: row, 10 | width: 150, 11 | editable, 12 | filter: true, 13 | })); 14 | }; 15 | 16 | export const buildRows = (rows: string[][], headerRow: string[]) => { 17 | return !rows.length 18 | ? [] 19 | : rows.slice(1).map((valueArray) => { 20 | const row: any = {}; 21 | 22 | valueArray.forEach((value, index) => { 23 | row[headerRow[index]] = value; 24 | }); 25 | 26 | row._id = generateId(); 27 | 28 | return row; 29 | }); 30 | }; 31 | -------------------------------------------------------------------------------- /server/src/database/prisma/migrations/20240214155718_items/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "Item" ( 3 | "id" TEXT NOT NULL, 4 | "entityId" TEXT NOT NULL, 5 | "rulesetId" TEXT NOT NULL, 6 | "moduleId" TEXT, 7 | "moduleTitle" TEXT, 8 | "title" TEXT NOT NULL, 9 | "description" TEXT, 10 | "imageId" TEXT, 11 | "logic" JSONB NOT NULL DEFAULT '[]', 12 | "category" TEXT, 13 | "details" JSONB NOT NULL DEFAULT '{}', 14 | 15 | CONSTRAINT "Item_pkey" PRIMARY KEY ("id") 16 | ); 17 | 18 | -- AddForeignKey 19 | ALTER TABLE "Item" ADD CONSTRAINT "Item_rulesetId_fkey" FOREIGN KEY ("rulesetId") REFERENCES "Ruleset"("id") ON DELETE CASCADE ON UPDATE CASCADE; 20 | 21 | -- AddForeignKey 22 | ALTER TABLE "Item" ADD CONSTRAINT "Item_imageId_fkey" FOREIGN KEY ("imageId") REFERENCES "Image"("id") ON DELETE SET NULL ON UPDATE CASCADE; 23 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/v2/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import * as SeparatorPrimitive from '@radix-ui/react-separator'; 4 | import * as React from 'react'; 5 | 6 | import { cn } from '@/libs/compass-core-ui/utils'; 7 | 8 | function Separator({ 9 | className, 10 | orientation = 'horizontal', 11 | decorative = true, 12 | ...props 13 | }: React.ComponentProps) { 14 | return ( 15 | 25 | ); 26 | } 27 | 28 | export { Separator }; 29 | -------------------------------------------------------------------------------- /server/.env: -------------------------------------------------------------------------------- 1 | # .env and ./server/.env should be identical 2 | 3 | # Optionally change these to use whatever DB name and password you'd like 4 | DATABASE_NAME=qbdb 5 | DATABASE_PASSWORD=password 6 | ############################################### 7 | 8 | # These should not be changed 9 | MODE=local 10 | PORT=8000 11 | DATABASE_PORT=5432 12 | DATABASE_HOST=localhost 13 | REDIS_URL=localhost 14 | ############################################### 15 | 16 | # If you changed the DATABASE_NAME or DATABASE_PASSWORD, you must update these 17 | # The DATABASE_NAME should match the string following :5432/ in DATABASE_URL and :6543/ in DIRECT_URL 18 | # The DATABASE_PASSWORD should follow 'postgres:' 19 | DATABASE_URL="postgres://postgres:password@localhost:5432/qbdb?pgbouncer=true" 20 | DIRECT_URL="postgres://postgres:password@localhost:5432/qbdb" 21 | ############################################### 22 | -------------------------------------------------------------------------------- /client/src/libs/compass-core-ui/v2/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { cn } from '@/libs/compass-core-ui/utils'; 4 | 5 | function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) { 6 | return ( 7 |