From 61fe220638bce4d26c463385697dc66f624433b8 Mon Sep 17 00:00:00 2001 From: Leaftail <110915645+leaftail1880@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:56:52 +0300 Subject: [PATCH] chore: Field Decorator Refactor (#302) * refactor: impove field decorators * chore: update scripts * refactor: improve lang --------- Co-authored-by: leaftail1880 <110915645+leaftaul1880@users.noreply.github.com> --- .eslintrc.js | 8 +- .../src/app/file/file.service.spec.ts | 2 + .../form-generator.service.spec.ts | 40 ++-- .../form-generator/form-generator.service.ts | 7 +- .../parsers/title-parser.service.spec.ts | 11 +- .../parsers/title-parser.service.ts | 7 +- .../app/post-parsers/post-parsers.module.ts | 7 +- .../src/app/post/post-manager.service.spec.ts | 8 +- .../services/submission.service.spec.ts | 2 + .../app/validation/validation.service.spec.ts | 16 +- .../website-options.service.spec.ts | 2 + .../discord/models/discord-file-submission.ts | 19 +- .../models/discord-message-submission.ts | 6 +- .../models/fur-affinity-file-submission.ts | 34 +--- .../models/fur-affinity-message-submission.ts | 32 +--- .../test/models/test-file-submission.ts | 22 +-- .../test/models/test-message-submission.ts | 17 +- .../models/default-website-options.ts | 33 +--- .../components/form/fields/field-label.tsx | 20 +- .../form/fields/field-translations.ts | 17 ++ .../src/components/form/fields/field.tsx | 2 +- .../components/form/fields/form-field.type.ts | 5 +- .../website-option-form.tsx | 10 +- ...slation.tsx => validation-translation.tsx} | 13 +- .../postybirb-ui/src/external-translations.ts | 9 - .../discord/discord-validation.tsx | 4 +- .../furaffinity/furaffinity-form-fields.tsx | 7 + apps/postybirb/src/main.ts | 2 +- jest.preset.js | 1 - lang/en.po | 58 ++++-- lang/es.po | 58 ++++-- lang/ru.po | 116 ++++++----- libs/form-builder/jest.config.ts | 5 +- .../lib/decorators/boolean-field.decorator.ts | 26 +-- .../decorators/description-field.decorator.ts | 35 ++-- .../lib/decorators/radio-field.decorator.ts | 32 ++-- .../src/lib/decorators/rating.decorator.ts | 54 ++++-- .../lib/decorators/select-field.decorator.ts | 40 ++-- .../src/lib/decorators/tag-field.decorator.ts | 36 +--- .../lib/decorators/text-field.decorator.ts | 33 ++-- .../form-builder/src/lib/form-builder.spec.ts | 47 +++-- libs/form-builder/src/lib/form-builder.ts | 19 +- .../src/lib/types/field-aggregate.ts | 44 +++-- libs/form-builder/src/lib/types/field.ts | 23 ++- .../src/lib/types/form-builder-metadata.ts | 6 +- .../src/lib/utils/assign-metadata.ts | 128 ++++++++++--- libs/form-builder/tsconfig.json | 3 + libs/fs/src/lib/fs.spec.ts | 12 +- libs/http/jest.config.ts | 1 - libs/types/src/models/index.ts | 1 + .../submission/field-translation.type.ts | 12 ++ .../types/src/models/tag/default-tag-value.ts | 2 +- package.json | 27 ++- ...@kayahr+jest-electron-runner+29.14.0.patch | 30 +++ yarn.lock | 181 ++++++++++++++---- 55 files changed, 803 insertions(+), 589 deletions(-) create mode 100644 apps/postybirb-ui/src/components/form/fields/field-translations.ts rename apps/postybirb-ui/src/components/translations/{translation.tsx => validation-translation.tsx} (94%) delete mode 100644 apps/postybirb-ui/src/external-translations.ts create mode 100644 apps/postybirb-ui/src/website-components/furaffinity/furaffinity-form-fields.tsx create mode 100644 libs/types/src/models/submission/field-translation.type.ts create mode 100644 patches/@kayahr+jest-electron-runner+29.14.0.patch diff --git a/.eslintrc.js b/.eslintrc.js index a7a80d527..10815e079 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -44,7 +44,12 @@ module.exports = { 'error', { enforceBuildableLibDependency: true, - allow: [], + + // We allow it because we need to use import from + // postybirb-ui to make jump-to definition in the + // FieldType.label + allow: ['@postybirb/form-builder'], + depConstraints: [ { sourceTag: '*', @@ -73,6 +78,7 @@ module.exports = { 'import/prefer-default-export': 'off', 'react/jsx-props-no-spreading': 'off', 'react/react-in-jsx-scope': 'off', + 'no-restricted-syntax': 'off', '@typescript-eslint/ban-types': 'warn', 'import/no-extraneous-dependencies': [ diff --git a/apps/client-server/src/app/file/file.service.spec.ts b/apps/client-server/src/app/file/file.service.spec.ts index 92331204e..4ba662666 100644 --- a/apps/client-server/src/app/file/file.service.spec.ts +++ b/apps/client-server/src/app/file/file.service.spec.ts @@ -18,6 +18,7 @@ import { MessageSubmissionService } from '../submission/services/message-submiss import { SubmissionService } from '../submission/services/submission.service'; import { TagConvertersService } from '../tag-converters/tag-converters.service'; import { UserSpecifiedWebsiteOptionsService } from '../user-specified-website-options/user-specified-website-options.service'; +import { ValidationService } from '../validation/validation.service'; import { WebsiteOptionsService } from '../website-options/website-options.service'; import { WebsiteImplProvider } from '../websites/implementations'; import { WebsiteRegistryService } from '../websites/website-registry.service'; @@ -76,6 +77,7 @@ describe('FileService', () => { CreateFileService, UpdateFileService, FileService, + ValidationService, SubmissionService, FileSubmissionService, MessageSubmissionService, diff --git a/apps/client-server/src/app/form-generator/form-generator.service.spec.ts b/apps/client-server/src/app/form-generator/form-generator.service.spec.ts index a0fd6405f..c5f8097e8 100644 --- a/apps/client-server/src/app/form-generator/form-generator.service.spec.ts +++ b/apps/client-server/src/app/form-generator/form-generator.service.spec.ts @@ -76,7 +76,7 @@ describe('FormGeneratorService', () => { col: 1, defaultValue: '', formField: 'input', - label: 'Content Warning / Spoilers', + label: 'contentWarning', row: 2, type: 'text', }, @@ -87,16 +87,15 @@ describe('FormGeneratorService', () => { overrideDefault: false, }, formField: 'description', - i18nLabel: 'form.descriptions', - label: 'Description', + label: 'description', row: 3, type: 'description', }, rating: { col: 0, - defaultValue: SubmissionRating.ADULT, + defaultValue: 'ADULT', formField: 'rating', - label: 'Rating', + label: 'rating', layout: 'vertical', options: [ { @@ -127,8 +126,7 @@ describe('FormGeneratorService', () => { tags: [], }, formField: 'tag', - i18nLabel: 'form.tags', - label: 'Tags', + label: 'tags', row: 1, type: 'tag', }, @@ -136,7 +134,7 @@ describe('FormGeneratorService', () => { col: 1, defaultValue: '', formField: 'input', - label: 'Title', + label: 'title', required: true, row: 0, type: 'text', @@ -151,7 +149,7 @@ describe('FormGeneratorService', () => { col: 1, defaultValue: '', formField: 'input', - label: 'Content Warning / Spoilers', + label: 'contentWarning', row: 2, type: 'text', }, @@ -162,16 +160,14 @@ describe('FormGeneratorService', () => { overrideDefault: false, }, formField: 'description', - i18nLabel: 'form.descriptions', - label: 'Description', + label: 'description', row: 3, type: 'description', }, rating: { col: 0, - defaultValue: 'GENERAL', formField: 'rating', - label: 'Rating', + label: 'rating', layout: 'vertical', options: [ { @@ -202,8 +198,7 @@ describe('FormGeneratorService', () => { tags: [], }, formField: 'tag', - i18nLabel: 'form.tags', - label: 'Tags', + label: 'tags', row: 1, type: 'tag', }, @@ -211,7 +206,7 @@ describe('FormGeneratorService', () => { col: 1, defaultValue: '', formField: 'input', - label: 'Title', + label: 'title', required: true, row: 0, type: 'text', @@ -224,7 +219,7 @@ describe('FormGeneratorService', () => { col: 1, defaultValue: '', formField: 'input', - label: 'Content Warning / Spoilers', + label: 'contentWarning', row: 2, type: 'text', }, @@ -235,16 +230,14 @@ describe('FormGeneratorService', () => { overrideDefault: false, }, formField: 'description', - i18nLabel: 'form.descriptions', - label: 'Description', + label: 'description', row: 3, type: 'description', }, rating: { col: 0, - defaultValue: 'GENERAL', formField: 'rating', - label: 'Rating', + label: 'rating', layout: 'vertical', options: [ { @@ -275,8 +268,7 @@ describe('FormGeneratorService', () => { tags: [], }, formField: 'tag', - i18nLabel: 'form.tags', - label: 'Tags', + label: 'tags', row: 1, type: 'tag', }, @@ -284,7 +276,7 @@ describe('FormGeneratorService', () => { col: 1, defaultValue: '', formField: 'input', - label: 'Title', + label: 'title', required: true, row: 0, type: 'text', diff --git a/apps/client-server/src/app/form-generator/form-generator.service.ts b/apps/client-server/src/app/form-generator/form-generator.service.ts index a269ffe86..4a142d67c 100644 --- a/apps/client-server/src/app/form-generator/form-generator.service.ts +++ b/apps/client-server/src/app/form-generator/form-generator.service.ts @@ -34,7 +34,7 @@ export class FormGeneratorService { */ async generateForm( request: FormGenerationRequestDto, - ): Promise> { + ): Promise { const account = await this.accountService.findById(request.accountId, { failOnMissing: true, }); @@ -96,10 +96,10 @@ export class FormGeneratorService { } private async populateUserDefaults( - form: FormBuilderMetadata, + form: FormBuilderMetadata, accountId: AccountId, type: SubmissionType, - ): Promise> { + ): Promise { const userSpecifiedDefaults = await this.userSpecifiedWebsiteOptionsService.findByAccountAndSubmissionType( accountId, @@ -110,7 +110,6 @@ export class FormGeneratorService { Object.entries(userSpecifiedDefaults.options).forEach(([key, value]) => { const field = form[key]; if (field) { - // eslint-disable-next-line no-param-reassign field.defaultValue = value ?? field.defaultValue; } }); diff --git a/apps/client-server/src/app/post-parsers/parsers/title-parser.service.spec.ts b/apps/client-server/src/app/post-parsers/parsers/title-parser.service.spec.ts index 4cbdafe74..b0b6075d4 100644 --- a/apps/client-server/src/app/post-parsers/parsers/title-parser.service.spec.ts +++ b/apps/client-server/src/app/post-parsers/parsers/title-parser.service.spec.ts @@ -39,11 +39,13 @@ describe('TitleParserService', () => { it('should parse title', async () => { const submission = new Submission({}); const defaultOptions: IWebsiteOptions = { + id: 'default', data: { title: 'default', }, } as IWebsiteOptions; const websiteOptions: IWebsiteOptions = { + id: 'website', data: { title: 'website', }, @@ -71,15 +73,17 @@ describe('TitleParserService', () => { const submission = new Submission({}); const instance = new WebsiteInstanceMock(); const defaultOptions: IWebsiteOptions = { + id: 'default', data: { title: 'default', }, } as IWebsiteOptions; const websiteOptions: IWebsiteOptions = { + id: 'website', data: {}, } as IWebsiteOptions; - const defaultForm = { title: [{ maxLength: 10 }] }; - const websiteForm = { title: [{ maxLength: 5 }] }; + const defaultForm = { title: { maxLength: 10 } }; + const websiteForm = { title: { maxLength: 5 } }; (formGeneratorService.getDefaultForm as jest.Mock).mockResolvedValue( defaultForm, ); @@ -94,6 +98,7 @@ describe('TitleParserService', () => { websiteOptions, ); + // Title should be truncated expect(title).toBe('defau'); }); @@ -101,11 +106,13 @@ describe('TitleParserService', () => { const submission = new Submission({}); const instance = new WebsiteInstanceMock(); const defaultOptions: IWebsiteOptions = { + id: 'default', data: { title: 'default', }, } as IWebsiteOptions; const websiteOptions: IWebsiteOptions = { + id: 'website', data: { title: 'website', }, diff --git a/apps/client-server/src/app/post-parsers/parsers/title-parser.service.ts b/apps/client-server/src/app/post-parsers/parsers/title-parser.service.ts index 7202f0ca3..c3125d034 100644 --- a/apps/client-server/src/app/post-parsers/parsers/title-parser.service.ts +++ b/apps/client-server/src/app/post-parsers/parsers/title-parser.service.ts @@ -4,7 +4,7 @@ import { ISubmission, IWebsiteOptions } from '@postybirb/types'; import { FormGeneratorService } from '../../form-generator/form-generator.service'; import { UnknownWebsite } from '../../websites/website'; -type TitleType = { title: TextFieldType[] }; +type TitleType = { title: TextFieldType }; @Injectable() export class TitleParserService { @@ -29,10 +29,7 @@ export class TitleParserService { })) as unknown as TitleType); const title = websiteOptions.data.title ?? defaultOptions.data.title ?? ''; - const field: TextFieldType = - websiteForm?.title[0] ?? - defaultForm?.title[0] ?? - ({ maxLength: Infinity } as TextFieldType); + const field = websiteForm?.title ?? defaultForm?.title; const maxLength = field?.maxLength ?? Infinity; return title.trim().slice(0, maxLength); diff --git a/apps/client-server/src/app/post-parsers/post-parsers.module.ts b/apps/client-server/src/app/post-parsers/post-parsers.module.ts index 3d961159c..7c55c1bfe 100644 --- a/apps/client-server/src/app/post-parsers/post-parsers.module.ts +++ b/apps/client-server/src/app/post-parsers/post-parsers.module.ts @@ -23,6 +23,11 @@ import { PostParsersService } from './post-parsers.service'; WebsiteImplProvider, DescriptionParserService, ], - exports: [PostParsersService], + exports: [ + PostParsersService, + TagParserService, + TitleParserService, + DescriptionParserService, + ], }) export class PostParsersModule {} diff --git a/apps/client-server/src/app/post/post-manager.service.spec.ts b/apps/client-server/src/app/post/post-manager.service.spec.ts index 58af354c4..614910cd5 100644 --- a/apps/client-server/src/app/post/post-manager.service.spec.ts +++ b/apps/client-server/src/app/post/post-manager.service.spec.ts @@ -15,6 +15,7 @@ import { CreateSubmissionDto } from '../submission/dtos/create-submission.dto'; import { SubmissionService } from '../submission/services/submission.service'; import { SubmissionModule } from '../submission/submission.module'; import { UserSpecifiedWebsiteOptionsModule } from '../user-specified-website-options/user-specified-website-options.module'; +import { ValidationService } from '../validation/validation.service'; import { CreateWebsiteOptionsDto } from '../website-options/dtos/create-website-options.dto'; import { WebsiteOptionsModule } from '../website-options/website-options.module'; import { WebsiteOptionsService } from '../website-options/website-options.service'; @@ -47,7 +48,12 @@ describe('PostManagerService', () => { PostParsersModule, PostModule, ], - providers: [PostManagerService, PostService, PostFileResizerService], + providers: [ + PostManagerService, + PostService, + PostFileResizerService, + ValidationService, + ], }).compile(); service = module.get(PostManagerService); diff --git a/apps/client-server/src/app/submission/services/submission.service.spec.ts b/apps/client-server/src/app/submission/services/submission.service.spec.ts index a344ea630..3311dc1c3 100644 --- a/apps/client-server/src/app/submission/services/submission.service.spec.ts +++ b/apps/client-server/src/app/submission/services/submission.service.spec.ts @@ -24,6 +24,7 @@ import { FormGeneratorModule } from '../../form-generator/form-generator.module' import { PostParsersModule } from '../../post-parsers/post-parsers.module'; import { UserSpecifiedWebsiteOptionsModule } from '../../user-specified-website-options/user-specified-website-options.module'; import { UserSpecifiedWebsiteOptionsService } from '../../user-specified-website-options/user-specified-website-options.service'; +import { ValidationService } from '../../validation/validation.service'; import { WebsiteOptionsService } from '../../website-options/website-options.service'; import { WebsiteImplProvider } from '../../websites/implementations'; import { WebsiteRegistryService } from '../../websites/website-registry.service'; @@ -68,6 +69,7 @@ describe('SubmissionService', () => { AccountService, WebsiteRegistryService, UserSpecifiedWebsiteOptionsService, + ValidationService, WebsiteOptionsService, WebsiteImplProvider, ], diff --git a/apps/client-server/src/app/validation/validation.service.spec.ts b/apps/client-server/src/app/validation/validation.service.spec.ts index 6b79f0bdc..0092b0629 100644 --- a/apps/client-server/src/app/validation/validation.service.spec.ts +++ b/apps/client-server/src/app/validation/validation.service.spec.ts @@ -1,4 +1,11 @@ import { Test, TestingModule } from '@nestjs/testing'; +import { DatabaseModule } from '../database/database.module'; +import { DatabaseUpdateSubscriber } from '../database/subscribers/database.subscriber'; +import { PostParsersModule } from '../post-parsers/post-parsers.module'; +import { PostParsersService } from '../post-parsers/post-parsers.service'; +import { WebsiteImplProvider } from '../websites/implementations'; +import { WebsiteRegistryService } from '../websites/website-registry.service'; +import { WebsitesModule } from '../websites/websites.module'; import { ValidationService } from './validation.service'; describe('ValidationService', () => { @@ -6,7 +13,14 @@ describe('ValidationService', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [ValidationService], + imports: [WebsitesModule, PostParsersModule, DatabaseModule], + providers: [ + WebsiteImplProvider, + ValidationService, + DatabaseUpdateSubscriber, + WebsiteRegistryService, + PostParsersService, + ], }).compile(); service = module.get(ValidationService); diff --git a/apps/client-server/src/app/website-options/website-options.service.spec.ts b/apps/client-server/src/app/website-options/website-options.service.spec.ts index 5cbbd7295..a8381c5cd 100644 --- a/apps/client-server/src/app/website-options/website-options.service.spec.ts +++ b/apps/client-server/src/app/website-options/website-options.service.spec.ts @@ -22,6 +22,7 @@ import { MessageSubmissionService } from '../submission/services/message-submiss import { SubmissionService } from '../submission/services/submission.service'; import { UserSpecifiedWebsiteOptionsModule } from '../user-specified-website-options/user-specified-website-options.module'; import { UserSpecifiedWebsiteOptionsService } from '../user-specified-website-options/user-specified-website-options.service'; +import { ValidationService } from '../validation/validation.service'; import { WebsiteImplProvider } from '../websites/implementations'; import { WebsiteRegistryService } from '../websites/website-registry.service'; import { WebsitesModule } from '../websites/websites.module'; @@ -76,6 +77,7 @@ describe('WebsiteOptionsService', () => { MessageSubmissionService, AccountService, WebsiteRegistryService, + ValidationService, WebsiteOptionsService, WebsiteImplProvider, UserSpecifiedWebsiteOptionsService, diff --git a/apps/client-server/src/app/websites/implementations/discord/models/discord-file-submission.ts b/apps/client-server/src/app/websites/implementations/discord/models/discord-file-submission.ts index 05d9556b2..7ee73796c 100644 --- a/apps/client-server/src/app/websites/implementations/discord/models/discord-file-submission.ts +++ b/apps/client-server/src/app/websites/implementations/discord/models/discord-file-submission.ts @@ -5,33 +5,24 @@ import { TextField, } from '@postybirb/form-builder'; import { - DefaultDescriptionValue, DescriptionValue, IWebsiteFormFields, SubmissionRating, } from '@postybirb/types'; -import { DefaultRatingOptions } from '../../../models/default-website-options'; export class DiscordFileSubmission implements IWebsiteFormFields { - @BooleanField({ label: 'Use thumbnail', defaultValue: true }) + @BooleanField({ label: 'useThumbnail', defaultValue: true }) useThumbnail = true; - @BooleanField({ label: 'Allow resizing image', defaultValue: true }) + @BooleanField({ label: 'allowResize', defaultValue: true }) allowResize = true; - @TextField({ label: 'Title', defaultValue: '' }) + @TextField({ label: 'title', defaultValue: '' }) title?: string; - @DescriptionField({ - label: 'Description', - defaultValue: DefaultDescriptionValue(), - }) + @DescriptionField({}) description: DescriptionValue; - @RatingField({ - label: 'Rating', - defaultValue: undefined, - options: DefaultRatingOptions, - }) + @RatingField({}) rating: SubmissionRating; } diff --git a/apps/client-server/src/app/websites/implementations/discord/models/discord-message-submission.ts b/apps/client-server/src/app/websites/implementations/discord/models/discord-message-submission.ts index 3727c784f..d4f690647 100644 --- a/apps/client-server/src/app/websites/implementations/discord/models/discord-message-submission.ts +++ b/apps/client-server/src/app/websites/implementations/discord/models/discord-message-submission.ts @@ -9,11 +9,10 @@ import { IWebsiteFormFields, SubmissionRating, } from '@postybirb/types'; -import { DefaultRatingOptions } from '../../../models/default-website-options'; export class DiscordMessageSubmission implements IWebsiteFormFields { @TextField({ - label: 'Title', + label: 'title', defaultValue: '', row: 0, col: 1, @@ -29,9 +28,6 @@ export class DiscordMessageSubmission implements IWebsiteFormFields { description: DescriptionValue; @RatingField({ - label: 'Rating', - defaultValue: undefined, - options: DefaultRatingOptions, required: true, row: 0, col: 0, diff --git a/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-file-submission.ts b/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-file-submission.ts index dca89288b..cad874286 100644 --- a/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-file-submission.ts +++ b/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-file-submission.ts @@ -6,50 +6,28 @@ import { TextField, } from '@postybirb/form-builder'; import { - DefaultDescriptionValue, - DefaultTagValue, DescriptionValue, IWebsiteFormFields, SubmissionRating, TagValue, } from '@postybirb/types'; -import { DefaultRatingOptions } from '../../../models/default-website-options'; export class FurAffinityFileSubmission implements IWebsiteFormFields { - @BooleanField({ label: 'Use thumbnail', defaultValue: true }) + @BooleanField({ label: 'useThumbnail', defaultValue: true }) useThumbnail = true; - @BooleanField({ label: 'Allow resizing image', defaultValue: true }) + @BooleanField({ label: 'allowResize', defaultValue: true }) allowResize = true; - @TextField({ - label: 'Title', - defaultValue: '', - required: true, - row: 0, - col: 1, - }) + @TextField({ label: 'title', required: true, row: 0, col: 1 }) title: string; - @TagField({ label: 'Tags', defaultValue: DefaultTagValue(), row: 2, col: 1 }) + @TagField({ row: 2, col: 1 }) tags: TagValue; - @DescriptionField({ - label: 'Description', - defaultValue: DefaultDescriptionValue(), - row: 3, - col: 1, - }) + @DescriptionField({ row: 3, col: 1 }) description: DescriptionValue; - @RatingField({ - label: 'Rating', - defaultValue: undefined, - options: DefaultRatingOptions, - required: true, - row: 0, - col: 0, - layout: 'vertical', - }) + @RatingField({ required: true, row: 0, col: 0 }) rating: SubmissionRating; } diff --git a/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-message-submission.ts b/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-message-submission.ts index 4f7633114..14eb4aaf9 100644 --- a/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-message-submission.ts +++ b/apps/client-server/src/app/websites/implementations/fur-affinity/models/fur-affinity-message-submission.ts @@ -6,47 +6,25 @@ import { TextField, } from '@postybirb/form-builder'; import { - DefaultDescriptionValue, - DefaultTagValue, DescriptionValue, IWebsiteFormFields, SubmissionRating, TagValue, } from '@postybirb/types'; -import { DefaultRatingOptions } from '../../../models/default-website-options'; export class FurAffinityMessageSubmission implements IWebsiteFormFields { - @TextField({ - label: 'Title', - defaultValue: '', - row: 0, - col: 1, - maxLength: 124, - }) + @TextField({ label: 'title', row: 0, col: 1, maxLength: 124 }) title: string; - @TagField({ label: 'Tags', defaultValue: DefaultTagValue(), row: 2, col: 1 }) + @TagField({ row: 2, col: 1 }) tags: TagValue; - @DescriptionField({ - label: 'Description', - defaultValue: DefaultDescriptionValue(), - row: 3, - col: 1, - }) + @DescriptionField({ row: 3, col: 1 }) description: DescriptionValue; - @RatingField({ - label: 'Rating', - defaultValue: undefined, - options: DefaultRatingOptions, - required: true, - row: 0, - col: 0, - layout: 'vertical', - }) + @RatingField({ required: true, row: 0, col: 0 }) rating: SubmissionRating; - @BooleanField({ label: 'Feature', defaultValue: true }) + @BooleanField({ label: 'feature', defaultValue: true }) feature: boolean; } diff --git a/apps/client-server/src/app/websites/implementations/test/models/test-file-submission.ts b/apps/client-server/src/app/websites/implementations/test/models/test-file-submission.ts index fa2f07300..2273fd41f 100644 --- a/apps/client-server/src/app/websites/implementations/test/models/test-file-submission.ts +++ b/apps/client-server/src/app/websites/implementations/test/models/test-file-submission.ts @@ -6,38 +6,28 @@ import { TextField, } from '@postybirb/form-builder'; import { - DefaultDescriptionValue, - DefaultTagValue, DescriptionValue, IWebsiteFormFields, SubmissionRating, TagValue, } from '@postybirb/types'; -import { DefaultRatingOptions } from '../../../models/default-website-options'; export class TestFileSubmission implements IWebsiteFormFields { - @BooleanField({ label: 'Use thumbnail', defaultValue: true }) + @BooleanField({ label: 'useThumbnail', defaultValue: true }) useThumbnail = true; - @BooleanField({ label: 'Allow resizing image', defaultValue: true }) + @BooleanField({ label: 'allowResize', defaultValue: true }) allowResize = true; - @TextField({ label: 'Title', defaultValue: '' }) + @TextField({ label: 'title', defaultValue: '' }) title?: string; - @TagField({ label: 'Tags', defaultValue: DefaultTagValue(), maxTags: 10 }) + @TagField({ maxTags: 10 }) tags: TagValue; - @DescriptionField({ - label: 'Description', - defaultValue: DefaultDescriptionValue(), - }) + @DescriptionField({}) description: DescriptionValue; - @RatingField({ - label: 'Rating', - defaultValue: undefined, - options: DefaultRatingOptions, - }) + @RatingField({}) rating: SubmissionRating; } diff --git a/apps/client-server/src/app/websites/implementations/test/models/test-message-submission.ts b/apps/client-server/src/app/websites/implementations/test/models/test-message-submission.ts index 71281a55f..dcd40b964 100644 --- a/apps/client-server/src/app/websites/implementations/test/models/test-message-submission.ts +++ b/apps/client-server/src/app/websites/implementations/test/models/test-message-submission.ts @@ -5,32 +5,23 @@ import { TextField, } from '@postybirb/form-builder'; import { - DefaultDescriptionValue, DefaultTagValue, DescriptionValue, IWebsiteFormFields, SubmissionRating, TagValue, } from '@postybirb/types'; -import { DefaultRatingOptions } from '../../../models/default-website-options'; export class TestMessageSubmission implements IWebsiteFormFields { - @TextField({ label: 'Title', defaultValue: '' }) + @TextField({ label: 'title', defaultValue: '' }) title?: string; - @TagField({ label: 'Tags', defaultValue: DefaultTagValue() }) + @TagField({ label: 'tags', defaultValue: DefaultTagValue() }) tags: TagValue; - @DescriptionField({ - label: 'Description', - defaultValue: DefaultDescriptionValue(), - }) + @DescriptionField({}) description: DescriptionValue; - @RatingField({ - label: 'Rating', - defaultValue: undefined, - options: DefaultRatingOptions, - }) + @RatingField({}) rating: SubmissionRating; } diff --git a/apps/client-server/src/app/websites/models/default-website-options.ts b/apps/client-server/src/app/websites/models/default-website-options.ts index b62b03116..a6b4de484 100644 --- a/apps/client-server/src/app/websites/models/default-website-options.ts +++ b/apps/client-server/src/app/websites/models/default-website-options.ts @@ -1,7 +1,6 @@ import { DescriptionField, RatingField, - RatingOption, TagField, TextField, } from '@postybirb/form-builder'; @@ -14,25 +13,6 @@ import { TagValue, } from '@postybirb/types'; -export const DefaultRatingOptions: RatingOption[] = [ - { - label: 'General', - value: SubmissionRating.GENERAL, - }, - { - label: 'Mature', - value: SubmissionRating.MATURE, - }, - { - label: 'Adult', - value: SubmissionRating.ADULT, - }, - { - label: 'Extreme', - value: SubmissionRating.EXTREME, - }, -]; - export const DefaultWebsiteOptionsObject: IWebsiteFormFields = { title: '', tags: DefaultTagValue(), @@ -42,8 +22,7 @@ export const DefaultWebsiteOptionsObject: IWebsiteFormFields = { export class DefaultWebsiteOptions implements IWebsiteFormFields { @TextField({ - label: 'Title', - defaultValue: DefaultWebsiteOptionsObject.title, + label: 'title', required: true, col: 1, row: 0, @@ -51,15 +30,13 @@ export class DefaultWebsiteOptions implements IWebsiteFormFields { title: string; @TagField({ - label: 'Tags', - defaultValue: DefaultWebsiteOptionsObject.tags, col: 1, row: 1, }) tags: TagValue; @TextField({ - label: 'Content Warning / Spoilers', + label: 'contentWarning', defaultValue: '', col: 1, row: 2, @@ -67,21 +44,15 @@ export class DefaultWebsiteOptions implements IWebsiteFormFields { contentWarning: string; @DescriptionField({ - label: 'Description', - defaultValue: DefaultWebsiteOptionsObject.description, col: 1, row: 3, }) description: DescriptionValue; @RatingField({ - label: 'Rating', - defaultValue: DefaultWebsiteOptionsObject.rating, - options: DefaultRatingOptions, required: true, col: 0, row: 0, - layout: 'vertical', }) rating: SubmissionRating; } diff --git a/apps/postybirb-ui/src/components/form/fields/field-label.tsx b/apps/postybirb-ui/src/components/form/fields/field-label.tsx index ec2c31d4a..bed68976f 100644 --- a/apps/postybirb-ui/src/components/form/fields/field-label.tsx +++ b/apps/postybirb-ui/src/components/form/fields/field-label.tsx @@ -1,11 +1,11 @@ import { MessageDescriptor } from '@lingui/core'; import { useLingui } from '@lingui/react'; import { Input } from '@mantine/core'; -import { FieldAggregateType } from '@postybirb/form-builder'; +import type { FieldAggregateType } from '@postybirb/form-builder'; import { PropsWithChildren } from 'react'; -import { externalTranslations } from '../../../external-translations'; -import { ValidationTranslation } from '../../translations/translation'; +import { ValidationTranslation } from '../../translations/validation-translation'; import { UseValidationResult } from '../hooks/use-validations'; +import { fieldLabelTranslations } from './field-translations'; import { FormFieldProps } from './form-field.type'; type FieldLabelProps = FormFieldProps & { @@ -13,20 +13,18 @@ type FieldLabelProps = FormFieldProps & { }; export function getTranslatedLabel( - field: FieldAggregateType, + field: FieldAggregateType, converter: (msg: MessageDescriptor) => string, ): string { - // eslint-disable-next-line prefer-const - let { label, i18nLabel } = field; - const i18n = i18nLabel || label; - const translationLabel = externalTranslations[i18n]; + const translationLabel = fieldLabelTranslations[field.label]; + if (!translationLabel) { // eslint-disable-next-line lingui/no-unlocalized-strings, no-console console.warn('Missing translation for field', field); - } else { - label = converter(translationLabel); + return field.label; } - return label; + + return converter(translationLabel); } export function FieldLabel( diff --git a/apps/postybirb-ui/src/components/form/fields/field-translations.ts b/apps/postybirb-ui/src/components/form/fields/field-translations.ts new file mode 100644 index 000000000..bbd12a435 --- /dev/null +++ b/apps/postybirb-ui/src/components/form/fields/field-translations.ts @@ -0,0 +1,17 @@ +import { MessageDescriptor } from '@lingui/core'; +import { msg } from '@lingui/macro'; +import { FieldTranslations } from '@postybirb/types'; + +export const fieldLabelTranslations: { + [K in keyof FieldTranslations]: MessageDescriptor; +} = { + description: msg`Description`, + tags: msg`Tags`, + title: msg`Title`, + rating: msg`Rating`, + species: msg`Species`, + contentWarning: msg`Content warning`, + useThumbnail: msg`Use thumbnail`, + allowResize: msg`Allow resizing image`, + feature: msg`Feature`, +}; diff --git a/apps/postybirb-ui/src/components/form/fields/field.tsx b/apps/postybirb-ui/src/components/form/fields/field.tsx index ea6dc6b0a..82fafdf0a 100644 --- a/apps/postybirb-ui/src/components/form/fields/field.tsx +++ b/apps/postybirb-ui/src/components/form/fields/field.tsx @@ -1,4 +1,4 @@ -import { +import type { BooleanFieldType, DescriptionFieldType, RadioFieldType, diff --git a/apps/postybirb-ui/src/components/form/fields/form-field.type.ts b/apps/postybirb-ui/src/components/form/fields/form-field.type.ts index 78055f78a..75b45ebb8 100644 --- a/apps/postybirb-ui/src/components/form/fields/form-field.type.ts +++ b/apps/postybirb-ui/src/components/form/fields/form-field.type.ts @@ -1,6 +1,5 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ import { UseFormReturnType } from '@mantine/form'; -import { FieldAggregateType } from '@postybirb/form-builder'; +import type { FieldAggregateType } from '@postybirb/form-builder'; import { IWebsiteFormFields, ValidationResult, @@ -12,7 +11,7 @@ export type SubmissionValidationResult = { result: ValidationResult; }; -export type FormFieldProps> = { +export type FormFieldProps = { defaultOption: WebsiteOptionsDto; field: T; form: UseFormReturnType< diff --git a/apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx b/apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx index a5dda9a47..6e5bcedbb 100644 --- a/apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx +++ b/apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx @@ -2,7 +2,7 @@ import { Trans } from '@lingui/macro'; import { Alert, Box, Flex, Loader, Stack } from '@mantine/core'; import { useForm } from '@mantine/form'; -import { +import type { FieldAggregateType, FormBuilderMetadata, } from '@postybirb/form-builder'; @@ -19,7 +19,7 @@ import { useQuery } from 'react-query'; import formGeneratorApi from '../../../api/form-generator.api'; import websiteOptionsApi from '../../../api/website-options.api'; import { SubmissionDto } from '../../../models/dtos/submission.dto'; -import { ValidationTranslation } from '../../translations/translation'; +import { ValidationTranslation } from '../../translations/validation-translation'; import { Field } from '../fields/field'; import { UserSpecifiedWebsiteOptionsSaveModal } from '../user-specified-website-options-modal/user-specified-website-options-modal'; @@ -33,7 +33,7 @@ type WebsiteOptionFormProps = { type InnerFormProps = { account: AccountId; submission: SubmissionDto; - formFields: FormBuilderMetadata; + formFields: FormBuilderMetadata; option: WebsiteOptionsDto; defaultOption: WebsiteOptionsDto; userSpecifiedModalVisible: boolean; @@ -42,7 +42,7 @@ type InnerFormProps = { type FieldEntry = { key: string; - field: FieldAggregateType; + field: FieldAggregateType; }; function shouldGrow(entries: FieldEntry[]): boolean { @@ -193,7 +193,7 @@ function InnerForm({ } + field={entry.field as unknown as FieldAggregateType} form={form} key={entry.key} option={option as unknown as WebsiteOptionsDto} diff --git a/apps/postybirb-ui/src/components/translations/translation.tsx b/apps/postybirb-ui/src/components/translations/validation-translation.tsx similarity index 94% rename from apps/postybirb-ui/src/components/translations/translation.tsx rename to apps/postybirb-ui/src/components/translations/validation-translation.tsx index d55ff7e6c..542ce037c 100644 --- a/apps/postybirb-ui/src/components/translations/translation.tsx +++ b/apps/postybirb-ui/src/components/translations/validation-translation.tsx @@ -65,6 +65,11 @@ export const TranslationMessages: Partial = { }, 'validation.tags.max-tags': (props) => { + // + // Tag limit reached (7/5) + // Tag limit reached (7 / 5) + // with space its more readable + // const { maxLength, currentLength } = props.values; return ( @@ -76,12 +81,12 @@ export const TranslationMessages: Partial = { 'validation.tags.min-tags': (props) => { const { minLength, currentLength } = props.values; return ( - <> - Requires at least {minLength} tags{' '} + + Requires at least {minLength} tags{' '} ({currentLength} / {minLength}) - + ); }, @@ -89,7 +94,7 @@ export const TranslationMessages: Partial = { const { tags, maxLength } = props.values; return ( <> - Tags longer than {maxLength} characters will be skipped :{' '} + Tags longer than {maxLength} characters will be skipped:{' '} {tags.join(', ')} ); diff --git a/apps/postybirb-ui/src/external-translations.ts b/apps/postybirb-ui/src/external-translations.ts deleted file mode 100644 index 1b6b3ab59..000000000 --- a/apps/postybirb-ui/src/external-translations.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { MessageDescriptor } from '@lingui/core'; -import { msg } from '@lingui/macro'; - -export const externalTranslations: Record = { - Description: msg`Description`, - Tags: msg`Tags`, - Title: msg`Title`, - Rating: msg`Rating`, -}; diff --git a/apps/postybirb-ui/src/website-components/discord/discord-validation.tsx b/apps/postybirb-ui/src/website-components/discord/discord-validation.tsx index d2190b630..ca325bee9 100644 --- a/apps/postybirb-ui/src/website-components/discord/discord-validation.tsx +++ b/apps/postybirb-ui/src/website-components/discord/discord-validation.tsx @@ -1,7 +1,7 @@ // This is example file showing how to define custom messages import { Trans } from '@lingui/macro'; -import { TranslationMessages } from '../../components/translations/translation'; +import { TranslationMessages } from '../../components/translations/validation-translation'; declare module '@postybirb/types' { interface ValidationMessages { @@ -15,5 +15,3 @@ TranslationMessages['discord.webhook.name'] = (props) => { const { name } = props.values; return Webhook name {name} is invalid; }; - -export {}; diff --git a/apps/postybirb-ui/src/website-components/furaffinity/furaffinity-form-fields.tsx b/apps/postybirb-ui/src/website-components/furaffinity/furaffinity-form-fields.tsx new file mode 100644 index 000000000..8ada474cc --- /dev/null +++ b/apps/postybirb-ui/src/website-components/furaffinity/furaffinity-form-fields.tsx @@ -0,0 +1,7 @@ +declare module '@postybirb/types' { + interface FieldTranslations { + species: true; + } +} + +export {}; diff --git a/apps/postybirb/src/main.ts b/apps/postybirb/src/main.ts index ab86bd2ae..77992dbc4 100644 --- a/apps/postybirb/src/main.ts +++ b/apps/postybirb/src/main.ts @@ -1,6 +1,6 @@ -/* eslint-disable @nrwl/nx/enforce-module-boundaries */ import { INestApplication } from '@nestjs/common'; import { PostyBirbEnvConfig } from '@postybirb/utils/electron'; +// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries import { bootstrapClientServer } from 'apps/client-server/src/main'; import { app, BrowserWindow, powerSaveBlocker } from 'electron'; import contextMenu from 'electron-context-menu'; diff --git a/jest.preset.js b/jest.preset.js index 9b180d99d..671545469 100644 --- a/jest.preset.js +++ b/jest.preset.js @@ -7,6 +7,5 @@ const basePath = __dirname.split(/(app|lib)/)[0]; module.exports = { ...nxPreset, setupFiles: [join(basePath, 'jest.setup.ts')], - verbose: false, silent: true, }; diff --git a/lang/en.po b/lang/en.po index 1b60d0470..fb92c982d 100644 --- a/lang/en.po +++ b/lang/en.po @@ -13,11 +13,11 @@ msgstr "" "Language-Team: \n" "Plural-Forms: \n" -#: apps/postybirb-ui/src/components/translations/translation.tsx:53 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:53 msgid "{fileName} ({fileSizeString}) is too large (max {maxFileSizeString}) and an attempt will be made to reduce size when posting" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:63 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:63 msgid "{fileName} will be modified to support website requirements" msgstr "" @@ -42,6 +42,10 @@ msgstr "" msgid "Allow PostyBirb to insert an Ad into the description" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:15 +msgid "Allow resizing image" +msgstr "" + #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-metadata-manager.tsx:163 msgid "Alt Text" msgstr "" @@ -102,6 +106,10 @@ msgstr "" msgid "Clear" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:13 +msgid "Content warning" +msgstr "" + #: apps/postybirb-ui/src/components/form/fields/field-copy-button.tsx:10 msgid "Copied" msgstr "" @@ -174,15 +182,15 @@ msgstr "" msgid "Delete" msgstr "" -#: apps/postybirb-ui/src/external-translations.ts:5 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:8 msgid "Description" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:19 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:19 msgid "Description is greater than {maxLength} characters long" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:25 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:25 msgid "Description is less than {minLength} characters long" msgstr "" @@ -254,10 +262,14 @@ msgstr "" msgid "Failed to update" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:13 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:13 msgid "Failed to validate submission: {message}" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:16 +msgid "Feature" +msgstr "" + #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-spotlight/postybirb-spotlight.tsx:63 msgid "File submissions" msgstr "" @@ -436,7 +448,7 @@ msgstr "" msgid "Primary" msgstr "" -#: apps/postybirb-ui/src/external-translations.ts:8 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:11 msgid "Rating" msgstr "" @@ -455,7 +467,7 @@ msgctxt "import.override-title" msgid "Replace title" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:80 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:80 msgid "Requires at least {minLength} tags" msgstr "" @@ -531,6 +543,10 @@ msgstr "" msgid "Spanish" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:12 +msgid "Species" +msgstr "" + #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-metadata-manager.tsx:174 msgid "Spoiler Text" msgstr "" @@ -557,7 +573,7 @@ msgstr "" msgid "Submission templates" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:31 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:31 msgid "Submission will be split into {expectedBatchesToCreate} different submissions with {maxBatchSize} files each." msgstr "" @@ -589,17 +605,17 @@ msgstr "" msgid "Tag Groups" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:70 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:70 msgid "Tag limit reached ({currentLength} / {maxLength})" msgstr "" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:58 #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:150 -#: apps/postybirb-ui/src/external-translations.ts:6 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:9 msgid "Tags" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:92 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:92 msgid "Tags longer than {maxLength} characters will be skipped" msgstr "" @@ -644,27 +660,27 @@ msgstr "" msgid "Thumbnail" msgstr "" -#: apps/postybirb-ui/src/external-translations.ts:7 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:10 msgid "Title" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:104 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:104 msgid "Title is too long" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:102 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:102 msgid "Title is too long and will be truncated" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:118 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:118 msgid "Title is too short" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:136 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:136 msgid "Translation {id} not found" msgstr "" -#: apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx:230 +#: apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx:231 msgid "Unable to display form" msgstr "" @@ -684,7 +700,7 @@ msgstr "" msgid "Unschedule" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:42 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:42 msgid "Unsupported file type {mimeType}" msgstr "" @@ -713,6 +729,10 @@ msgstr "" msgid "Use custom description" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:14 +msgid "Use thumbnail" +msgstr "" + #: apps/postybirb-ui/src/website-components/discord/discord-login-view.tsx:86 msgid "Webhook is required" msgstr "" diff --git a/lang/es.po b/lang/es.po index 1939a43fb..b813f0c26 100644 --- a/lang/es.po +++ b/lang/es.po @@ -11,11 +11,11 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" -#: apps/postybirb-ui/src/components/translations/translation.tsx:53 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:53 msgid "{fileName} ({fileSizeString}) is too large (max {maxFileSizeString}) and an attempt will be made to reduce size when posting" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:63 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:63 msgid "{fileName} will be modified to support website requirements" msgstr "" @@ -40,6 +40,10 @@ msgstr "Añadir observador de carpeta" msgid "Allow PostyBirb to insert an Ad into the description" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:15 +msgid "Allow resizing image" +msgstr "" + #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-metadata-manager.tsx:163 msgid "Alt Text" msgstr "" @@ -100,6 +104,10 @@ msgstr "" msgid "Clear" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:13 +msgid "Content warning" +msgstr "" + #: apps/postybirb-ui/src/components/form/fields/field-copy-button.tsx:10 msgid "Copied" msgstr "" @@ -172,15 +180,15 @@ msgstr "Guardados por Defecto" msgid "Delete" msgstr "Borrar" -#: apps/postybirb-ui/src/external-translations.ts:5 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:8 msgid "Description" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:19 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:19 msgid "Description is greater than {maxLength} characters long" msgstr "La descripción sobrepasa los {maxLength} caracteres" -#: apps/postybirb-ui/src/components/translations/translation.tsx:25 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:25 msgid "Description is less than {minLength} characters long" msgstr "" @@ -252,10 +260,14 @@ msgstr "" msgid "Failed to update" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:13 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:13 msgid "Failed to validate submission: {message}" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:16 +msgid "Feature" +msgstr "" + #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-spotlight/postybirb-spotlight.tsx:63 msgid "File submissions" msgstr "" @@ -434,7 +446,7 @@ msgstr "" msgid "Primary" msgstr "Primario" -#: apps/postybirb-ui/src/external-translations.ts:8 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:11 msgid "Rating" msgstr "" @@ -453,7 +465,7 @@ msgctxt "import.override-title" msgid "Replace title" msgstr "Reemplazar Título" -#: apps/postybirb-ui/src/components/translations/translation.tsx:80 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:80 msgid "Requires at least {minLength} tags" msgstr "" @@ -529,6 +541,10 @@ msgstr "Tamaño" msgid "Spanish" msgstr "Español" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:12 +msgid "Species" +msgstr "" + #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-metadata-manager.tsx:174 msgid "Spoiler Text" msgstr "" @@ -555,7 +571,7 @@ msgstr "Publicación programada" msgid "Submission templates" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:31 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:31 msgid "Submission will be split into {expectedBatchesToCreate} different submissions with {maxBatchSize} files each." msgstr "" @@ -587,17 +603,17 @@ msgstr "" msgid "Tag Groups" msgstr "Grupos de Etiquetas" -#: apps/postybirb-ui/src/components/translations/translation.tsx:70 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:70 msgid "Tag limit reached ({currentLength} / {maxLength})" msgstr "" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:58 #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:150 -#: apps/postybirb-ui/src/external-translations.ts:6 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:9 msgid "Tags" msgstr "Etiquetas" -#: apps/postybirb-ui/src/components/translations/translation.tsx:92 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:92 msgid "Tags longer than {maxLength} characters will be skipped" msgstr "" @@ -642,27 +658,27 @@ msgstr "" msgid "Thumbnail" msgstr "Miniatura" -#: apps/postybirb-ui/src/external-translations.ts:7 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:10 msgid "Title" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:104 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:104 msgid "Title is too long" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:102 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:102 msgid "Title is too long and will be truncated" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:118 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:118 msgid "Title is too short" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:136 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:136 msgid "Translation {id} not found" msgstr "Traducción {id} no encontrada" -#: apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx:230 +#: apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx:231 msgid "Unable to display form" msgstr "" @@ -682,7 +698,7 @@ msgstr "Publicación desconocida" msgid "Unschedule" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:42 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:42 msgid "Unsupported file type {mimeType}" msgstr "" @@ -711,6 +727,10 @@ msgstr "" msgid "Use custom description" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:14 +msgid "Use thumbnail" +msgstr "" + #: apps/postybirb-ui/src/website-components/discord/discord-login-view.tsx:86 msgid "Webhook is required" msgstr "" diff --git a/lang/ru.po b/lang/ru.po index aa5d30411..a8cdeebf7 100644 --- a/lang/ru.po +++ b/lang/ru.po @@ -11,11 +11,11 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" -#: apps/postybirb-ui/src/components/translations/translation.tsx:53 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:53 msgid "{fileName} ({fileSizeString}) is too large (max {maxFileSizeString}) and an attempt will be made to reduce size when posting" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:63 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:63 msgid "{fileName} will be modified to support website requirements" msgstr "" @@ -40,6 +40,10 @@ msgstr "Добавить мониторинг папки" msgid "Allow PostyBirb to insert an Ad into the description" msgstr "Вставлять рекламу PostyBirb в описания постов" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:15 +msgid "Allow resizing image" +msgstr "Масштабировать изображения" + #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-metadata-manager.tsx:163 msgid "Alt Text" msgstr "Alt текст" @@ -100,6 +104,10 @@ msgstr "Выберите сайты" msgid "Clear" msgstr "Очистить" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:13 +msgid "Content warning" +msgstr "Предупреждение (CW)" + #: apps/postybirb-ui/src/components/form/fields/field-copy-button.tsx:10 msgid "Copied" msgstr "Копировать" @@ -172,15 +180,15 @@ msgstr "Опции по умолчанию сохранены" msgid "Delete" msgstr "Удалить" -#: apps/postybirb-ui/src/external-translations.ts:5 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:8 msgid "Description" msgstr "Описание" -#: apps/postybirb-ui/src/components/translations/translation.tsx:19 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:19 msgid "Description is greater than {maxLength} characters long" msgstr "Описание больше, чем {maxLength} символов длиной" -#: apps/postybirb-ui/src/components/translations/translation.tsx:25 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:25 msgid "Description is less than {minLength} characters long" msgstr "" @@ -252,10 +260,14 @@ msgstr "Не удалось отложить пост" msgid "Failed to update" msgstr "Не удалось обновить" -#: apps/postybirb-ui/src/components/translations/translation.tsx:13 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:13 msgid "Failed to validate submission: {message}" msgstr "" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:16 +msgid "Feature" +msgstr "" + #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-spotlight/postybirb-spotlight.tsx:63 msgid "File submissions" msgstr "Посты с файлами" @@ -423,7 +435,7 @@ msgstr "Опубликовать текст" #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-layout.tsx:72 msgid "Post Files" -msgstr "Опубликовать файлы" +msgstr "Файлы" #: apps/postybirb-ui/src/components/submissions/submission-view/submission-view-card/submission-view-actions/post-selected-submissions-action.tsx:46 msgid "Post Selected" @@ -434,14 +446,14 @@ msgstr "" msgid "Primary" msgstr "Основные значения" -#: apps/postybirb-ui/src/external-translations.ts:8 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:11 msgid "Rating" -msgstr "" +msgstr "Рейтинг" #: apps/postybirb-ui/src/components/submissions/submission-scheduler/submission-scheduler.tsx:25 msgctxt "internalSchedule.recurring" msgid "Recurring" -msgstr "" +msgstr "Повторяющееся" #: apps/postybirb-ui/src/components/submission-templates/template-picker-modal/template-picker-modal.tsx:193 msgctxt "import.override-description" @@ -453,9 +465,9 @@ msgctxt "import.override-title" msgid "Replace title" msgstr "Заменить заголовок" -#: apps/postybirb-ui/src/components/translations/translation.tsx:80 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:80 msgid "Requires at least {minLength} tags" -msgstr "" +msgstr "Нужно минимум {minLength} тегов" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/account-drawer/website-card.tsx:48 msgid "Reset" @@ -475,12 +487,12 @@ msgstr "Сохранить" #: apps/postybirb-ui/src/components/form/website-option-form/website-option-group-section.tsx:49 #: apps/postybirb-ui/src/components/form/website-option-form/website-option-group-section.tsx:109 msgid "Save current form values as the default values for future submissions" -msgstr "" +msgstr "Сохранить значения формы по умолчанию для использования в будущих постах" #: apps/postybirb-ui/src/components/form/website-option-form/website-option-group-section.tsx:56 #: apps/postybirb-ui/src/components/form/website-option-form/website-option-group-section.tsx:124 msgid "Save defaults" -msgstr "" +msgstr "Сохранить по умолчанию" #: apps/postybirb-ui/src/components/submissions/directory-watchers-view/directory-watchers-view.tsx:120 msgid "Save folder upload changes" @@ -496,24 +508,24 @@ msgstr "Отложить" #: apps/postybirb-ui/src/components/submissions/submission-view/submission-view-card/submission-view-multi-scheduler-modal.tsx:201 msgctxt "schedule.modal-header" msgid "Schedule" -msgstr "" +msgstr "Отложить" #: apps/postybirb-ui/src/components/submissions/submission-view/submission-view-card/submission-view-actions/schedule-submissions-action.tsx:24 msgid "Schedule Many" -msgstr "" +msgstr "Отложить несколько" #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-layout.tsx:148 #: apps/postybirb-ui/src/components/submissions/submission-view/submission-view-card/submission-view-actions/submission-view-actions.tsx:56 msgid "Search" -msgstr "" +msgstr "Поиск" #: apps/postybirb-ui/src/components/submissions/directory-watchers-view/directory-watchers-view.tsx:69 msgid "Select folder" -msgstr "" +msgstr "Выбрать папку" #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-layout.tsx:80 msgid "Send Messages" -msgstr "" +msgstr "Сообщения" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/settings-drawer.tsx:155 #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-layout.tsx:105 @@ -529,22 +541,26 @@ msgstr "Размер" msgid "Spanish" msgstr "Испанский" +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:12 +msgid "Species" +msgstr "Виды" + #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-metadata-manager.tsx:174 msgid "Spoiler Text" -msgstr "" +msgstr "Спойлер" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/settings-drawer.tsx:66 msgid "Startup Settings" -msgstr "" +msgstr "Настройки запуска" #: apps/postybirb-ui/src/components/submissions/submission-view/submission-view-card/submission-view-card-actions.tsx:49 msgid "Submission duplicated" -msgstr "" +msgstr "Пост дублирован" #: apps/postybirb-ui/src/components/submissions/submission-view/submission-view-card/submission-view-card-actions.tsx:146 #: apps/postybirb-ui/src/pages/submission/edit-submission-page.tsx:180 msgid "Submission queued" -msgstr "" +msgstr "Пост в очереди" #: apps/postybirb-ui/src/components/submissions/submission-view/submission-view-card/submission-view-card-actions.tsx:117 #: apps/postybirb-ui/src/pages/submission/edit-submission-page.tsx:79 @@ -553,9 +569,9 @@ msgstr "Пост отложен" #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-spotlight/postybirb-spotlight.tsx:85 msgid "Submission templates" -msgstr "" +msgstr "Шаблоны постов" -#: apps/postybirb-ui/src/components/translations/translation.tsx:31 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:31 msgid "Submission will be split into {expectedBatchesToCreate} different submissions with {maxBatchSize} files each." msgstr "" @@ -571,7 +587,7 @@ msgstr "Тег" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-converter-drawer.tsx:78 msgid "Tag converter updated" -msgstr "" +msgstr "Конвертер тегов обновлен" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-converter-drawer.tsx:223 #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-layout.tsx:96 @@ -580,24 +596,24 @@ msgstr "Конвертер тегов" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:85 msgid "Tag group updated" -msgstr "" +msgstr "Группа тегов обновлена" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:203 #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-layout.tsx:88 msgid "Tag Groups" -msgstr "Группа тегов" +msgstr "Группы тегов" -#: apps/postybirb-ui/src/components/translations/translation.tsx:70 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:70 msgid "Tag limit reached ({currentLength} / {maxLength})" msgstr "" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:58 #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:150 -#: apps/postybirb-ui/src/external-translations.ts:6 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:9 msgid "Tags" msgstr "Теги" -#: apps/postybirb-ui/src/components/translations/translation.tsx:92 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:92 msgid "Tags longer than {maxLength} characters will be skipped" msgstr "" @@ -642,29 +658,29 @@ msgstr "" msgid "Thumbnail" msgstr "Набросок (Маленькая картинка)" -#: apps/postybirb-ui/src/external-translations.ts:7 +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:10 msgid "Title" -msgstr "" +msgstr "Название" -#: apps/postybirb-ui/src/components/translations/translation.tsx:104 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:104 msgid "Title is too long" -msgstr "" +msgstr "Название слишком длинное" -#: apps/postybirb-ui/src/components/translations/translation.tsx:102 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:102 msgid "Title is too long and will be truncated" -msgstr "" +msgstr "Название слишком длинное и будет сокращено" -#: apps/postybirb-ui/src/components/translations/translation.tsx:118 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:118 msgid "Title is too short" -msgstr "" +msgstr "Название слишком короткое" -#: apps/postybirb-ui/src/components/translations/translation.tsx:136 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:136 msgid "Translation {id} not found" msgstr "Перевод {id} не найден" -#: apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx:230 +#: apps/postybirb-ui/src/components/form/website-option-form/website-option-form.tsx:231 msgid "Unable to display form" -msgstr "" +msgstr "Не удалось показать форму" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/account-drawer/website-card.tsx:116 #: apps/postybirb-ui/src/components/submission-templates/template-picker-modal/template-picker-modal.tsx:104 @@ -682,9 +698,9 @@ msgstr "Неизвестный пост" msgid "Unschedule" msgstr "" -#: apps/postybirb-ui/src/components/translations/translation.tsx:42 +#: apps/postybirb-ui/src/components/translations/validation-translation.tsx:42 msgid "Unsupported file type {mimeType}" -msgstr "" +msgstr "Неподдерживаемый тип файла {mimeType}" #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-converter-drawer.tsx:91 #: apps/postybirb-ui/src/app/postybirb-layout/drawers/tag-group-drawer.tsx:98 @@ -693,7 +709,7 @@ msgstr "Обновить" #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-card-file-actions.tsx:184 msgid "Update file" -msgstr "" +msgstr "Загрузить файл" #: apps/postybirb-ui/src/app/postybirb-layout/postybirb-update-button.tsx:42 msgid "Update PostyBirb" @@ -701,15 +717,19 @@ msgstr "Обновить PostyBirb" #: apps/postybirb-ui/src/components/submissions/submission-uploader/submission-uploader.tsx:176 msgid "Upload" -msgstr "" +msgstr "Загрузить" #: apps/postybirb-ui/src/components/submissions/submission-edit-form/submission-file-manager/submission-file-card/file-card-file-actions.tsx:233 msgid "Upload new thumbnail" -msgstr "" +msgstr "Загрузить новую миниатюру" #: apps/postybirb-ui/src/components/form/fields/description-field.tsx:29 msgid "Use custom description" -msgstr "" +msgstr "Кастомное описание" + +#: apps/postybirb-ui/src/components/form/fields/field-translations.ts:14 +msgid "Use thumbnail" +msgstr "Использовать миниатюру" #: apps/postybirb-ui/src/website-components/discord/discord-login-view.tsx:86 msgid "Webhook is required" diff --git a/libs/form-builder/jest.config.ts b/libs/form-builder/jest.config.ts index 988d235b7..7545e71b3 100644 --- a/libs/form-builder/jest.config.ts +++ b/libs/form-builder/jest.config.ts @@ -1,17 +1,18 @@ /* eslint-disable */ export default { + prettierPath: null, displayName: 'form-builder', preset: '../../jest.preset.js', globals: {}, testEnvironment: 'node', transform: { - '^.+\\.[tj]sx?$': [ + '^.+\\.[tj]s?$': [ 'ts-jest', { tsconfig: '/tsconfig.spec.json', }, ], }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + moduleFileExtensions: ['js', 'ts', 'html'], coverageDirectory: '../../coverage/libs/form-builder', }; diff --git a/libs/form-builder/src/lib/decorators/boolean-field.decorator.ts b/libs/form-builder/src/lib/decorators/boolean-field.decorator.ts index 7783f469b..ebed6f42c 100644 --- a/libs/form-builder/src/lib/decorators/boolean-field.decorator.ts +++ b/libs/form-builder/src/lib/decorators/boolean-field.decorator.ts @@ -1,23 +1,9 @@ /* eslint-disable no-param-reassign */ import 'reflect-metadata'; -import { FieldType } from '../types/field'; -import { PrimitiveRecord } from '../types/primitive-record'; -import { assignMetadata } from '../utils/assign-metadata'; +import { createFieldDecorator } from '../utils/assign-metadata'; -type BooleanFormField = 'checkbox'; -const TYPE_KEY = 'boolean'; - -export type BooleanFieldType = - FieldType; - -export function BooleanField( - options: BooleanFieldType, -): PropertyDecorator { - options.type = TYPE_KEY; - if (!options.formField) { - options.formField = 'checkbox'; - } - return (target, propertyKey) => { - assignMetadata(target, propertyKey, TYPE_KEY, options); - }; -} +export const BooleanField = createFieldDecorator('boolean')({ + defaults: { + formField: 'checkbox', + }, +}); diff --git a/libs/form-builder/src/lib/decorators/description-field.decorator.ts b/libs/form-builder/src/lib/decorators/description-field.decorator.ts index e316e8c60..6a78b0c1d 100644 --- a/libs/form-builder/src/lib/decorators/description-field.decorator.ts +++ b/libs/form-builder/src/lib/decorators/description-field.decorator.ts @@ -1,27 +1,14 @@ /* eslint-disable no-param-reassign */ -import { DescriptionValue } from '@postybirb/types'; +import { DefaultDescriptionValue, DescriptionValue } from '@postybirb/types'; import 'reflect-metadata'; -import { FieldType } from '../types/field'; -import { PrimitiveRecord } from '../types/primitive-record'; -import { assignMetadata } from '../utils/assign-metadata'; +import { createFieldDecorator } from '../utils/assign-metadata'; -type DescriptionFormField = 'description'; -const TYPE_KEY = 'description'; - -export type DescriptionFieldType = - FieldType; - -export function DescriptionField( - options: DescriptionFieldType, -): PropertyDecorator { - options.type = TYPE_KEY; - if (!options.formField) { - options.formField = 'description'; - } - if (!options.i18nLabel) { - options.i18nLabel = 'form.descriptions'; - } - return (target, propertyKey) => { - assignMetadata(target, propertyKey, TYPE_KEY, options); - }; -} +export const DescriptionField = createFieldDecorator( + 'description', +)({ + defaults: { + label: 'description', + formField: 'description', + defaultValue: DefaultDescriptionValue(), + }, +}); diff --git a/libs/form-builder/src/lib/decorators/radio-field.decorator.ts b/libs/form-builder/src/lib/decorators/radio-field.decorator.ts index f38bebf33..bf5cbaabb 100644 --- a/libs/form-builder/src/lib/decorators/radio-field.decorator.ts +++ b/libs/form-builder/src/lib/decorators/radio-field.decorator.ts @@ -1,31 +1,21 @@ /* eslint-disable no-param-reassign */ import 'reflect-metadata'; import { Primitive } from 'type-fest'; -import { FieldType } from '../types/field'; -import { PrimitiveRecord } from '../types/primitive-record'; -import { assignMetadata } from '../utils/assign-metadata'; - -type RadioFormField = 'radio'; -const TYPE_KEY = 'radio'; +import { createFieldDecorator } from '../utils/assign-metadata'; export type RadioOption = { label: string; value: Primitive; }; -export type RadioFieldType = - FieldType & { - options: RadioOption[]; - layout?: 'vertical' | 'horizontal'; - }; +type ExtraOptions = { + options: RadioOption[]; + layout?: 'vertical' | 'horizontal'; +}; -export function RadioField( - options: RadioFieldType, -): PropertyDecorator { - options.type = TYPE_KEY; - options.formField = 'radio'; - options.layout = options.layout ?? 'horizontal'; - return (target, propertyKey) => { - assignMetadata(target, propertyKey, TYPE_KEY, options); - }; -} +export const RadioField = createFieldDecorator('radio')({ + defaults: { + formField: 'radio', + layout: 'vertical', + }, +}); diff --git a/libs/form-builder/src/lib/decorators/rating.decorator.ts b/libs/form-builder/src/lib/decorators/rating.decorator.ts index d0779477d..07a2471b9 100644 --- a/libs/form-builder/src/lib/decorators/rating.decorator.ts +++ b/libs/form-builder/src/lib/decorators/rating.decorator.ts @@ -1,31 +1,43 @@ /* eslint-disable no-param-reassign */ import { SubmissionRating } from '@postybirb/types'; import 'reflect-metadata'; -import { FieldType } from '../types/field'; -import { PrimitiveRecord } from '../types/primitive-record'; -import { assignMetadata } from '../utils/assign-metadata'; - -type RatingFormField = 'rating'; -const TYPE_KEY = 'rating'; +import { createFieldDecorator } from '../utils/assign-metadata'; export type RatingOption = { label: string; value: SubmissionRating | undefined; }; -export type RatingFieldType = - FieldType & { - options: RatingOption[]; - layout?: 'vertical' | 'horizontal'; - }; +type ExtraOptions = { + options: RatingOption[]; + layout?: 'vertical' | 'horizontal'; +}; -export function RatingField( - options: RatingFieldType, -): PropertyDecorator { - options.type = TYPE_KEY; - options.formField = TYPE_KEY; - options.layout = options.layout ?? 'horizontal'; - return (target, propertyKey) => { - assignMetadata(target, propertyKey, TYPE_KEY, options); - }; -} +export const RatingField = createFieldDecorator( + 'rating', +)({ + defaults: { + label: 'rating', + layout: 'vertical', + formField: 'rating', + defaultValue: undefined, + options: [ + { + label: 'General', + value: SubmissionRating.GENERAL, + }, + { + label: 'Mature', + value: SubmissionRating.MATURE, + }, + { + label: 'Adult', + value: SubmissionRating.ADULT, + }, + { + label: 'Extreme', + value: SubmissionRating.EXTREME, + }, + ], + }, +}); diff --git a/libs/form-builder/src/lib/decorators/select-field.decorator.ts b/libs/form-builder/src/lib/decorators/select-field.decorator.ts index 61de80d73..1af738678 100644 --- a/libs/form-builder/src/lib/decorators/select-field.decorator.ts +++ b/libs/form-builder/src/lib/decorators/select-field.decorator.ts @@ -1,33 +1,23 @@ /* eslint-disable no-param-reassign */ import 'reflect-metadata'; -import { FieldType } from '../types/field'; -import { PrimitiveRecord } from '../types/primitive-record'; -import { assignMetadata } from '../utils/assign-metadata'; +import { createFieldDecorator } from '../utils/assign-metadata'; -type SelectFormField = 'select'; -const TYPE_KEY = 'select'; - -export type SelectOption = { +type SelectOption = { label: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - value: any; + value: unknown; options?: SelectOption[]; }; -export type SelectFieldType = - // eslint-disable-next-line @typescript-eslint/no-explicit-any - FieldType & { - options: SelectOption[]; - allowMultiple: boolean; - }; +type ExtraOptions = { + options: SelectOption[]; + allowMultiple: boolean; +}; -export function SelectField( - options: SelectFieldType, -): PropertyDecorator { - options.type = TYPE_KEY; - options.formField = 'select'; - options.allowMultiple = options.allowMultiple ?? false; - return (target, propertyKey) => { - assignMetadata(target, propertyKey, TYPE_KEY, options); - }; -} +export const SelectField = createFieldDecorator( + 'select', +)({ + defaults: { + formField: 'select', + allowMultiple: false, + }, +}); diff --git a/libs/form-builder/src/lib/decorators/tag-field.decorator.ts b/libs/form-builder/src/lib/decorators/tag-field.decorator.ts index ebe948ba6..e3cddf3e6 100644 --- a/libs/form-builder/src/lib/decorators/tag-field.decorator.ts +++ b/libs/form-builder/src/lib/decorators/tag-field.decorator.ts @@ -1,30 +1,14 @@ /* eslint-disable no-param-reassign */ -import { TagValue } from '@postybirb/types'; +import { DefaultTagValue, TagValue } from '@postybirb/types'; import 'reflect-metadata'; -import { FieldType } from '../types/field'; -import { PrimitiveRecord } from '../types/primitive-record'; -import { assignMetadata } from '../utils/assign-metadata'; +import { createFieldDecorator } from '../utils/assign-metadata'; -type TagFormField = 'tag'; -const TYPE_KEY = 'tag'; +type TagExtraFields = { minTags?: number; maxTags?: number }; -export type TagFieldType = - FieldType & { - minTags?: number; - maxTags?: number; - }; - -export function TagField( - options: TagFieldType, -): PropertyDecorator { - options.type = TYPE_KEY; - if (!options.formField) { - options.formField = 'tag'; - } - if (!options.i18nLabel) { - options.i18nLabel = 'form.tags'; - } - return (target, propertyKey) => { - assignMetadata(target, propertyKey, TYPE_KEY, options); - }; -} +export const TagField = createFieldDecorator('tag')({ + defaults: { + formField: 'tag', + label: 'tags', + defaultValue: DefaultTagValue(), + }, +}); diff --git a/libs/form-builder/src/lib/decorators/text-field.decorator.ts b/libs/form-builder/src/lib/decorators/text-field.decorator.ts index 9ae5402a1..c7c67f4c3 100644 --- a/libs/form-builder/src/lib/decorators/text-field.decorator.ts +++ b/libs/form-builder/src/lib/decorators/text-field.decorator.ts @@ -1,26 +1,15 @@ /* eslint-disable no-param-reassign */ import 'reflect-metadata'; -import { FieldType } from '../types/field'; -import { PrimitiveRecord } from '../types/primitive-record'; -import { assignMetadata } from '../utils/assign-metadata'; +import { createFieldDecorator } from '../utils/assign-metadata'; -type TextFormField = 'input' | 'textarea'; -const TYPE_KEY = 'text'; +type ExtraOptions = { + maxLength?: number; + formField: 'input' | 'textarea'; +}; -export type TextFieldType = - FieldType & { - maxLength?: number; - }; - -export function TextField( - options: TextFieldType, -): PropertyDecorator { - options.type = TYPE_KEY; - options.maxLength = options.maxLength ?? undefined; - if (!options.formField) { - options.formField = 'input'; - } - return (target, propertyKey) => { - assignMetadata(target, propertyKey, TYPE_KEY, options); - }; -} +export const TextField = createFieldDecorator('text')({ + defaults: { + defaultValue: '', + formField: 'input', + }, +}); diff --git a/libs/form-builder/src/lib/form-builder.spec.ts b/libs/form-builder/src/lib/form-builder.spec.ts index c3031d1ee..8b4eda75d 100644 --- a/libs/form-builder/src/lib/form-builder.spec.ts +++ b/libs/form-builder/src/lib/form-builder.spec.ts @@ -1,51 +1,74 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable max-classes-per-file */ -import { BooleanField, TextField } from './decorators'; +import { BooleanField, TagField, TextField } from './decorators'; import { formBuilder } from './form-builder'; describe('formBuilder', () => { it('should build boolean types', () => { class BooleanType { - @BooleanField({ label: 'boolean field', defaultValue: false }) + @BooleanField({ label: 'description', defaultValue: false }) public field: boolean; } expect(formBuilder(new BooleanType(), {})).toEqual({ field: { - label: 'boolean field', + label: 'description', defaultValue: false, type: 'boolean', - formField: 'switch', + formField: 'checkbox', row: Number.MAX_SAFE_INTEGER, - col: Number.MAX_SAFE_INTEGER, + col: 0, }, }); }); it('should build text types', () => { class TextType { - @TextField({ label: 'text field', defaultValue: 'Hello' }) + @TextField({ label: 'description', defaultValue: 'Hello' }) public field: string; } expect(formBuilder(new TextType(), {})).toEqual({ field: { - label: 'text field', + label: 'description', defaultValue: 'Hello', type: 'text', formField: 'input', row: Number.MAX_SAFE_INTEGER, - col: Number.MAX_SAFE_INTEGER, + col: 0, }, }); }); + it('should build tag fields', () => { + class TestType { + @TagField({}) + field: string[]; + } + + expect(formBuilder(new TestType(), {})).toMatchInlineSnapshot(` +{ + "field": { + "col": 0, + "defaultValue": { + "overrideDefault": false, + "tags": [], + }, + "formField": "tag", + "label": "tags", + "row": 9007199254740991, + "type": "tag", + }, +} +`); + }); + it('should support defaultFrom', () => { type TestType = { testBoolean: true }; const test: TestType = { testBoolean: true }; class BooleanType { @BooleanField({ - label: 'boolean field', + label: 'description', defaultValue: false, defaultFrom: 'testBoolean', }) @@ -54,13 +77,13 @@ describe('formBuilder', () => { expect(formBuilder(new BooleanType(), test)).toEqual({ field: { - label: 'boolean field', + label: 'description', defaultFrom: 'testBoolean', defaultValue: test.testBoolean, type: 'boolean', - formField: 'switch', + formField: 'checkbox', row: Number.MAX_SAFE_INTEGER, - col: Number.MAX_SAFE_INTEGER, + col: 0, }, }); }); diff --git a/libs/form-builder/src/lib/form-builder.ts b/libs/form-builder/src/lib/form-builder.ts index bc56fba75..294b1f699 100644 --- a/libs/form-builder/src/lib/form-builder.ts +++ b/libs/form-builder/src/lib/form-builder.ts @@ -3,20 +3,17 @@ import { METADATA_KEY } from '../constants'; import { FormBuilderMetadata } from './types/form-builder-metadata'; import { PrimitiveRecord } from './types/primitive-record'; -export function formBuilder( +export function formBuilder( target: object, - data: T, -): FormBuilderMetadata { - const metadata: FormBuilderMetadata = JSON.parse( + data: PrimitiveRecord, +): FormBuilderMetadata { + const metadata = JSON.parse( JSON.stringify(Reflect.getMetadata(METADATA_KEY, target.constructor)), - ); + ) as FormBuilderMetadata; - Object.values(metadata).forEach((value) => { - if (value.defaultFrom) { - // eslint-disable-next-line no-param-reassign, @typescript-eslint/no-explicit-any - value.defaultValue = data[value.defaultFrom] as any; - } - }); + for (const value of Object.values(metadata)) { + if (value.defaultFrom) value.defaultValue = data[value.defaultFrom]; + } return metadata; } diff --git a/libs/form-builder/src/lib/types/field-aggregate.ts b/libs/form-builder/src/lib/types/field-aggregate.ts index 417c0e701..c4c4eca46 100644 --- a/libs/form-builder/src/lib/types/field-aggregate.ts +++ b/libs/form-builder/src/lib/types/field-aggregate.ts @@ -1,19 +1,31 @@ import { - BooleanFieldType, - DescriptionFieldType, - RadioFieldType, - RatingFieldType, - TextFieldType, + BooleanField, + DescriptionField, + RadioField, + RatingField, + SelectField, + TagField, + TextField, } from '../decorators'; -import { SelectFieldType } from '../decorators/select-field.decorator'; -import { TagFieldType } from '../decorators/tag-field.decorator'; -import { PrimitiveRecord } from './primitive-record'; +import { ExtractFieldTypeFromDecorator } from '../utils/assign-metadata'; -export type FieldAggregateType = - | BooleanFieldType - | TextFieldType - | RadioFieldType - | RatingFieldType - | TagFieldType - | DescriptionFieldType - | SelectFieldType; +export type RatingFieldType = ExtractFieldTypeFromDecorator; +export type TagFieldType = ExtractFieldTypeFromDecorator; +export type DescriptionFieldType = ExtractFieldTypeFromDecorator< + typeof DescriptionField +>; +export type TextFieldType = ExtractFieldTypeFromDecorator; +export type SelectFieldType = ExtractFieldTypeFromDecorator; +export type BooleanFieldType = ExtractFieldTypeFromDecorator< + typeof BooleanField +>; +export type RadioFieldType = ExtractFieldTypeFromDecorator; + +export type FieldAggregateType = + | BooleanFieldType + | TextFieldType + | RadioFieldType + | RatingFieldType + | TagFieldType + | DescriptionFieldType + | SelectFieldType; diff --git a/libs/form-builder/src/lib/types/field.ts b/libs/form-builder/src/lib/types/field.ts index c749e85bd..63d681478 100644 --- a/libs/form-builder/src/lib/types/field.ts +++ b/libs/form-builder/src/lib/types/field.ts @@ -1,6 +1,18 @@ +// eslint-typescript doesn't counts @link as a var use. We use it +// to make jump-to defenitions and to simplify DX +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import { FieldTranslationId, FieldTranslations } from '@postybirb/types'; import { PrimitiveRecord } from './primitive-record'; -export type FieldType = { +type Translations = + typeof import('apps/postybirb-ui/src/components/form/fields/field-translations.ts'); + +export type FieldType< + V, + F extends string, + T extends PrimitiveRecord | unknown = unknown, +> = { /** * Pulls a default value from a key property */ @@ -27,14 +39,9 @@ export type FieldType = { formField?: F; /** - * The label to display for the field. - */ - label: string; - - /** - * Translation label (wip) + * The translation id of the label to display. All possible values can be found here: {@link Translations.fieldLabelTranslations|fieldLabelTranslations} and here: {@link FieldTranslations}. */ - i18nLabel?: string; + label: FieldTranslationId; /** * Whether the field is considered required. diff --git a/libs/form-builder/src/lib/types/form-builder-metadata.ts b/libs/form-builder/src/lib/types/form-builder-metadata.ts index 8a0961ac2..1abaed0ef 100644 --- a/libs/form-builder/src/lib/types/form-builder-metadata.ts +++ b/libs/form-builder/src/lib/types/form-builder-metadata.ts @@ -1,7 +1,3 @@ import { FieldAggregateType } from './field-aggregate'; -import { PrimitiveRecord } from './primitive-record'; -export type FormBuilderMetadata = Record< - string, - FieldAggregateType ->; +export type FormBuilderMetadata = Record; diff --git a/libs/form-builder/src/lib/utils/assign-metadata.ts b/libs/form-builder/src/lib/utils/assign-metadata.ts index 9c3ce379f..300ab68c0 100644 --- a/libs/form-builder/src/lib/utils/assign-metadata.ts +++ b/libs/form-builder/src/lib/utils/assign-metadata.ts @@ -1,34 +1,118 @@ /* eslint-disable no-param-reassign */ import 'reflect-metadata'; import { METADATA_KEY } from '../../constants'; -import { FieldAggregateType } from '../types'; +import { FieldAggregateType, FieldType } from '../types'; import { FormBuilderMetadata } from '../types/form-builder-metadata'; import { PrimitiveRecord } from '../types/primitive-record'; -export function assignMetadata( - target: object, - propertyKey: string | symbol, - fieldKey: string, - options: FieldAggregateType, -): void { - if (typeof propertyKey === 'symbol') return; +/** + * Make keys V in type T partial + */ +export type PartialOnly = Omit & + Partial<{ + [P in V]: V extends keyof T ? T[V] : never; + }>; - const proto = target.constructor; - const fields: FormBuilderMetadata = - Reflect.getMetadata(METADATA_KEY, proto) || {}; +/** + * Field decorator creator superfunction + * + * @param type - Type of the decorator to create. Will be set to the {@link FieldType.type} field. + * @returns Creator function + */ +export function createFieldDecorator< + FieldValue, + ExtraFields extends object = object, + TypeKey extends string = string, +>(type: TypeKey) { + // Note that we cant just create one function that returns a decorator + // because if you specify generics by hand, e.g. createFieldDecorator('type', {}) + // it will stop narrowing all other generic types such as Defaults + /** + * Function used to finalize field decorator options + */ + return function create< + Defaults extends + | Partial & ExtraFields> + | unknown, + >(field: { + /** + * Default values of the field. If label or defaultValue are provided, they will be not required when using a decorator + * + * Example: + * ```ts + * const WithDefaults = createFieldDecorator('with')({ + * defaults: { + * label: 'title', + * defaultValue: '' + * } + * }) + * const WithoutDefaults = createFieldDecorator('without')({}) + * + * class TestType { + * WithDefaults({}) + * field1: string + * + * WithoutDefaults({}) // Error! Missing properties label and defaultValue + * field2: string + * } + * + * ``` + */ + defaults?: Defaults; + /** + * Function that being called on decorator applying. Can be used to change options or to change applied value + * + * @param options - Options to be changed + */ + onCreate?: ( + options: FieldType, + target: object, + propertyKey: string | symbol, + ) => void; + }) { + function decorator( + options: PartialOnly< + FieldType & ExtraFields, + keyof Defaults + >, + ): PropertyDecorator { + if (field.defaults) + for (const [key, value] of Object.entries(field.defaults)) { + options[key] ??= value; + } - if (!fields[propertyKey]) { - fields[propertyKey] = options; - } + const fieldOptions = options as FieldType & + ExtraFields; - if (options.row === undefined) { - options.row = Number.MAX_SAFE_INTEGER; - } + fieldOptions.type ??= type; + fieldOptions.row ??= Number.MAX_SAFE_INTEGER; + fieldOptions.col ??= 0; - if (options.col === undefined) { - options.col = 0; - } + return (target, propertyKey) => { + if (typeof propertyKey === 'symbol') return; - fields[propertyKey] = options; - Reflect.defineMetadata(METADATA_KEY, fields, proto); + const proto = target.constructor; + const fields: FormBuilderMetadata = + Reflect.getMetadata(METADATA_KEY, proto) || {}; + + field.onCreate?.( + fieldOptions as unknown as FieldType, + target, + propertyKey, + ); + + fields[propertyKey] = fieldOptions as unknown as FieldAggregateType; + + Reflect.defineMetadata(METADATA_KEY, fields, proto); + }; + } + + return decorator as typeof decorator & { + field: FieldType & ExtraFields; + }; + }; } + +export type ExtractFieldTypeFromDecorator = D extends { field: infer T } + ? T + : D; diff --git a/libs/form-builder/tsconfig.json b/libs/form-builder/tsconfig.json index 62ebbd946..b8241b775 100644 --- a/libs/form-builder/tsconfig.json +++ b/libs/form-builder/tsconfig.json @@ -2,6 +2,9 @@ "extends": "../../tsconfig.base.json", "files": [], "include": [], + "compilerOptions": { + "experimentalDecorators": true + }, "references": [ { "path": "./tsconfig.lib.json" diff --git a/libs/fs/src/lib/fs.spec.ts b/libs/fs/src/lib/fs.spec.ts index 141dca993..c575150fe 100644 --- a/libs/fs/src/lib/fs.spec.ts +++ b/libs/fs/src/lib/fs.spec.ts @@ -1,12 +1,12 @@ -import { rmdirSync } from 'fs'; +import { rmSync } from 'fs'; import { join } from 'path'; -import { POSTYBIRB_DIRECTORY, initializeDirectories } from './directories'; +import { initializeDirectories, POSTYBIRB_DIRECTORY } from './directories'; import { - writeSync, - readSync, - writeJsonSync, readJsonSync, + readSync, removeFileSync, + writeJsonSync, + writeSync, } from './fs'; let filepath: string; @@ -18,7 +18,7 @@ beforeEach(() => { }); afterAll(() => { - rmdirSync(POSTYBIRB_DIRECTORY, { recursive: true }); + rmSync(POSTYBIRB_DIRECTORY, { recursive: true, force: true }); }); describe('PostyBirbFS', () => { diff --git a/libs/http/jest.config.ts b/libs/http/jest.config.ts index f48528136..81ddabe0a 100644 --- a/libs/http/jest.config.ts +++ b/libs/http/jest.config.ts @@ -15,5 +15,4 @@ export default { coverageDirectory: '../../coverage/libs/http', runner: '@kayahr/jest-electron-runner/main', testEnvironment: 'node', - verbose: false, }; diff --git a/libs/types/src/models/index.ts b/libs/types/src/models/index.ts index 871193773..8638dbba1 100644 --- a/libs/types/src/models/index.ts +++ b/libs/types/src/models/index.ts @@ -11,6 +11,7 @@ export * from './settings/settings-options.interface'; export * from './settings/settings.interface'; export * from './submission/default-submission-file-props'; export * from './submission/description-value.type'; +export * from './submission/field-translation.type'; export * from './submission/file-submission/file-metadata-fields.type'; export * from './submission/file-submission/file-metadata.type'; export * from './submission/file-submission/file-submission'; diff --git a/libs/types/src/models/submission/field-translation.type.ts b/libs/types/src/models/submission/field-translation.type.ts new file mode 100644 index 000000000..cbef07e37 --- /dev/null +++ b/libs/types/src/models/submission/field-translation.type.ts @@ -0,0 +1,12 @@ +export interface FieldTranslations { + title: true; + tags: true; + description: true; + rating: true; + contentWarning: true; + useThumbnail: true; + allowResize: true; + feature: true; +} + +export type FieldTranslationId = keyof FieldTranslations; diff --git a/libs/types/src/models/tag/default-tag-value.ts b/libs/types/src/models/tag/default-tag-value.ts index 8dc0da32b..68762c5f7 100644 --- a/libs/types/src/models/tag/default-tag-value.ts +++ b/libs/types/src/models/tag/default-tag-value.ts @@ -1,6 +1,6 @@ import { TagValue } from './tag-value.type'; -/** Default tag value @type {TagValue} */ +/** Default tag value {@link TagValue} */ export const DefaultTagValue = (): TagValue => ({ overrideDefault: false, tags: [], diff --git a/package.json b/package.json index 89e9c4966..2f3dad979 100644 --- a/package.json +++ b/package.json @@ -12,33 +12,27 @@ "main": "dist/apps/postybirb/main.js", "scripts": { "nx": "nx", - "start": "nx run-many --target=serve --projects=postybirb,postybirb-ui --parallel", - "build": "nx run-many --target=build --projects=postybirb,postybirb-ui --parallel", - "build:prod": "nx run-many --target=build --configuration=production --projects=postybirb,postybirb-ui --parallel", + "start": "nx run-many -t serve --projects=postybirb,postybirb-ui --parallel", + "build": "nx run-many -t build --projects=postybirb,postybirb-ui --parallel", + "build:prod": "nx run-many -t build --configuration=production --projects=postybirb,postybirb-ui --parallel", "lingui:extract": "lingui extract --clean", "make": "electron-builder -w", - "test": "nx test", "test:client-server": "nx test client-server && rimraf test", + "test": "nx run-many -t test --parallel", "lint": "nx run-many -t lint --parallel --fix", - "e2e": "nx e2e", - "affected:apps": "nx affected:apps", - "affected:libs": "nx affected:libs", - "affected:build": "nx affected:build", - "affected:e2e": "nx affected:e2e", - "affected:test": "nx affected:test --all", - "affected:lint": "nx affected:lint --parallel", + "format": "prettier -w apps libs", + "affected:build": "nx affected: -t build", + "affected:test": "nx affected -t test", + "affected:lint": "nx affected -t lint --parallel", "affected:dep-graph": "nx affected:dep-graph", "affected": "nx affected", - "format": "nx format:write", - "format:write": "nx format:write", - "format:check": "nx format:check", "update": "nx migrate latest", - "workspace-generator": "nx workspace-generator", "dep-graph": "nx dep-graph", "help": "nx help", "postinstall": "run-p --continue-on-error postinstall:*", "postinstall:deps": "exitzero electron-builder install-app-deps", "postinstall:i18n": "lingui extract --clean", + "postinstall:apply-patches": "patch-package", "setup": "run-s setup:husky", "setup:husky": "husky install" }, @@ -122,6 +116,7 @@ }, "devDependencies": { "@babel/core": "^7.14.5", + "@babel/plugin-proposal-decorators": "^7.25.9", "@babel/preset-env": "7.12.13", "@babel/preset-react": "^7.14.5", "@babel/preset-typescript": "7.12.13", @@ -208,4 +203,4 @@ "webpack-node-externals": "^3.0.0" }, "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" -} +} \ No newline at end of file diff --git a/patches/@kayahr+jest-electron-runner+29.14.0.patch b/patches/@kayahr+jest-electron-runner+29.14.0.patch new file mode 100644 index 000000000..497880430 --- /dev/null +++ b/patches/@kayahr+jest-electron-runner+29.14.0.patch @@ -0,0 +1,30 @@ +diff --git a/node_modules/@kayahr/jest-electron-runner/lib/main/electron/TestRunner.js b/node_modules/@kayahr/jest-electron-runner/lib/main/electron/TestRunner.js +index 4485862..12e0042 100644 +--- a/node_modules/@kayahr/jest-electron-runner/lib/main/electron/TestRunner.js ++++ b/node_modules/@kayahr/jest-electron-runner/lib/main/electron/TestRunner.js +@@ -73,7 +73,9 @@ async function startWorker(rootDir, target, config) { + // Ignored + } + } +- child.kill("SIGKILL"); ++ try { ++ child.kill("SIGKILL"); ++ } catch {} + }); + return child; + }); +diff --git a/node_modules/@kayahr/jest-electron-runner/lib/main/rpc/RPCProcess.js b/node_modules/@kayahr/jest-electron-runner/lib/main/rpc/RPCProcess.js +index 19ffdd5..bd9f53b 100644 +--- a/node_modules/@kayahr/jest-electron-runner/lib/main/rpc/RPCProcess.js ++++ b/node_modules/@kayahr/jest-electron-runner/lib/main/rpc/RPCProcess.js +@@ -74,7 +74,9 @@ class RPCProcess { + // Ignored + } + } +- this.subProcess?.kill("SIGKILL"); ++ try { ++ this.subProcess?.kill("SIGKILL"); ++ } catch {} + delete this.server; + this.isAlive = false; + } diff --git a/yarn.lock b/yarn.lock index 04f011266..9332d0441 100644 --- a/yarn.lock +++ b/yarn.lock @@ -263,6 +263,15 @@ "@babel/highlight" "^7.24.7" picocolors "^1.0.0" +"@babel/code-frame@^7.25.9": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== + dependencies: + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" + picocolors "^1.0.0" + "@babel/compat-data@^7.12.13", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2", "@babel/compat-data@^7.25.4": version "7.25.4" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.4.tgz#7d2a80ce229890edcf4cc259d4d696cb4dae2fcb" @@ -299,6 +308,17 @@ "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" +"@babel/generator@^7.25.9": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.2.tgz#87b75813bec87916210e5e01939a4c823d6bb74f" + integrity sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw== + dependencies: + "@babel/parser" "^7.26.2" + "@babel/types" "^7.26.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + "@babel/helper-annotate-as-pure@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" @@ -306,6 +326,13 @@ dependencies: "@babel/types" "^7.24.7" +"@babel/helper-annotate-as-pure@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4" + integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g== + dependencies: + "@babel/types" "^7.25.9" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz#37d66feb012024f2422b762b9b2a7cfe27c7fba3" @@ -338,6 +365,19 @@ "@babel/traverse" "^7.25.4" semver "^6.3.1" +"@babel/helper-create-class-features-plugin@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83" + integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/traverse" "^7.25.9" + semver "^6.3.1" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.7", "@babel/helper-create-regexp-features-plugin@^7.25.0", "@babel/helper-create-regexp-features-plugin@^7.25.2": version "7.25.2" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz#24c75974ed74183797ffd5f134169316cd1808d9" @@ -373,6 +413,14 @@ "@babel/traverse" "^7.24.8" "@babel/types" "^7.24.8" +"@babel/helper-member-expression-to-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz#9dfffe46f727005a5ea29051ac835fb735e4c1a3" + integrity sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" @@ -398,11 +446,23 @@ dependencies: "@babel/types" "^7.24.7" +"@babel/helper-optimise-call-expression@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz#3324ae50bae7e2ab3c33f60c9a877b6a0146b54e" + integrity sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ== + dependencies: + "@babel/types" "^7.25.9" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.24.8" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== +"@babel/helper-plugin-utils@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" + integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== + "@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.24.7", "@babel/helper-remap-async-to-generator@^7.25.0": version "7.25.0" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz#d2f0fbba059a42d68e5e378feaf181ef6055365e" @@ -421,6 +481,15 @@ "@babel/helper-optimise-call-expression" "^7.24.7" "@babel/traverse" "^7.25.0" +"@babel/helper-replace-supers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz#ba447224798c3da3f8713fc272b145e33da6a5c5" + integrity sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/helper-simple-access@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" @@ -437,16 +506,34 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" +"@babel/helper-skip-transparent-expression-wrappers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9" + integrity sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA== + dependencies: + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + "@babel/helper-string-parser@^7.24.8": version "7.24.8" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + "@babel/helper-validator-identifier@^7.24.7": version "7.24.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + "@babel/helper-validator-option@^7.12.11", "@babel/helper-validator-option@^7.24.7", "@babel/helper-validator-option@^7.24.8": version "7.24.8" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" @@ -486,6 +573,13 @@ dependencies: "@babel/types" "^7.25.6" +"@babel/parser@^7.25.9", "@babel/parser@^7.26.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.2.tgz#fd7b6f487cfea09889557ef5d4eeb9ff9a5abd11" + integrity sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ== + dependencies: + "@babel/types" "^7.26.0" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.3": version "7.25.3" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz#dca427b45a6c0f5c095a1c639dfe2476a3daba7f" @@ -552,6 +646,15 @@ "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-syntax-decorators" "^7.24.7" +"@babel/plugin-proposal-decorators@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz#8680707f943d1a3da2cd66b948179920f097e254" + integrity sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-syntax-decorators" "^7.25.9" + "@babel/plugin-proposal-dynamic-import@^7.12.1": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" @@ -684,6 +787,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.7" +"@babel/plugin-syntax-decorators@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz#986b4ca8b7b5df3f67cee889cedeffc2e2bf14b3" + integrity sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -1516,6 +1626,15 @@ "@babel/parser" "^7.25.0" "@babel/types" "^7.25.0" +"@babel/template@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" + integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/types" "^7.25.9" + "@babel/traverse@^7.16.0", "@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.4": version "7.25.6" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.6.tgz#04fad980e444f182ecf1520504941940a90fea41" @@ -1529,6 +1648,19 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" + integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== + dependencies: + "@babel/code-frame" "^7.25.9" + "@babel/generator" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/template" "^7.25.9" + "@babel/types" "^7.25.9" + debug "^4.3.1" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.20.7", "@babel/types@^7.21.2", "@babel/types@^7.21.3", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.25.6", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.25.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.6.tgz#893942ddb858f32ae7a004ec9d3a76b3463ef8e6" @@ -1538,6 +1670,14 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" +"@babel/types@^7.25.9", "@babel/types@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" + integrity sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -8648,11 +8788,6 @@ eslint-config-prettier@9.0.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz#eb25485946dd0c66cd216a46232dc05451518d1f" integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== -eslint-define-config@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-define-config/-/eslint-define-config-2.1.0.tgz#9708b3efd57637b6fb685d9c2fb6285b9acfbd71" - integrity sha512-QUp6pM9pjKEVannNAbSJNeRuYwW3LshejfyBBpjeMGaJjaDUpVps4C6KVR8R7dWZnD3i0synmrE36znjTkJvdQ== - eslint-import-resolver-node@^0.3.6: version "0.3.9" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" @@ -11590,6 +11725,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== + jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" @@ -16233,16 +16373,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -16343,14 +16474,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -17816,7 +17940,7 @@ word-wrap@^1.2.5: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -17834,15 +17958,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"