From 543bd5acf7a6192fd464a84043497193bb5297f4 Mon Sep 17 00:00:00 2001 From: coolbot <76798835+coolbot100s@users.noreply.github.com> Date: Mon, 22 Dec 2025 15:37:44 -0800 Subject: [PATCH] Coolbot/moderation updates for versions changes (#4942) * update reports message to the correct support bubble color * update checklist to direct to new settings pages and use v3 env info * fix: project v2 + v3 in moderation checklist funcs * Split environment stage if project uses mixed environments. --------- Co-authored-by: Calum H. (IMB11) --- .../checklist/ModerationChecklist.vue | 93 +++++++++++-------- apps/frontend/src/pages/[type]/[id].vue | 1 - packages/moderation/src/data/checklist.ts | 6 +- .../environment/environment-multiple.md | 2 + .../environment.md} | 2 + .../data/messages/environment/inaccurate.md | 6 ++ .../src/data/messages/gallery/insufficient.md | 2 +- .../src/data/messages/gallery/not-relevant.md | 2 +- .../data/messages/reports/platform-issue.md | 2 +- .../messages/side-types/inaccurate-mod.md | 5 - .../messages/side-types/inaccurate-modpack.md | 5 - .../src/data/modpack-permissions-stage.ts | 5 +- packages/moderation/src/data/nags/tags.ts | 8 +- .../environment/environment-multiple.ts | 29 ++++++ .../data/stages/environment/environment.ts | 29 ++++++ .../moderation/src/data/stages/side-types.ts | 38 -------- .../moderation/src/data/stages/title-slug.ts | 4 +- packages/moderation/src/types/actions.ts | 8 +- packages/moderation/src/types/keybinds.ts | 4 +- packages/moderation/src/types/nags.ts | 5 +- packages/moderation/src/types/reports.ts | 5 +- packages/moderation/src/types/stage.ts | 12 ++- packages/moderation/src/utils.ts | 83 ++++++++++++----- 23 files changed, 216 insertions(+), 140 deletions(-) create mode 100644 packages/moderation/src/data/messages/checklist-text/environment/environment-multiple.md rename packages/moderation/src/data/messages/checklist-text/{side_types.md => environment/environment.md} (61%) create mode 100644 packages/moderation/src/data/messages/environment/inaccurate.md delete mode 100644 packages/moderation/src/data/messages/side-types/inaccurate-mod.md delete mode 100644 packages/moderation/src/data/messages/side-types/inaccurate-modpack.md create mode 100644 packages/moderation/src/data/stages/environment/environment-multiple.ts create mode 100644 packages/moderation/src/data/stages/environment/environment.ts delete mode 100644 packages/moderation/src/data/stages/side-types.ts diff --git a/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue b/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue index 6d8135de..d3dece98 100644 --- a/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue +++ b/apps/frontend/src/components/ui/moderation/checklist/ModerationChecklist.vue @@ -84,8 +84,8 @@
@@ -282,7 +282,7 @@ - @@ -360,7 +360,9 @@ import { expandVariables, finalPermissionMessages, findMatchingVariant, + flattenProjectV3Variables, flattenProjectVariables, + flattenStaticVariables, getActionIdForStage, getActionMessage, getVisibleInputs, @@ -380,6 +382,7 @@ import { Collapsible, DropdownSelect, injectNotificationManager, + injectProjectPageContext, MarkdownEditor, OverflowMenu, type OverflowMenuOption, @@ -387,7 +390,6 @@ import { import { type ModerationJudgements, type ModerationModpackItem, - type Project, type ProjectStatus, renderHighlightedString, } from '@modrinth/utils' @@ -404,14 +406,19 @@ const { addNotification } = notifications const keybindsModal = ref>() const props = defineProps<{ - project: Project collapsed: boolean }>() +const { projectV2, projectV3 } = injectProjectPageContext() + const moderationStore = useModerationStore() const variables = computed(() => { - return flattenProjectVariables(props.project) + return { + ...flattenStaticVariables(), + ...flattenProjectVariables(projectV2.value), + ...flattenProjectV3Variables(projectV3.value), + } }) const modpackPermissionsComplete = ref(false) @@ -445,12 +452,12 @@ function resetProgress() { message.value = '' loadingMessage.value = false - localStorage.removeItem(`modpack-permissions-${props.project.id}`) - localStorage.removeItem(`modpack-permissions-index-${props.project.id}`) + localStorage.removeItem(`modpack-permissions-${projectV2.value.id}`) + localStorage.removeItem(`modpack-permissions-index-${projectV2.value.id}`) - sessionStorage.removeItem(`modpack-permissions-data-${props.project.id}`) - sessionStorage.removeItem(`modpack-permissions-permanent-no-${props.project.id}`) - sessionStorage.removeItem(`modpack-permissions-updated-${props.project.id}`) + sessionStorage.removeItem(`modpack-permissions-data-${projectV2.value.id}`) + sessionStorage.removeItem(`modpack-permissions-permanent-no-${projectV2.value.id}`) + sessionStorage.removeItem(`modpack-permissions-updated-${projectV2.value.id}`) modpackPermissionsComplete.value = false modpackJudgements.value = {} @@ -468,7 +475,7 @@ function findFirstValidStage(): number { } const currentStageObj = computed(() => checklist[currentStage.value]) -const currentStage = useLocalStorage(`moderation-stage-${props.project.slug}`, () => +const currentStage = useLocalStorage(`moderation-stage-${projectV2.value.slug}`, () => findFirstValidStage(), ) @@ -477,7 +484,12 @@ const stageTextExpanded = computedAsync(async () => { const stage = checklist[stageIndex] if (stage.text) { return renderHighlightedString( - expandVariables(await stage.text(props.project), props.project, variables.value), + expandVariables( + await stage.text(projectV2.value, projectV3.value), + projectV2.value, + projectV3.value, + variables.value, + ), ) } return null @@ -489,7 +501,7 @@ interface ActionState { } const persistedActionStates = useLocalStorage( - `moderation-actions-${props.project.slug}`, + `moderation-actions-${projectV2.value.slug}`, {}, { serializer: { @@ -502,7 +514,7 @@ const persistedActionStates = useLocalStorage( const router = useRouter() const persistedTextInputs = useLocalStorage( - `moderation-inputs-${props.project.slug}`, + `moderation-inputs-${projectV2.value.slug}`, {} as Record, ) @@ -530,7 +542,7 @@ function handleKeybinds(event: KeyboardEvent) { handleKeybind( event, { - project: props.project, + project: projectV2.value, state: { currentStage: currentStage.value, totalStages: checklist.length, @@ -562,7 +574,7 @@ function handleKeybinds(event: KeyboardEvent) { tryResetProgress: resetProgress, tryExitModeration: () => emit('exit'), - tryApprove: () => sendMessage(props.project.requested_status), + tryApprove: () => sendMessage(projectV2.value.requested_status ?? 'approved'), tryReject: () => sendMessage('rejected'), tryWithhold: () => sendMessage('withheld'), tryEditMessage: goBackToStages, @@ -656,7 +668,7 @@ watch( (newIndex) => { const stage = checklist[newIndex] if (stage?.navigate) { - router.push(`/${props.project.project_type}/${props.project.slug}${stage.navigate}`) + router.push(`/${projectV2.value.project_type}/${projectV2.value.slug}${stage.navigate}`) } initializeCurrentStage() @@ -858,11 +870,11 @@ function getModpackFilesFromStorage(): { permanentNo: ModerationModpackItem[] } { try { - const sessionData = sessionStorage.getItem(`modpack-permissions-data-${props.project.id}`) + const sessionData = sessionStorage.getItem(`modpack-permissions-data-${projectV2.value.id}`) const interactive = sessionData ? (JSON.parse(sessionData) as ModerationModpackItem[]) : [] const permanentNoData = sessionStorage.getItem( - `modpack-permissions-permanent-no-${props.project.id}`, + `modpack-permissions-permanent-no-${projectV2.value.id}`, ) const permanentNo = permanentNoData ? (JSON.parse(permanentNoData) as ModerationModpackItem[]) @@ -894,7 +906,8 @@ async function assembleFullMessage() { .map((part) => part.content) .filter((content) => content.trim().length > 0) .join('\n\n'), - props.project, + projectV2.value, + projectV3.value, ) return finalMessage @@ -1048,7 +1061,7 @@ function shouldShowStage(stage: Stage): boolean { } if (typeof stage.shouldShow === 'function') { - return stage.shouldShow(props.project) + return stage.shouldShow(projectV2.value, projectV3.value) } return true @@ -1056,7 +1069,7 @@ function shouldShowStage(stage: Stage): boolean { function shouldShowAction(action: Action): boolean { if (typeof action.shouldShow === 'function') { - return action.shouldShow(props.project) + return action.shouldShow(projectV2.value) } return true @@ -1065,7 +1078,7 @@ function shouldShowAction(action: Action): boolean { function getVisibleDropdownOptions(action: DropdownAction) { return action.options.filter((option) => { if (typeof option.shouldShow === 'function') { - return option.shouldShow(props.project) + return option.shouldShow(projectV2.value) } return true }) @@ -1074,7 +1087,7 @@ function getVisibleDropdownOptions(action: DropdownAction) { function getVisibleMultiSelectOptions(action: MultiSelectChipsAction) { return action.options.filter((option) => { if (typeof option.shouldShow === 'function') { - return option.shouldShow(props.project) + return option.shouldShow(projectV2.value) } return true }) @@ -1141,13 +1154,13 @@ async function generateMessage() { loadingMessage.value = true - router.push(`/${props.project.project_type}/${props.project.slug}/moderation`) + router.push(`/${projectV2.value.project_type}/${projectV2.value.slug}/moderation`) try { const baseMessage = await assembleFullMessage() let fullMessage = baseMessage - if (props.project.project_type === 'modpack') { + if (projectV2.value.project_type === 'modpack') { const modpackFilesData = getModpackFilesFromStorage() if (modpackFilesData.interactive.length > 0 || modpackFilesData.permanentNo.length > 0) { @@ -1239,7 +1252,7 @@ function generateModpackMessage(allFiles: { const hasNextProject = ref(false) async function sendMessage(status: ProjectStatus) { try { - await useBaseFetch(`project/${props.project.id}`, { + await useBaseFetch(`project/${projectV2.value.id}`, { method: 'PATCH', body: { status, @@ -1247,7 +1260,7 @@ async function sendMessage(status: ProjectStatus) { }) if (message.value) { - await useBaseFetch(`thread/${props.project.thread_id}`, { + await useBaseFetch(`thread/${projectV2.value.thread_id}`, { method: 'POST', body: { body: { @@ -1259,7 +1272,7 @@ async function sendMessage(status: ProjectStatus) { } if ( - props.project.project_type === 'modpack' && + projectV2.value.project_type === 'modpack' && Object.keys(modpackJudgements.value).length > 0 ) { await useBaseFetch(`moderation/project`, { @@ -1272,7 +1285,7 @@ async function sendMessage(status: ProjectStatus) { done.value = true hasNextProject.value = await moderationStore.completeCurrentProject( - props.project.id, + projectV2.value.id, 'completed', ) } catch (error) { @@ -1326,21 +1339,21 @@ async function endChecklist(status?: string) { } async function skipCurrentProject() { - hasNextProject.value = await moderationStore.completeCurrentProject(props.project.id, 'skipped') + hasNextProject.value = await moderationStore.completeCurrentProject(projectV2.value.id, 'skipped') await endChecklist('skipped') } function clearProjectLocalStorage() { - localStorage.removeItem(`modpack-permissions-${props.project.id}`) - localStorage.removeItem(`modpack-permissions-index-${props.project.id}`) - localStorage.removeItem(`moderation-actions-${props.project.slug}`) - localStorage.removeItem(`moderation-inputs-${props.project.slug}`) - localStorage.removeItem(`moderation-stage-${props.project.slug}`) + localStorage.removeItem(`modpack-permissions-${projectV2.value.id}`) + localStorage.removeItem(`modpack-permissions-index-${projectV2.value.id}`) + localStorage.removeItem(`moderation-actions-${projectV2.value.slug}`) + localStorage.removeItem(`moderation-inputs-${projectV2.value.slug}`) + localStorage.removeItem(`moderation-stage-${projectV2.value.slug}`) - sessionStorage.removeItem(`modpack-permissions-data-${props.project.id}`) - sessionStorage.removeItem(`modpack-permissions-permanent-no-${props.project.id}`) - sessionStorage.removeItem(`modpack-permissions-updated-${props.project.id}`) + sessionStorage.removeItem(`modpack-permissions-data-${projectV2.value.id}`) + sessionStorage.removeItem(`modpack-permissions-permanent-no-${projectV2.value.id}`) + sessionStorage.removeItem(`modpack-permissions-updated-${projectV2.value.id}`) actionStates.value = {} } diff --git a/apps/frontend/src/pages/[type]/[id].vue b/apps/frontend/src/pages/[type]/[id].vue index ec395089..ebda1791 100644 --- a/apps/frontend/src/pages/[type]/[id].vue +++ b/apps/frontend/src/pages/[type]/[id].vue @@ -930,7 +930,6 @@ class="moderation-checklist" > project.project_type === 'modpack', + shouldShow: (project: Labrinth.Projects.v2.Project) => project.project_type === 'modpack', actions: [ { id: 'button', diff --git a/packages/moderation/src/data/nags/tags.ts b/packages/moderation/src/data/nags/tags.ts index 9931da62..a2ad0196 100644 --- a/packages/moderation/src/data/nags/tags.ts +++ b/packages/moderation/src/data/nags/tags.ts @@ -1,4 +1,4 @@ -import type { Project } from '@modrinth/utils' +import type { Labrinth } from '@modrinth/api-client' import { defineMessage, useVIntl } from '@vintl/vintl' import type { Nag, NagContext } from '../../types/nags' @@ -8,7 +8,7 @@ const allResolutionTags = ['8x-', '16x', '32x', '48x', '64x', '128x', '256x', '5 const MAX_TAG_COUNT = 8 function getCategories( - project: Project & { actualProjectType: string }, + project: Labrinth.Projects.v2.Project & { actualProjectType: string }, tags: { categories?: { project_type: string @@ -120,7 +120,7 @@ export const tagsNags: Nag[] = [ description: (context: NagContext) => { const { formatMessage } = useVIntl() const categoriesForProjectType = getCategories( - context.project as Project & { actualProjectType: string }, + context.project as Labrinth.Projects.v2.Project & { actualProjectType: string }, context.tags, ) const totalAvailableTags = categoriesForProjectType.length @@ -139,7 +139,7 @@ export const tagsNags: Nag[] = [ status: 'required', shouldShow: (context: NagContext) => { const categoriesForProjectType = getCategories( - context.project as Project & { actualProjectType: string }, + context.project as Labrinth.Projects.v2.Project & { actualProjectType: string }, context.tags, ) const totalSelectedTags = diff --git a/packages/moderation/src/data/stages/environment/environment-multiple.ts b/packages/moderation/src/data/stages/environment/environment-multiple.ts new file mode 100644 index 00000000..357ed9e8 --- /dev/null +++ b/packages/moderation/src/data/stages/environment/environment-multiple.ts @@ -0,0 +1,29 @@ +import { GlobeIcon } from '@modrinth/assets' + +import type { ButtonAction } from '../../../types/actions' +import type { Stage } from '../../../types/stage' + +const environmentMultiple: Stage = { + title: "Is the project's environment information accurate?", + id: 'environment', + navigate: '/settings/versions', + icon: GlobeIcon, + guidance_url: 'https://modrinth.com/legal/rules#miscellaneous', + text: async () => + (await import('../../messages/checklist-text/environment/environment-multiple.md?raw')).default, + shouldShow: (project, projectV3) => (projectV3?.environment?.length ?? 0) !== 1, + actions: [ + { + id: 'side_types_inaccurate', + type: 'button', + label: 'Inaccurate', + weight: 800, + suggestedStatus: 'flagged', + severity: 'low', + shouldShow: (project) => project.project_type === 'mod' || project.project_type === 'modpack', + message: async () => (await import('../../messages/environment/inaccurate.md?raw')).default, + } as ButtonAction, + ], +} + +export default environmentMultiple diff --git a/packages/moderation/src/data/stages/environment/environment.ts b/packages/moderation/src/data/stages/environment/environment.ts new file mode 100644 index 00000000..d2a51e97 --- /dev/null +++ b/packages/moderation/src/data/stages/environment/environment.ts @@ -0,0 +1,29 @@ +import { GlobeIcon } from '@modrinth/assets' + +import type { ButtonAction } from '../../../types/actions' +import type { Stage } from '../../../types/stage' + +const environment: Stage = { + title: "Is the project's environment information accurate?", + id: 'environment', + navigate: '/settings/environment', + icon: GlobeIcon, + guidance_url: 'https://modrinth.com/legal/rules#miscellaneous', + text: async () => + (await import('../../messages/checklist-text/environment/environment.md?raw')).default, + shouldShow: (project, projectV3) => (projectV3?.environment?.length ?? 0) === 1, + actions: [ + { + id: 'side_types_inaccurate', + type: 'button', + label: 'Inaccurate', + weight: 800, + suggestedStatus: 'flagged', + severity: 'low', + shouldShow: (project) => project.project_type === 'mod' || project.project_type === 'modpack', + message: async () => (await import('../../messages/environment/inaccurate.md?raw')).default, + } as ButtonAction, + ], +} + +export default environment diff --git a/packages/moderation/src/data/stages/side-types.ts b/packages/moderation/src/data/stages/side-types.ts deleted file mode 100644 index 8d43b804..00000000 --- a/packages/moderation/src/data/stages/side-types.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { GlobeIcon } from '@modrinth/assets' - -import type { ButtonAction } from '../../types/actions' -import type { Stage } from '../../types/stage' - -const sideTypes: Stage = { - title: "Is the project's environment information accurate?", - id: 'environment', - icon: GlobeIcon, - guidance_url: 'https://modrinth.com/legal/rules#miscellaneous', - navigate: '/settings/environment', - text: async () => (await import('../messages/checklist-text/side_types.md?raw')).default, - actions: [ - { - id: 'side_types_inaccurate_modpack', - type: 'button', - label: 'Inaccurate', - weight: 800, - suggestedStatus: 'flagged', - severity: 'low', - shouldShow: (project) => project.project_type === 'modpack', - message: async () => - (await import('../messages/side-types/inaccurate-modpack.md?raw')).default, - } as ButtonAction, - { - id: 'side_types_inaccurate_mod', - type: 'button', - label: 'Inaccurate', - weight: 800, - suggestedStatus: 'flagged', - severity: 'low', - shouldShow: (project) => project.project_type === 'mod', - message: async () => (await import('../messages/side-types/inaccurate-mod.md?raw')).default, - } as ButtonAction, - ], -} - -export default sideTypes diff --git a/packages/moderation/src/data/stages/title-slug.ts b/packages/moderation/src/data/stages/title-slug.ts index a90b2eeb..b2a4215d 100644 --- a/packages/moderation/src/data/stages/title-slug.ts +++ b/packages/moderation/src/data/stages/title-slug.ts @@ -1,9 +1,9 @@ +import type { Labrinth } from '@modrinth/api-client' import { BookOpenIcon } from '@modrinth/assets' -import type { Project } from '@modrinth/utils' import type { Stage } from '../../types/stage' -function hasCustomSlug(project: Project): boolean { +function hasCustomSlug(project: Labrinth.Projects.v2.Project): boolean { return ( project.slug !== project.title diff --git a/packages/moderation/src/types/actions.ts b/packages/moderation/src/types/actions.ts index 337b7f2e..e6174116 100644 --- a/packages/moderation/src/types/actions.ts +++ b/packages/moderation/src/types/actions.ts @@ -1,4 +1,4 @@ -import type { Project } from '@modrinth/utils' +import type { Labrinth } from '@modrinth/api-client' import type { WeightedMessage } from './messages' @@ -60,7 +60,7 @@ export interface BaseAction { * * By default, it returns `true`, meaning the action is always shown. */ - shouldShow?: (project: Project) => boolean + shouldShow?: (project: Labrinth.Projects.v2.Project) => boolean } /** @@ -165,7 +165,7 @@ export interface DropdownActionOption extends WeightedMessage { * * By default, it returns `true`, meaning the option is always shown. */ - shouldShow?: (project: Project) => boolean + shouldShow?: (project: Labrinth.Projects.v2.Project) => boolean } export interface DropdownAction extends BaseAction { @@ -198,7 +198,7 @@ export interface MultiSelectChipsOption extends WeightedMessage { * * By default, it returns `true`, meaning the option is always shown. */ - shouldShow?: (project: Project) => boolean + shouldShow?: (project: Labrinth.Projects.v2.Project) => boolean } export interface MultiSelectChipsAction extends BaseAction { diff --git a/packages/moderation/src/types/keybinds.ts b/packages/moderation/src/types/keybinds.ts index 8bd77fb4..a5524b39 100644 --- a/packages/moderation/src/types/keybinds.ts +++ b/packages/moderation/src/types/keybinds.ts @@ -1,4 +1,4 @@ -import type { Project } from '@modrinth/utils' +import type { Labrinth } from '@modrinth/api-client' export interface ModerationActions { tryGoNext: () => void @@ -44,7 +44,7 @@ export interface ModerationState { } export interface ModerationContext { - project: Project + project: Labrinth.Projects.v2.Project state: ModerationState actions: ModerationActions } diff --git a/packages/moderation/src/types/nags.ts b/packages/moderation/src/types/nags.ts index 68f560a1..5fb20629 100644 --- a/packages/moderation/src/types/nags.ts +++ b/packages/moderation/src/types/nags.ts @@ -1,4 +1,5 @@ -import type { Project, User, Version } from '@modrinth/utils' +import type { Labrinth } from '@modrinth/api-client' +import type { User, Version } from '@modrinth/utils' import type { MessageDescriptor } from '@vintl/vintl' import type { FunctionalComponent, SVGAttributes } from 'vue' @@ -20,7 +21,7 @@ export interface NagContext { /** * The project associated with the nag. */ - project: Project + project: Labrinth.Projects.v2.Project /** * The versions associated with the project. */ diff --git a/packages/moderation/src/types/reports.ts b/packages/moderation/src/types/reports.ts index cb02f8c3..249e457f 100644 --- a/packages/moderation/src/types/reports.ts +++ b/packages/moderation/src/types/reports.ts @@ -1,4 +1,5 @@ -import type { Project, Report, Thread, User, Version } from '@modrinth/utils' +import type { Labrinth } from '@modrinth/api-client' +import type { Report, Thread, User, Version } from '@modrinth/utils' export interface OwnershipTarget { name: string @@ -10,7 +11,7 @@ export interface OwnershipTarget { export interface ExtendedReport extends Report { thread: Thread reporter_user: User - project?: Project + project?: Labrinth.Projects.v2.Project user?: User version?: Version target?: OwnershipTarget diff --git a/packages/moderation/src/types/stage.ts b/packages/moderation/src/types/stage.ts index ad40ec7b..5e7eb946 100644 --- a/packages/moderation/src/types/stage.ts +++ b/packages/moderation/src/types/stage.ts @@ -1,4 +1,4 @@ -import type { Project } from '@modrinth/utils' +import type { Labrinth } from '@modrinth/api-client' import type { FunctionalComponent, SVGAttributes } from 'vue' import type { Action } from './actions' @@ -15,7 +15,10 @@ export interface Stage { /** * An optional description or additional text for the stage. */ - text?: (project: Project) => Promise + text?: ( + project: Labrinth.Projects.v2.Project, + projectV3?: Labrinth.Projects.v3.Project, + ) => Promise /** * Optional id for the stage, used for identification in the checklist. Will be used in the stage list as well instead of the title. @@ -49,5 +52,8 @@ export interface Stage { * * By default, it returns `true`, meaning the stage is always shown. */ - shouldShow?: (project: Project) => boolean + shouldShow?: ( + project: Labrinth.Projects.v2.Project, + projectV3?: Labrinth.Projects.v3.Project, + ) => boolean } diff --git a/packages/moderation/src/utils.ts b/packages/moderation/src/utils.ts index 5e6efdab..2d3655e4 100644 --- a/packages/moderation/src/utils.ts +++ b/packages/moderation/src/utils.ts @@ -1,4 +1,4 @@ -import type { Project } from '@modrinth/utils' +import type { Labrinth } from '@modrinth/api-client' import type { Action, @@ -210,11 +210,14 @@ export function getVisibleInputs( export function expandVariables( template: string, - project: Project, + project: Labrinth.Projects.v2.Project, + projectV3: Labrinth.Projects.v3.Project, variables?: Record, ): string { - if (!variables) { - variables = flattenProjectVariables(project) + variables ??= { + ...flattenStaticVariables(), + ...flattenProjectVariables(project), + ...flattenProjectV3Variables(projectV3), } return Object.entries(variables).reduce((result, [key, value]) => { @@ -234,7 +237,30 @@ export function arrayOrNone(arr: string[]): string { return arr.length > 0 ? arr.join(', ') : 'None' } -export function flattenProjectVariables(project: Project): Record { +export function flattenStaticVariables(): Record { + const vars: Record = {} + + vars[`RULES`] = `[Modrinth's Content Rules](https://modrinth.com/legal/rules)` + vars[`TOS`] = `[Terms of Use](https://modrinth.com/legal/terms)` + vars[`COPYRIGHT_POLICY`] = `[Copyright Policy](https://modrinth.com/legal/copyright)` + vars[`SUPPORT`] = + `please visit the [Modrinth Help Center](https://support.modrinth.com/) and click the blue bubble to contact support.` + vars[`MODPACK_PERMISSIONS_GUIDE`] = + `our guide to [Obtaining Modpack Permissions](https://support.modrinth.com/en/articles/8797527-obtaining-modpack-permissions)` + vars[`MODPACKS_ON_MODRINTH`] = + `[Modpacks on Modrinth](https://support.modrinth.com/en/articles/8802250-modpacks-on-modrinth)` + vars[`ADVANCED_MARKDOWN`] = + `[Markdown Formatting Guide](https://support.modrinth.com/en/articles/8801962-advanced-markdown-formatting)` + vars[`LICENSING_GUIDE`] = + `our guide to [Licensing your Mods](https://modrinth.com/news/article/licensing-guide)` + vars[`NEW_ENVIRONMENTS_LINK`] = `https://modrinth.com/news/article/new-environments` + + return vars +} + +export function flattenProjectVariables( + project: Labrinth.Projects.v2.Project, +): Record { const vars: Record = {} vars['PROJECT_ID'] = project.id @@ -299,22 +325,6 @@ export function flattenProjectVariables(project: Project): Record { + const vars: Record = {} + + const environment = projectV3.environment ?? [] + vars['PROJECT_V3_ENVIRONMENT_COUNT'] = environment.length.toString() + vars['PROJECT_V3_ALL_ENVIRONMENTS'] = environment.join(', ') + + environment.forEach((env, index) => { + vars[`PROJECT_V3_ENVIRONMENT_${index}`] = env + }) + + vars['PROJECT_V3_REVIEW_STATUS'] = projectV3.side_types_migration_review_status + vars['PROJECT_V3_TYPES'] = projectV3.project_types.join(', ') + + return vars +}