Much stricter ts
This commit is contained in:
parent
f56ba4675f
commit
f28a928442
|
@ -0,0 +1,9 @@
|
|||
import { Access } from "payload/config";
|
||||
import { RecordersRoles } from "../../constants";
|
||||
import { Recorder } from "../../types/collections";
|
||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
|
||||
export const mustBeAdmin: Access<unknown, Recorder> = ({ req: { user } }): boolean => {
|
||||
if (isUndefined(user)) return false;
|
||||
return isDefined(user.role) && user.role.includes(RecordersRoles.Admin);
|
||||
};
|
|
@ -1,11 +1,10 @@
|
|||
import { Access } from "payload/config";
|
||||
import { Recorder } from "../../types/collections";
|
||||
import { RecordersRoles } from "../../constants";
|
||||
import { Recorder } from "../../types/collections";
|
||||
import { isUndefined } from "../../utils/asserts";
|
||||
|
||||
export const mustBeAdminOrSelf: Access = ({ req }) => {
|
||||
const user = req.user as Recorder | undefined;
|
||||
export const mustBeAdminOrSelf: Access<unknown, Recorder> = ({ req: { user } }) => {
|
||||
if (isUndefined(user)) return false;
|
||||
if (user.role.includes(RecordersRoles.Admin)) return true;
|
||||
if (user.role?.includes(RecordersRoles.Admin)) return true;
|
||||
return { id: { equals: user.id } };
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Access } from "payload/config";
|
||||
import { Recorder } from "../../types/collections";
|
||||
import { isUndefined } from "../../utils/asserts";
|
||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
|
||||
export const mustHaveAtLeastOneRole = ({ req }): boolean => {
|
||||
const user = req.user as Recorder | undefined;
|
||||
export const mustHaveAtLeastOneRole: Access<unknown, Recorder> = ({ req: { user } }): boolean => {
|
||||
if (isUndefined(user)) return false;
|
||||
return user.role.length > 0;
|
||||
return isDefined(user.role) && user.role.length > 0;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import { FieldAccess } from "payload/types";
|
||||
import { RecordersRoles } from "../../constants";
|
||||
import { Recorder } from "../../types/collections";
|
||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
|
||||
export const mustBeAdmin: FieldAccess<any, any, Recorder> = ({ req: { user } }): boolean => {
|
||||
if (isUndefined(user)) return false;
|
||||
return isDefined(user.role) && user.role.includes(RecordersRoles.Admin);
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
import { Recorder } from "../types/collections";
|
||||
import { RecordersRoles } from "../constants";
|
||||
import { isUndefined } from "../utils/asserts";
|
||||
|
||||
export const mustBeAdmin = ({ req }): boolean => {
|
||||
const user = req.user as Recorder | undefined;
|
||||
if (isUndefined(user)) return false;
|
||||
return user.role.includes(RecordersRoles.Admin);
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||
import { mustBeAdmin } from "../../accesses/collections/mustBeAdmin";
|
||||
import { CollectionGroups, Collections } from "../../constants";
|
||||
import { backPropagationField } from "../../fields/backPropagationField/backPropagationField";
|
||||
import { slugField } from "../../fields/slugField/slugField";
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
import { Collections } from "../../../constants";
|
||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { ChronologyEra } from "../../../types/collections";
|
||||
import { StrapiLanguage } from "../../../types/strapi";
|
||||
import { isUndefined } from "../../../utils/asserts";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<ChronologyEra>({
|
||||
type StrapiChronologyEra = {
|
||||
slug: string;
|
||||
starting_year: number;
|
||||
ending_year: number;
|
||||
title: { title: string; language: StrapiLanguage; description?: string }[];
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<ChronologyEra, StrapiChronologyEra>({
|
||||
strapi: {
|
||||
collection: "chronology-eras",
|
||||
params: {
|
||||
|
@ -15,11 +24,15 @@ export const importFromStrapi = createStrapiImportEndpoint<ChronologyEra>({
|
|||
slug,
|
||||
startingYear: starting_year,
|
||||
endingYear: ending_year,
|
||||
translations: titles.map(({ language, title, description }) => ({
|
||||
language: language.data.attributes.code,
|
||||
title,
|
||||
description,
|
||||
})),
|
||||
translations: titles.map(({ language, title, description }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("Language is undefined for one of the translations");
|
||||
return {
|
||||
language: language.data?.attributes.code,
|
||||
title,
|
||||
description,
|
||||
};
|
||||
}),
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
import { CollectionBeforeValidateHook } from "payload/types";
|
||||
import { ChronologyEra } from "../../../types/collections";
|
||||
import { isUndefined } from "../../../utils/asserts";
|
||||
|
||||
export const beforeValidateEndingGreaterThanStarting: CollectionBeforeValidateHook<
|
||||
ChronologyEra
|
||||
> = async ({ data: { startingYear, endingYear } }) => {
|
||||
> = async ({ data }) => {
|
||||
if (isUndefined(data)) throw new Error("The data is undefined");
|
||||
const { startingYear, endingYear } = data;
|
||||
if (isUndefined(endingYear)) throw new Error("Ending year is undefined");
|
||||
if (isUndefined(startingYear)) throw new Error("Starting year is undefined");
|
||||
if (endingYear < startingYear) {
|
||||
throw new Error("The ending year cannot be before the starting year.");
|
||||
}
|
||||
|
|
|
@ -2,11 +2,16 @@ import payload from "payload";
|
|||
import { CollectionBeforeValidateHook } from "payload/types";
|
||||
import { Collections } from "../../../constants";
|
||||
import { ChronologyEra } from "../../../types/collections";
|
||||
import { hasIntersection } from "../../../utils/asserts";
|
||||
import { hasIntersection, isUndefined } from "../../../utils/asserts";
|
||||
|
||||
export const beforeValidateNoIntersection: CollectionBeforeValidateHook<ChronologyEra> = async ({
|
||||
data: { startingYear, endingYear },
|
||||
data,
|
||||
}) => {
|
||||
if (isUndefined(data)) throw new Error("The data is undefined");
|
||||
const { startingYear, endingYear } = data;
|
||||
if (isUndefined(endingYear)) throw new Error("Ending year is undefined");
|
||||
if (isUndefined(startingYear)) throw new Error("Starting year is undefined");
|
||||
|
||||
const otherEras = await payload.find({
|
||||
collection: Collections.ChronologyEras,
|
||||
limit: 100,
|
||||
|
|
|
@ -72,6 +72,7 @@ export const ChronologyItems: CollectionConfig = buildVersionedCollectionConfig(
|
|||
if (!DateTime.fromObject({ year, month, day }).isValid) {
|
||||
return `The given date (${stringDate}) is not a valid date.`;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
import { Collections } from "../../../constants";
|
||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { ChronologyItem } from "../../../types/collections";
|
||||
import { StrapiLanguage } from "../../../types/strapi";
|
||||
import { isUndefined } from "../../../utils/asserts";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<ChronologyItem>({
|
||||
type StrapiChronologyItem = {
|
||||
year: number;
|
||||
month?: number;
|
||||
day?: number;
|
||||
events: {
|
||||
translations: {
|
||||
title?: string;
|
||||
description?: string;
|
||||
note?: string;
|
||||
language: StrapiLanguage;
|
||||
}[];
|
||||
}[];
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<ChronologyItem, StrapiChronologyItem>({
|
||||
strapi: {
|
||||
collection: "chronology-items",
|
||||
params: {
|
||||
|
@ -14,16 +30,20 @@ export const importFromStrapi = createStrapiImportEndpoint<ChronologyItem>({
|
|||
convert: ({ year, month, day, events }, user) => ({
|
||||
date: { year, month, day },
|
||||
events: events.map((event) => ({
|
||||
translations: event.translations.map(({ title, description, note, language }) => ({
|
||||
title,
|
||||
description,
|
||||
note,
|
||||
language: language.data.attributes.code,
|
||||
sourceLanguage: "en",
|
||||
...(language.data.attributes.code === "en"
|
||||
? { transcribers: [user.id] }
|
||||
: { translators: [user.id] }),
|
||||
})),
|
||||
translations: event.translations.map(({ title, description, note, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a chronology item event translation");
|
||||
return {
|
||||
title,
|
||||
description,
|
||||
note,
|
||||
language: language.data.attributes.code,
|
||||
sourceLanguage: "en",
|
||||
...(language.data.attributes.code === "en"
|
||||
? { transcribers: [user.id] }
|
||||
: { translators: [user.id] }),
|
||||
};
|
||||
}),
|
||||
})),
|
||||
}),
|
||||
},
|
||||
|
|
|
@ -6,8 +6,12 @@ export const beforeValidatePopulateNameField: FieldHook<
|
|||
ChronologyItem,
|
||||
ChronologyItem["name"],
|
||||
ChronologyItem
|
||||
> = ({ data: { date } }) => {
|
||||
if (isUndefined(date?.year)) return "????-??-??";
|
||||
> = ({ data }) => {
|
||||
if (isUndefined(data)) {
|
||||
return "????-??-??";
|
||||
}
|
||||
const { date } = data;
|
||||
if (isUndefined(date) || isUndefined(date?.year)) return "????-??-??";
|
||||
const { year, month, day } = date;
|
||||
let result = String(year).padStart(5, " ");
|
||||
if (isDefined(month)) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { text } from "payload/dist/fields/validations";
|
||||
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||
import { mustBeAdmin } from "../../accesses/collections/mustBeAdmin";
|
||||
import { CollectionGroups, Collections } from "../../constants";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||
|
|
|
@ -2,7 +2,12 @@ import { Collections } from "../../../constants";
|
|||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { Language } from "../../../types/collections";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Language>({
|
||||
type StrapiLanguage = {
|
||||
code: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Language, StrapiLanguage>({
|
||||
strapi: {
|
||||
collection: "currencies",
|
||||
params: {},
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import payload from "payload";
|
||||
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||
import { mustBeAdmin } from "../../accesses/collections/mustBeAdmin";
|
||||
import { QuickFilters } from "../../components/QuickFilters";
|
||||
import { CollectionGroups, Collections, KeysTypes, LanguageCodes } from "../../constants";
|
||||
import { translatedFields } from "../../fields/translatedFields/translatedFields";
|
||||
import { beforeDuplicateAddCopyTo } from "../../hooks/beforeDuplicateAddCopyTo";
|
||||
import { Key } from "../../types/collections";
|
||||
import { isDefined } from "../../utils/asserts";
|
||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||
|
||||
|
@ -58,15 +58,15 @@ export const Keys = buildCollectionConfig({
|
|||
},
|
||||
hooks: {
|
||||
beforeValidate: [
|
||||
async ({ data: { name, type } }) => {
|
||||
async ({ data }) => {
|
||||
if (isUndefined(data)) return;
|
||||
const { name, type } = data;
|
||||
const result = await payload.find({
|
||||
collection: Collections.Keys,
|
||||
where: { name: { equals: name }, type: { equals: type } },
|
||||
});
|
||||
if (result.docs.length > 0) {
|
||||
throw new Error(
|
||||
`A Key of type "${KeysTypes[type]}" already exists with the name "${name}"`
|
||||
);
|
||||
throw new Error(`A Key of type "${type}" already exists with the name "${name}"`);
|
||||
}
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import payload from "payload";
|
||||
import { CollectionConfig } from "payload/types";
|
||||
import { Collections } from "../../../constants";
|
||||
import {
|
||||
getAllStrapiEntries,
|
||||
importStrapiEntries,
|
||||
} from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { Key } from "../../../types/collections";
|
||||
import { isDefined } from "../../../utils/asserts";
|
||||
import { CollectionEndpoint, PayloadCreateData } from "../../../types/payload";
|
||||
import { StrapiLanguage } from "../../../types/strapi";
|
||||
import { isDefined, isUndefined } from "../../../utils/asserts";
|
||||
import { formatToCamelCase } from "../../../utils/string";
|
||||
import { PayloadCreateData } from "../../../utils/types";
|
||||
|
||||
const importStrapiWordings: typeof importStrapiEntries = async ({
|
||||
payload: payloadParams,
|
||||
|
@ -30,7 +30,7 @@ const importStrapiWordings: typeof importStrapiEntries = async ({
|
|||
.filter(({ name }) => isDefined(name) && name !== ""),
|
||||
}));
|
||||
|
||||
const errors = [];
|
||||
const errors: string[] = [];
|
||||
|
||||
await Promise.all(
|
||||
entries.map(async (entry) => {
|
||||
|
@ -42,7 +42,9 @@ const importStrapiWordings: typeof importStrapiEntries = async ({
|
|||
});
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
errors.push(`${e.name} with ${entry.name}`);
|
||||
if (typeof e === "object" && isDefined(e) && "name" in e) {
|
||||
errors.push(`${e.name} with ${entry.name}`);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -50,7 +52,7 @@ const importStrapiWordings: typeof importStrapiEntries = async ({
|
|||
return { count: entries.length, errors };
|
||||
};
|
||||
|
||||
export const importFromStrapi: CollectionConfig["endpoints"][number] = {
|
||||
export const importFromStrapi: CollectionEndpoint = {
|
||||
method: "get",
|
||||
path: "/strapi",
|
||||
handler: async (req, res) => {
|
||||
|
@ -64,7 +66,15 @@ export const importFromStrapi: CollectionConfig["endpoints"][number] = {
|
|||
});
|
||||
}
|
||||
|
||||
const { count: categoriesCount, errors: categoriesErrors } = await importStrapiEntries<Key>({
|
||||
type StrapiCategories = {
|
||||
slug: string;
|
||||
titles: { title?: string; short?: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: categoriesCount, errors: categoriesErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiCategories
|
||||
>({
|
||||
strapi: {
|
||||
collection: "categories",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
|
@ -74,59 +84,96 @@ export const importFromStrapi: CollectionConfig["endpoints"][number] = {
|
|||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "Categories",
|
||||
translations: titles.map(({ title, short, language }) => ({
|
||||
name: title,
|
||||
short,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
translations: titles.map(({ title, short, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
if (isUndefined(title))
|
||||
throw new Error("A title is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
short,
|
||||
language: language.data.attributes.code,
|
||||
};
|
||||
}),
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: contentTypesCount, errors: contentTypesErrors } = await importStrapiEntries<Key>(
|
||||
{
|
||||
strapi: {
|
||||
collection: "content-types",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "Contents",
|
||||
translations: titles.map(({ title, language }) => ({
|
||||
type StrapiContentType = {
|
||||
slug: string;
|
||||
titles: { title: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: contentTypesCount, errors: contentTypesErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiContentType
|
||||
>({
|
||||
strapi: {
|
||||
collection: "content-types",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "Contents",
|
||||
translations: titles.map(({ title, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
};
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
}
|
||||
);
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: gamePlatformsCount, errors: gamePlatformsErrors } =
|
||||
await importStrapiEntries<Key>({
|
||||
strapi: {
|
||||
collection: "game-platforms",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "GamePlatforms",
|
||||
translations: titles.map(({ title, short, language }) => ({
|
||||
type StrapiGamePlatform = {
|
||||
slug: string;
|
||||
titles: { title?: string; short?: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: gamePlatformsCount, errors: gamePlatformsErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiGamePlatform
|
||||
>({
|
||||
strapi: {
|
||||
collection: "game-platforms",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "GamePlatforms",
|
||||
translations: titles.map(({ title, short, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
if (isUndefined(title))
|
||||
throw new Error("A title is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
short,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
};
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: libraryCount, errors: libraryErrors } = await importStrapiEntries<Key>({
|
||||
type StrapiMetadataTypes = {
|
||||
slug: string;
|
||||
titles: { title: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: libraryCount, errors: libraryErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiMetadataTypes
|
||||
>({
|
||||
strapi: {
|
||||
collection: "metadata-types",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
|
@ -136,99 +183,152 @@ export const importFromStrapi: CollectionConfig["endpoints"][number] = {
|
|||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "Library",
|
||||
translations: titles.map(({ title, language }) => ({
|
||||
name: title,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
translations: titles.map(({ title, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
language: language.data.attributes.code,
|
||||
};
|
||||
}),
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: libraryAudioCount, errors: libraryAudioErrors } = await importStrapiEntries<Key>(
|
||||
{
|
||||
strapi: {
|
||||
collection: "audio-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryAudio",
|
||||
translations: titles.map(({ title, language }) => ({
|
||||
type StrapiAudioSubtypes = {
|
||||
slug: string;
|
||||
titles: { title: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: libraryAudioCount, errors: libraryAudioErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiAudioSubtypes
|
||||
>({
|
||||
strapi: {
|
||||
collection: "audio-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryAudio",
|
||||
translations: titles.map(({ title, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
};
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
}
|
||||
);
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: libraryGroupCount, errors: libraryGroupErrors } = await importStrapiEntries<Key>(
|
||||
{
|
||||
strapi: {
|
||||
collection: "group-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryGroup",
|
||||
translations: titles.map(({ title, language }) => ({
|
||||
type StrapiGroupSubtypes = {
|
||||
slug: string;
|
||||
titles: { title: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: libraryGroupCount, errors: libraryGroupErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiGroupSubtypes
|
||||
>({
|
||||
strapi: {
|
||||
collection: "group-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryGroup",
|
||||
translations: titles.map(({ title, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
};
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
}
|
||||
);
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: libraryTextualCount, errors: libraryTextualErrors } =
|
||||
await importStrapiEntries<Key>({
|
||||
strapi: {
|
||||
collection: "textual-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryTextual",
|
||||
translations: titles.map(({ title, language }) => ({
|
||||
type StrapiTextualSubtypes = {
|
||||
slug: string;
|
||||
titles: { title: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: libraryTextualCount, errors: libraryTextualErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiTextualSubtypes
|
||||
>({
|
||||
strapi: {
|
||||
collection: "textual-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryTextual",
|
||||
translations: titles.map(({ title, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
};
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: libraryVideoCount, errors: libraryVideoErrors } = await importStrapiEntries<Key>(
|
||||
{
|
||||
strapi: {
|
||||
collection: "video-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryVideo",
|
||||
translations: titles.map(({ title, language }) => ({
|
||||
type StrapiVideoSubtypes = {
|
||||
slug: string;
|
||||
titles: { title: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: libraryVideoCount, errors: libraryVideoErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiVideoSubtypes
|
||||
>({
|
||||
strapi: {
|
||||
collection: "video-subtypes",
|
||||
params: { populate: { titles: { populate: "language" } } },
|
||||
},
|
||||
payload: {
|
||||
collection: Collections.Keys,
|
||||
convert: ({ slug, titles }) => ({
|
||||
name: slug,
|
||||
type: "LibraryVideo",
|
||||
translations: titles.map(({ title, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
return {
|
||||
name: title,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
};
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
}
|
||||
);
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: weaponsCount, errors: weaponsErrors } = await importStrapiEntries<Key>({
|
||||
type StrapiWeaponTypes = {
|
||||
slug: string;
|
||||
translations: { name?: string; language: StrapiLanguage }[];
|
||||
};
|
||||
|
||||
const { count: weaponsCount, errors: weaponsErrors } = await importStrapiEntries<
|
||||
Key,
|
||||
StrapiWeaponTypes
|
||||
>({
|
||||
strapi: {
|
||||
collection: "weapon-story-types",
|
||||
params: { populate: { translations: { populate: "language" } } },
|
||||
|
@ -238,16 +338,22 @@ export const importFromStrapi: CollectionConfig["endpoints"][number] = {
|
|||
convert: ({ slug, translations }) => ({
|
||||
name: slug,
|
||||
type: "Weapons",
|
||||
translations: translations.map(({ name, language }) => ({
|
||||
name,
|
||||
language: language.data.attributes.code,
|
||||
})),
|
||||
translations: translations.map(({ name, language }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Keys title translation");
|
||||
if (isUndefined(name))
|
||||
throw new Error("A name is required for a Keys title translation");
|
||||
return {
|
||||
name,
|
||||
language: language.data.attributes.code,
|
||||
};
|
||||
}),
|
||||
}),
|
||||
},
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
const { count: wordingsCount, errors: wordingsErrors } = await importStrapiWordings({
|
||||
const { count: wordingsCount, errors: wordingsErrors } = await importStrapiWordings<Key, Key>({
|
||||
strapi: { collection: "website-interfaces", params: { populate: "ui_language" } },
|
||||
payload: { collection: Collections.Keys, convert: (strapiObject) => strapiObject },
|
||||
user: req.user,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { text } from "payload/dist/fields/validations";
|
||||
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||
import { mustBeAdmin } from "../../accesses/collections/mustBeAdmin";
|
||||
import { publicAccess } from "../../accesses/publicAccess";
|
||||
import { CollectionGroups, Collections } from "../../constants";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
|
|
|
@ -2,7 +2,12 @@ import { Collections } from "../../../constants";
|
|||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { Language } from "../../../types/collections";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Language>({
|
||||
type StrapiLanguage = {
|
||||
name: string;
|
||||
code: string;
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Language, StrapiLanguage>({
|
||||
strapi: {
|
||||
collection: "languages",
|
||||
params: {},
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { RowLabelArgs } from "payload/dist/admin/components/forms/RowLabel/types";
|
||||
import {
|
||||
CollectionGroups,
|
||||
Collections,
|
||||
|
@ -18,7 +19,6 @@ import { LibraryItem } from "../../types/collections";
|
|||
import { isDefined } from "../../utils/asserts";
|
||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||
import { RowLabel } from "./components/RowLabel";
|
||||
import { getBySlug } from "./endpoints/getBySlug";
|
||||
|
||||
const fields = {
|
||||
status: "_status",
|
||||
|
@ -139,7 +139,6 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
|||
},
|
||||
preview: (doc) => `https://accords-library.com/library/${doc.slug}`,
|
||||
},
|
||||
endpoints: [getBySlug],
|
||||
fields: [
|
||||
{
|
||||
name: fields.itemType,
|
||||
|
@ -480,7 +479,7 @@ export const LibraryItems = buildVersionedCollectionConfig({
|
|||
"Make sure the page number corresponds to the page number written on \
|
||||
the scan. You can use negative page numbers if necessary.",
|
||||
components: {
|
||||
RowLabel: ({ data }) => RowLabel(data),
|
||||
RowLabel: ({ data }: RowLabelArgs) => RowLabel(data),
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
import cleanDeep from "clean-deep";
|
||||
import { Collections } from "../../../constants";
|
||||
import { createGetByEndpoint } from "../../../endpoints/createByEndpoint";
|
||||
import { LibraryItem } from "../../../types/collections";
|
||||
|
||||
type ProcessedLibraryItem = Omit<LibraryItem, "size" | "price" | "scans" | "id"> & {
|
||||
size?: Omit<LibraryItem["size"][number], "id">;
|
||||
price?: Omit<LibraryItem["price"][number], "id" | "currency"> & { currency: string };
|
||||
scans?: Omit<LibraryItem["scans"][number], "id" | "obi" | "cover" | "dustjacket"> & {
|
||||
obi: Omit<LibraryItem["scans"][number]["obi"][number], "id">;
|
||||
cover: Omit<LibraryItem["scans"][number]["obi"][number], "id">;
|
||||
dustjacket: Omit<LibraryItem["scans"][number]["obi"][number], "id">;
|
||||
};
|
||||
};
|
||||
|
||||
export const getBySlug = createGetByEndpoint<LibraryItem, Partial<ProcessedLibraryItem>>(
|
||||
Collections.LibraryItems,
|
||||
"slug",
|
||||
async ({ id, size, price, scans, ...otherProps }) => {
|
||||
const processedLibraryItem: ProcessedLibraryItem = {
|
||||
size: processOptionalGroup(size),
|
||||
price: processPrice(price),
|
||||
scans: processScans(scans),
|
||||
...otherProps,
|
||||
};
|
||||
|
||||
return cleanDeep(processedLibraryItem, {
|
||||
emptyStrings: false,
|
||||
emptyArrays: false,
|
||||
emptyObjects: false,
|
||||
nullValues: true,
|
||||
undefinedValues: true,
|
||||
NaNValues: false,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const processScans = (scans: LibraryItem["scans"]): ProcessedLibraryItem["scans"] => {
|
||||
if (!scans || scans.length === 0) return undefined;
|
||||
const { cover, dustjacket, id, obi, ...otherProps } = scans[0];
|
||||
return {
|
||||
cover: processOptionalGroup(cover),
|
||||
dustjacket: processOptionalGroup(dustjacket),
|
||||
obi: processOptionalGroup(obi),
|
||||
...otherProps,
|
||||
};
|
||||
};
|
||||
|
||||
const processPrice = (price: LibraryItem["price"]): ProcessedLibraryItem["price"] => {
|
||||
if (!price || price.length === 0) return undefined;
|
||||
const { currency, ...otherProps } = processOptionalGroup(price);
|
||||
return { ...otherProps, currency: typeof currency === "string" ? currency : currency.id };
|
||||
};
|
||||
|
||||
const processOptionalGroup = <T extends { id?: string }>(group: T[] | null | undefined) => {
|
||||
if (!group || group.length === 0) return undefined;
|
||||
const { id, ...otherProps } = group[0];
|
||||
return otherProps;
|
||||
};
|
|
@ -8,7 +8,6 @@ import { beforeDuplicatePiping } from "../../hooks/beforeDuplicatePiping";
|
|||
import { beforeDuplicateUnpublish } from "../../hooks/beforeDuplicateUnpublish";
|
||||
import { isDefined, isUndefined } from "../../utils/asserts";
|
||||
import { buildVersionedCollectionConfig } from "../../utils/versionedCollectionConfig";
|
||||
import { removeTranslatorsForTranscripts } from "./hooks/beforeValidate";
|
||||
|
||||
const fields = {
|
||||
slug: "slug",
|
||||
|
@ -57,9 +56,6 @@ export const Posts = buildVersionedCollectionConfig({
|
|||
},
|
||||
preview: (doc) => `https://accords-library.com/news/${doc.slug}`,
|
||||
},
|
||||
hooks: {
|
||||
beforeValidate: [removeTranslatorsForTranscripts],
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
type: "row",
|
||||
|
@ -110,6 +106,15 @@ export const Posts = buildVersionedCollectionConfig({
|
|||
type: "relationship",
|
||||
relationTo: Collections.Recorders,
|
||||
hasMany: true,
|
||||
hooks: {
|
||||
beforeChange: [
|
||||
({ siblingData }) => {
|
||||
if (siblingData.language === siblingData.sourceLanguage) {
|
||||
delete siblingData.translators;
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
admin: {
|
||||
condition: (_, siblingData) => {
|
||||
if (
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import { CollectionBeforeValidateHook } from "payload/types";
|
||||
import { Post } from "../../../types/collections";
|
||||
|
||||
export const removeTranslatorsForTranscripts: CollectionBeforeValidateHook<Post> = async ({
|
||||
data: { translations, ...data },
|
||||
}) => ({
|
||||
...data,
|
||||
translations: translations?.map(({ translators, ...translation }) => {
|
||||
if (translation.language === translation.sourceLanguage) {
|
||||
return { ...translation, translators: [] };
|
||||
}
|
||||
return { ...translation, translators };
|
||||
}),
|
||||
});
|
|
@ -1,5 +1,6 @@
|
|||
import { mustBeAdmin as mustBeAdminForCollections } from "../../accesses/collections/mustBeAdmin";
|
||||
import { mustBeAdminOrSelf } from "../../accesses/collections/mustBeAdminOrSelf";
|
||||
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||
import { mustBeAdmin as mustBeAdminForFields } from "../../accesses/fields/mustBeAdmin";
|
||||
import { QuickFilters } from "../../components/QuickFilters";
|
||||
import { CollectionGroups, Collections, RecordersRoles } from "../../constants";
|
||||
import { imageField } from "../../fields/imageField/imageField";
|
||||
|
@ -55,7 +56,6 @@ export const Recorders = buildCollectionConfig({
|
|||
label: "∅ Role",
|
||||
filter: { where: { role: { not_in: Object.keys(RecordersRoles).join(",") } } },
|
||||
},
|
||||
,
|
||||
],
|
||||
[{ label: "Anonymized", filter: { where: { anonymize: { equals: true } } } }],
|
||||
],
|
||||
|
@ -65,10 +65,10 @@ export const Recorders = buildCollectionConfig({
|
|||
},
|
||||
auth: true,
|
||||
access: {
|
||||
unlock: mustBeAdmin,
|
||||
unlock: mustBeAdminForCollections,
|
||||
update: mustBeAdminOrSelf,
|
||||
delete: mustBeAdmin,
|
||||
create: mustBeAdmin,
|
||||
delete: mustBeAdminForCollections,
|
||||
create: mustBeAdminForCollections,
|
||||
},
|
||||
hooks: {
|
||||
beforeLogin: [beforeLoginMustHaveAtLeastOneRole],
|
||||
|
@ -111,14 +111,14 @@ export const Recorders = buildCollectionConfig({
|
|||
description:
|
||||
"A short personal description about you or your involvement with this project or the franchise",
|
||||
},
|
||||
fields: [{ name: fields.biography, type: "textarea" }],
|
||||
fields: [{ name: fields.biography, required: true, type: "textarea" }],
|
||||
}),
|
||||
{
|
||||
name: fields.role,
|
||||
type: "select",
|
||||
access: {
|
||||
update: mustBeAdmin,
|
||||
create: mustBeAdmin,
|
||||
update: mustBeAdminForFields,
|
||||
create: mustBeAdminForFields,
|
||||
},
|
||||
hasMany: true,
|
||||
options: Object.entries(RecordersRoles).map(([value, label]) => ({
|
||||
|
|
|
@ -2,10 +2,21 @@ import payload from "payload";
|
|||
import { Collections } from "../../../constants";
|
||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { Recorder } from "../../../types/collections";
|
||||
import { PayloadCreateData } from "../../../types/payload";
|
||||
import { StrapiImage, StrapiLanguage } from "../../../types/strapi";
|
||||
import { isUndefined } from "../../../utils/asserts";
|
||||
import { uploadStrapiImage } from "../../../utils/localApi";
|
||||
import { PayloadCreateData } from "../../../utils/types";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Recorder>({
|
||||
type StrapiRecorder = {
|
||||
username: string;
|
||||
anonymize: boolean;
|
||||
anonymous_code: number;
|
||||
languages: { data: { attributes: { code: string } }[] };
|
||||
avatar: StrapiImage;
|
||||
bio: { language: StrapiLanguage; bio?: string }[];
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Recorder, StrapiRecorder>({
|
||||
strapi: {
|
||||
collection: "recorders",
|
||||
params: {
|
||||
|
@ -27,10 +38,15 @@ export const importFromStrapi = createStrapiImportEndpoint<Recorder>({
|
|||
anonymize,
|
||||
languages: languages.data?.map((language) => language.attributes.code),
|
||||
avatar: avatarId,
|
||||
biographies: bios?.map(({ language, bio }) => ({
|
||||
language: language.data.attributes.code,
|
||||
biography: bio,
|
||||
})),
|
||||
biographies: bios?.map(({ language, bio }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required for a Recorder biography");
|
||||
if (isUndefined(bio)) throw new Error("A bio is required for a Recorder biography");
|
||||
return {
|
||||
language: language.data.attributes.code,
|
||||
biography: bio,
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
await payload.create({ collection: Collections.Recorders, data, user });
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||
import { mustBeAdmin } from "../../accesses/collections/mustBeAdmin";
|
||||
import { CollectionGroups, Collections, VideoSources } from "../../constants";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||
|
|
|
@ -2,9 +2,26 @@ import payload from "payload";
|
|||
import { Collections } from "../../../constants";
|
||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { Video, VideosChannel } from "../../../types/collections";
|
||||
import { PayloadCreateData } from "../../../utils/types";
|
||||
import { PayloadCreateData } from "../../../types/payload";
|
||||
import { isUndefined } from "../../../utils/asserts";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Video>({
|
||||
type StapiVideo = {
|
||||
uid: string;
|
||||
title: string;
|
||||
description: string;
|
||||
published_date: {
|
||||
year?: number;
|
||||
month?: number;
|
||||
day?: number;
|
||||
};
|
||||
views: number;
|
||||
likes: number;
|
||||
source?: "YouTube" | "NicoNico" | "Tumblr";
|
||||
gone: boolean;
|
||||
channel: { data?: { attributes: { uid: string; title: string; subscribers: number } } };
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Video, StapiVideo>({
|
||||
strapi: {
|
||||
collection: "videos",
|
||||
params: { populate: "published_date,channel" },
|
||||
|
@ -25,6 +42,9 @@ export const importFromStrapi = createStrapiImportEndpoint<Video>({
|
|||
},
|
||||
user
|
||||
) => {
|
||||
if (isUndefined(source)) throw new Error("A source is required to create a Video");
|
||||
if (isUndefined(channel.data)) throw new Error("A channel is required to create a Video");
|
||||
|
||||
try {
|
||||
const videoChannel: PayloadCreateData<VideosChannel> = {
|
||||
uid: channel.data.attributes.uid,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
import { mustBeAdmin } from "../../accesses/mustBeAdmin";
|
||||
import { mustBeAdmin } from "../../accesses/collections/mustBeAdmin";
|
||||
import { CollectionGroups, Collections } from "../../constants";
|
||||
import { buildCollectionConfig } from "../../utils/collectionConfig";
|
||||
import { importFromStrapi } from "./endpoints/importFromStrapi";
|
||||
|
|
|
@ -2,7 +2,13 @@ import { Collections } from "../../../constants";
|
|||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { VideosChannel } from "../../../types/collections";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<VideosChannel>({
|
||||
type StrapiVideoChannel = {
|
||||
uid: string;
|
||||
title: string;
|
||||
subscribers: number;
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<VideosChannel, StrapiVideoChannel>({
|
||||
strapi: {
|
||||
collection: "video-channels",
|
||||
params: {},
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { RowLabelArgs } from "payload/dist/admin/components/forms/RowLabel/types";
|
||||
import { CollectionGroups, Collections, KeysTypes } from "../../constants";
|
||||
import { imageField } from "../../fields/imageField/imageField";
|
||||
import { keysField } from "../../fields/keysField/keysField";
|
||||
|
@ -78,7 +79,7 @@ export const Weapons = buildVersionedCollectionConfig({
|
|||
admin: {
|
||||
initCollapsed: true,
|
||||
components: {
|
||||
RowLabel: ({ data }) =>
|
||||
RowLabel: ({ data }: RowLabelArgs) =>
|
||||
AppearanceRowLabel({ keyIds: data[fields.appearancesCategories] ?? [] }),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2,11 +2,31 @@ import payload from "payload";
|
|||
import { Collections } from "../../../constants";
|
||||
import { createStrapiImportEndpoint } from "../../../endpoints/createStrapiImportEndpoint";
|
||||
import { Weapon, WeaponsGroup } from "../../../types/collections";
|
||||
import { isDefined } from "../../../utils/asserts";
|
||||
import { PayloadCreateData } from "../../../types/payload";
|
||||
import { StrapiImage, StrapiLanguage } from "../../../types/strapi";
|
||||
import { isDefined, isUndefined } from "../../../utils/asserts";
|
||||
import { findCategory, findWeaponType, uploadStrapiImage } from "../../../utils/localApi";
|
||||
import { PayloadCreateData } from "../../../utils/types";
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Weapon>({
|
||||
type StrapiWeapon = {
|
||||
slug: string;
|
||||
name: { name: string; language: StrapiLanguage }[];
|
||||
weapon_group: { data?: { attributes: { slug: string } } };
|
||||
thumbnail: StrapiImage;
|
||||
type: { data?: { attributes: { slug: string } } };
|
||||
stories: {
|
||||
categories: { data: { attributes: { slug: string } }[] };
|
||||
translations: {
|
||||
language: StrapiLanguage;
|
||||
description?: string;
|
||||
level_1?: string;
|
||||
level_2?: string;
|
||||
level_3?: string;
|
||||
level_4?: string;
|
||||
}[];
|
||||
}[];
|
||||
};
|
||||
|
||||
export const importFromStrapi = createStrapiImportEndpoint<Weapon, StrapiWeapon>({
|
||||
strapi: {
|
||||
collection: "weapon-stories",
|
||||
params: {
|
||||
|
@ -23,7 +43,7 @@ export const importFromStrapi = createStrapiImportEndpoint<Weapon>({
|
|||
payload: {
|
||||
collection: Collections.Weapons,
|
||||
import: async ({ slug, type, stories, name: names, weapon_group, thumbnail }, user) => {
|
||||
let groupId: string;
|
||||
let groupId: string | undefined;
|
||||
if (isDefined(weapon_group.data)) {
|
||||
try {
|
||||
const groupData: PayloadCreateData<WeaponsGroup> = {
|
||||
|
@ -51,6 +71,8 @@ export const importFromStrapi = createStrapiImportEndpoint<Weapon>({
|
|||
image: thumbnail,
|
||||
});
|
||||
|
||||
if (isUndefined(type.data)) throw new Error("A type is required to create a Weapon");
|
||||
|
||||
const data: PayloadCreateData<Weapon> = {
|
||||
slug,
|
||||
type: await findWeaponType(type.data.attributes.slug),
|
||||
|
@ -62,19 +84,26 @@ export const importFromStrapi = createStrapiImportEndpoint<Weapon>({
|
|||
categories.data.map(({ attributes }) => findCategory(attributes.slug))
|
||||
),
|
||||
translations: translations.map(
|
||||
({ language, description, level_1, level_2, level_3, level_4 }) => ({
|
||||
language: language.data?.attributes.code,
|
||||
sourceLanguage: language.data?.attributes.code,
|
||||
name: names.find(
|
||||
({ language, description, level_1, level_2, level_3, level_4 }) => {
|
||||
if (isUndefined(language.data))
|
||||
throw new Error("A language is required to create a Weapon translation");
|
||||
const name = names.find(
|
||||
(name) => name.language.data?.attributes.code === language.data?.attributes.code
|
||||
)?.name,
|
||||
description,
|
||||
level1: level_1,
|
||||
level2: level_2,
|
||||
level3: level_3,
|
||||
level4: level_4,
|
||||
transcribers: [user.id],
|
||||
})
|
||||
)?.name;
|
||||
if (isUndefined(name))
|
||||
throw new Error("A name is required to create a Weapon translation");
|
||||
return {
|
||||
language: language.data?.attributes.code,
|
||||
sourceLanguage: language.data?.attributes.code,
|
||||
name,
|
||||
description,
|
||||
level1: level_1,
|
||||
level2: level_2,
|
||||
level3: level_3,
|
||||
level4: level_4,
|
||||
transcribers: [user.id],
|
||||
};
|
||||
}
|
||||
),
|
||||
}))
|
||||
),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import payload from "payload";
|
||||
import { CollectionConfig } from "payload/types";
|
||||
import { CollectionEndpoint } from "../types/payload";
|
||||
|
||||
export const createGetByEndpoint = <T, R>(
|
||||
collection: string,
|
||||
attribute: string,
|
||||
handler: (doc: T) => Promise<R>
|
||||
): CollectionConfig["endpoints"][number] => ({
|
||||
): CollectionEndpoint => ({
|
||||
path: `/${attribute}/:${attribute}`,
|
||||
method: "get",
|
||||
handler: async (req, res) => {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import payload from "payload";
|
||||
import { CollectionConfig } from "payload/types";
|
||||
import QueryString from "qs";
|
||||
import { Recorder } from "../types/collections";
|
||||
import { CollectionEndpoint, PayloadCreateData } from "../types/payload";
|
||||
import { isDefined } from "../utils/asserts";
|
||||
import { PayloadCreateData } from "../utils/types";
|
||||
|
||||
export const getAllStrapiEntries = async <T>(
|
||||
collectionSlug: string,
|
||||
|
@ -31,26 +30,26 @@ export const getAllStrapiEntries = async <T>(
|
|||
return result;
|
||||
};
|
||||
|
||||
type Params<T> = {
|
||||
type Params<T, S> = {
|
||||
strapi: {
|
||||
collection: string;
|
||||
params: any;
|
||||
};
|
||||
payload: {
|
||||
collection: string;
|
||||
import?: (strapiObject: any, user: any) => Promise<void>;
|
||||
convert?: (strapiObject: any, user: any) => PayloadCreateData<T>;
|
||||
import?: (strapiObject: S, user: any) => Promise<void>;
|
||||
convert?: (strapiObject: S, user: any) => PayloadCreateData<T>;
|
||||
};
|
||||
};
|
||||
|
||||
export const importStrapiEntries = async <T>({
|
||||
export const importStrapiEntries = async <T, S>({
|
||||
strapi: strapiParams,
|
||||
payload: payloadParams,
|
||||
user,
|
||||
}: Params<T> & { user: Recorder }) => {
|
||||
}: Params<T, S> & { user: Recorder }) => {
|
||||
const entries = await getAllStrapiEntries<any>(strapiParams.collection, strapiParams.params);
|
||||
|
||||
const errors = [];
|
||||
const errors: string[] = [];
|
||||
|
||||
await Promise.all(
|
||||
entries.map(async ({ attributes, id }) => {
|
||||
|
@ -68,7 +67,9 @@ export const importStrapiEntries = async <T>({
|
|||
}
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
errors.push(`${e.name} with ${id}`);
|
||||
if (typeof e === "object" && isDefined(e) && "name" in e) {
|
||||
errors.push(`${e.name} with ${id}`);
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
@ -76,9 +77,7 @@ export const importStrapiEntries = async <T>({
|
|||
return { count: entries.length, errors };
|
||||
};
|
||||
|
||||
export const createStrapiImportEndpoint = <T>(
|
||||
params: Params<T>
|
||||
): CollectionConfig["endpoints"][number] => ({
|
||||
export const createStrapiImportEndpoint = <T, S>(params: Params<T, S>): CollectionEndpoint => ({
|
||||
method: "get",
|
||||
path: "/strapi",
|
||||
handler: async (req, res) => {
|
||||
|
|
|
@ -30,7 +30,7 @@ export const backPropagationField = ({
|
|||
afterRead: [
|
||||
...afterRead,
|
||||
async ({ data }) => {
|
||||
if (isNotEmpty(data.id)) {
|
||||
if (isNotEmpty(data?.id)) {
|
||||
const result = await payload.find({
|
||||
collection: params.relationTo,
|
||||
where: where(data),
|
||||
|
|
|
@ -19,5 +19,5 @@ export const keysField = ({
|
|||
filterOptions: { type: { equals: getKeysTypesKey(relationTo) } },
|
||||
});
|
||||
|
||||
const getKeysTypesKey = (keyType: KeysTypes): string =>
|
||||
Object.entries(KeysTypes).find(([, value]) => value === keyType)[0];
|
||||
const getKeysTypesKey = (keyType: KeysTypes): string | undefined =>
|
||||
Object.entries(KeysTypes).find(([, value]) => value === keyType)?.[0];
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { RowLabelArgs } from "payload/dist/admin/components/forms/RowLabel/types";
|
||||
import { array } from "payload/dist/fields/validations";
|
||||
import { ArrayField, Field } from "payload/types";
|
||||
import { Collections } from "../../constants";
|
||||
|
@ -118,6 +119,8 @@ const creditFields: Field = {
|
|||
],
|
||||
};
|
||||
|
||||
type FieldData = Record<string, any> & { [fieldsNames.language]: string };
|
||||
|
||||
export const translatedFields = ({
|
||||
fields,
|
||||
validate,
|
||||
|
@ -129,7 +132,7 @@ export const translatedFields = ({
|
|||
admin: {
|
||||
initCollapsed: true,
|
||||
components: {
|
||||
Cell: ({ cellData }) =>
|
||||
Cell: ({ cellData }: { cellData: FieldData[] }) =>
|
||||
Cell({
|
||||
cellData:
|
||||
cellData?.map((row) => ({
|
||||
|
@ -137,7 +140,7 @@ export const translatedFields = ({
|
|||
title: isDefined(useAsTitle) ? row[useAsTitle] : undefined,
|
||||
})) ?? [],
|
||||
}),
|
||||
RowLabel: ({ data }) =>
|
||||
RowLabel: ({ data }: RowLabelArgs) =>
|
||||
RowLabel({
|
||||
language: data[fieldsNames.language],
|
||||
title: isDefined(useAsTitle) ? data[useAsTitle] : undefined,
|
||||
|
@ -162,6 +165,8 @@ export const translatedFields = ({
|
|||
if (hasDuplicates(languages)) {
|
||||
return `There cannot be multiple ${otherProps.name} with the same ${fieldsNames.language}`;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
fields: [
|
||||
hasSourceLanguage
|
||||
|
|
|
@ -4,7 +4,8 @@ import path from "path";
|
|||
import payload from "payload";
|
||||
import { Collections, RecordersRoles } from "./constants";
|
||||
import { Recorder } from "./types/collections";
|
||||
import { PayloadCreateData } from "./utils/types";
|
||||
import { PayloadCreateData } from "./types/payload";
|
||||
import { isDefined, isUndefined } from "./utils/asserts";
|
||||
|
||||
const app = express();
|
||||
|
||||
|
@ -15,6 +16,15 @@ app.get("/", (_, res) => {
|
|||
|
||||
const start = async () => {
|
||||
// Initialize Payload
|
||||
|
||||
if (isUndefined(process.env.PAYLOAD_SECRET)) {
|
||||
throw new Error("Missing required env variable: PAYLOAD_SECRET");
|
||||
}
|
||||
|
||||
if (isUndefined(process.env.MONGODB_URI)) {
|
||||
throw new Error("Missing required env variable: MONGODB_URI");
|
||||
}
|
||||
|
||||
await payload.init({
|
||||
secret: process.env.PAYLOAD_SECRET,
|
||||
mongoURL: process.env.MONGODB_URI,
|
||||
|
@ -24,19 +34,26 @@ const start = async () => {
|
|||
const recorders = await payload.find({ collection: Collections.Recorders });
|
||||
|
||||
// If no recorders, we seed some initial data
|
||||
if (recorders.docs.length === 0) {
|
||||
payload.logger.info("Seeding some initial data");
|
||||
const recorder: PayloadCreateData<Recorder> = {
|
||||
email: process.env.SEEDING_ADMIN_EMAIL,
|
||||
password: process.env.SEEDING_ADMIN_PASSWORD,
|
||||
username: process.env.SEEDING_ADMIN_USERNAME,
|
||||
role: [RecordersRoles.Admin],
|
||||
anonymize: false,
|
||||
};
|
||||
await payload.create({
|
||||
collection: Collections.Recorders,
|
||||
data: recorder,
|
||||
});
|
||||
if (
|
||||
isDefined(process.env.SEEDING_ADMIN_EMAIL) &&
|
||||
isDefined(process.env.SEEDING_ADMIN_PASSWORD) &&
|
||||
isDefined(process.env.SEEDING_ADMIN_USERNAME)
|
||||
) {
|
||||
if (recorders.docs.length === 0) {
|
||||
payload.logger.info("Seeding some initial data");
|
||||
|
||||
const recorder: PayloadCreateData<Recorder> = {
|
||||
email: process.env.SEEDING_ADMIN_EMAIL,
|
||||
password: process.env.SEEDING_ADMIN_PASSWORD,
|
||||
username: process.env.SEEDING_ADMIN_USERNAME,
|
||||
role: [RecordersRoles.Admin],
|
||||
anonymize: false,
|
||||
};
|
||||
await payload.create({
|
||||
collection: Collections.Recorders,
|
||||
data: recorder,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
|
|
@ -14,7 +14,7 @@ export type CategoryTranslations = {
|
|||
}[];
|
||||
export type RecorderBiographies = {
|
||||
language: string | Language;
|
||||
biography?: string;
|
||||
biography: string;
|
||||
id?: string;
|
||||
}[];
|
||||
export type ContentFoldersTranslation = {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import { CollectionConfig } from "payload/types";
|
||||
|
||||
export type PayloadCreateData<T> = Omit<
|
||||
T,
|
||||
"id" | "updatedAt" | "createdAt" | "sizes" | "updatedBy"
|
||||
>;
|
||||
|
||||
export type CollectionEndpoint = NonNullable<CollectionConfig["endpoints"]>[number];
|
|
@ -0,0 +1,14 @@
|
|||
export type StrapiLanguage = {
|
||||
data?: { attributes: { code: string } };
|
||||
};
|
||||
|
||||
export type StrapiImage = {
|
||||
data?: {
|
||||
attributes: {
|
||||
url: string;
|
||||
mime: string;
|
||||
name: string;
|
||||
size: number;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,5 +1,6 @@
|
|||
import payload from "payload";
|
||||
import { Collections, KeysTypes } from "../constants";
|
||||
import { StrapiImage } from "../types/strapi";
|
||||
import { isDefined } from "./asserts";
|
||||
|
||||
export const findWeaponType = async (name: string): Promise<string> => {
|
||||
|
@ -23,20 +24,10 @@ type UploadStrapiImage = {
|
|||
collection: Collections;
|
||||
};
|
||||
|
||||
type StrapiImage = {
|
||||
data?: {
|
||||
attributes: {
|
||||
url: string;
|
||||
mime: string;
|
||||
name: string;
|
||||
size: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
export const uploadStrapiImage = async ({
|
||||
collection,
|
||||
image,
|
||||
}: UploadStrapiImage): Promise<string> => {
|
||||
}: UploadStrapiImage): Promise<string | undefined> => {
|
||||
if (isDefined(image.data)) {
|
||||
const url = `${process.env.STRAPI_URI}${image.data.attributes.url}`;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Block, BlockField } from "payload/types";
|
||||
import { capitalize } from "./string";
|
||||
|
||||
const isDefined = <T>(value: T | null | undefined): value is T =>
|
||||
value !== null && value !== undefined;
|
||||
|
@ -26,11 +27,6 @@ export const generateBlocks = <T extends string>(blocksConfig: BlocksConfig<T>):
|
|||
recursionFieldName in block;
|
||||
|
||||
const getInterfaceName = (parents: T[], currentBlockName: T): string => {
|
||||
const capitalize = (text: string): string => {
|
||||
if (text.length === 0) return text;
|
||||
const [firstLetter, ...rest] = text;
|
||||
return [firstLetter.toUpperCase(), ...rest].join("");
|
||||
};
|
||||
return [...parents, currentBlockName]
|
||||
.map((blockName) => blocksConfig[blockName].block.slug)
|
||||
.map(capitalize)
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import tags from "language-tags";
|
||||
import { isUndefined } from "./asserts";
|
||||
|
||||
export const shortenEllipsis = (text: string, length: number): string =>
|
||||
text.length - 3 > length ? `${text.substring(0, length)}...` : text;
|
||||
|
||||
export const formatLanguageCode = (code: string): string =>
|
||||
tags(code).valid() ? tags(code).language().descriptions()[0] : code;
|
||||
tags(code).valid() ? tags(code).language()?.descriptions()[0] ?? code : code;
|
||||
|
||||
export const capitalize = (string: string): string => {
|
||||
const [firstLetter, ...otherLetters] = string;
|
||||
if (isUndefined(firstLetter)) return "";
|
||||
return [firstLetter.toUpperCase(), ...otherLetters].join("");
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
export type PayloadCreateData<T> = Omit<
|
||||
T,
|
||||
"id" | "updatedAt" | "createdAt" | "sizes" | "updatedBy"
|
||||
>;
|
120
tsconfig.json
120
tsconfig.json
|
@ -1,18 +1,116 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"moduleResolution": "NodeNext",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"strict": false,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"jsx": "react",
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
|
||||
"jsx": "react" /* Specify what JSX code is generated. */,
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs" /* Specify what module code is generated. */,
|
||||
"rootDir": "./src" /* Specify the root folder within your source files. */,
|
||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
"paths": {
|
||||
"payload/generated-types": ["./src/payload-types.ts"]
|
||||
}
|
||||
} /* Specify a set of entries that re-map imports to additional lookup locations. */,
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./dist" /* Specify an output folder for all emitted files. */,
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
"alwaysStrict": true /* Ensure 'use strict' is always emitted. */,
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
"noFallthroughCasesInSwitch": true /* Enable error reporting for fallthrough cases in switch statements. */,
|
||||
"noUncheckedIndexedAccess": true /* Add 'undefined' to a type when accessed using an index. */,
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist", "build"],
|
||||
|
|
Loading…
Reference in New Issue