Browse Source

impl validateThemePluginGrowiDirective

Yuki Takei 1 year ago
parent
commit
ad63d666b0

+ 18 - 0
packages/core/src/interfaces/growi-theme-metadata.ts

@@ -19,3 +19,21 @@ export type GrowiThemeMetadata = {
   createBtn: string,
   isPresetTheme?: boolean,
 };
+
+export const isGrowiThemeMetadata = (obj: unknown): obj is GrowiThemeMetadata => {
+  const objAny = obj as any;
+
+  return objAny != null
+    && typeof objAny === 'object'
+    && Array.isArray(objAny) === false
+    && 'name' in objAny && typeof objAny.name === 'string'
+    && 'manifestKey' in objAny && typeof objAny.manifestKey === 'string'
+    && 'schemeType' in objAny && typeof objAny.schemeType === 'string'
+    && 'lightBg' in objAny && typeof objAny.lightBg === 'string'
+    && 'darkBg' in objAny && typeof objAny.darkBg === 'string'
+    && 'lightSidebar' in objAny && typeof objAny.lightSidebar === 'string'
+    && 'darkSidebar' in objAny && typeof objAny.darkSidebar === 'string'
+    && 'lightIcon' in objAny && typeof objAny.lightIcon === 'string'
+    && 'darkIcon' in objAny && typeof objAny.darkIcon === 'string'
+    && 'createBtn' in objAny && typeof objAny.createBtn === 'string';
+};

+ 6 - 2
packages/pluginkit/src/model/growi-plugin-validation-data.ts

@@ -1,6 +1,6 @@
-import { GrowiPluginType } from '@growi/core';
+import type { GrowiPluginType, GrowiThemeMetadata } from '@growi/core';
 
-import { GrowiPluginDirective } from './growi-plugin-package-data';
+import type { GrowiPluginDirective } from './growi-plugin-package-data';
 
 export type GrowiPluginValidationData = {
   projectDirRoot: string,
@@ -13,3 +13,7 @@ export type GrowiPluginValidationData = {
 export type GrowiTemplatePluginValidationData = GrowiPluginValidationData & {
   supportingLocales: string[],
 }
+
+export type GrowiThemePluginValidationData = GrowiPluginValidationData & {
+  themes: GrowiThemeMetadata[],
+}

+ 1 - 0
packages/pluginkit/src/v4/server/utils/theme/index.ts

@@ -0,0 +1 @@
+export * from './validate-growi-plugin-directive';

+ 46 - 0
packages/pluginkit/src/v4/server/utils/theme/validate-growi-plugin-directive.ts

@@ -0,0 +1,46 @@
+import type { GrowiThemeMetadata } from '@growi/core';
+import { GrowiPluginType, isGrowiThemeMetadata } from '@growi/core';
+
+import type { GrowiPluginValidationData, GrowiThemePluginValidationData } from '../../../../model';
+import { GrowiPluginValidationError } from '../../../../model';
+import { validateGrowiDirective } from '../common';
+
+
+/**
+ * An utility for theme plugin which wrap 'validateGrowiDirective' of './common' module
+ * @param projectDirRoot
+ */
+export const validateThemePluginGrowiDirective = (projectDirRoot: string): GrowiThemePluginValidationData => {
+  const data = validateGrowiDirective(projectDirRoot, GrowiPluginType.Template);
+
+  const { growiPlugin } = data;
+
+  // check themes
+  if (growiPlugin.themes == null || !Array.isArray(growiPlugin.themes) || growiPlugin.themes.length === 0) {
+    throw new GrowiPluginValidationError<GrowiPluginValidationData>(
+      "Theme plugin must have 'themes' array and that must have one or more theme metadata",
+    );
+  }
+
+  const validMetadatas: GrowiThemeMetadata[] = [];
+  const invalidObjects: unknown[] = [];
+  growiPlugin.themes.forEach((theme: unknown) => {
+    if (isGrowiThemeMetadata(theme)) {
+      validMetadatas.push(theme);
+    }
+    else {
+      invalidObjects.push(theme);
+    }
+  });
+
+  if (invalidObjects.length > 0) {
+    throw new GrowiPluginValidationError<GrowiPluginValidationData>(
+      `Some of theme metadata are invalid: ${invalidObjects}`,
+    );
+  }
+
+  return {
+    ...data,
+    themes: validMetadatas,
+  };
+};

+ 0 - 0
packages/pluginkit/test/fixtures/example-package/invalid-theme1/index.js


+ 29 - 0
packages/pluginkit/test/fixtures/example-package/invalid-theme1/package.json

@@ -0,0 +1,29 @@
+{
+  "name": "example-package-invalid-theme1",
+  "version": "1.0.0",
+  "main": "index.js",
+  "growiPlugin": {
+    "schemaVersion": "4",
+    "types": ["theme"],
+    "themes": [
+      {
+        "name": "theme1-1",
+        "manifestKey": "src/styles/style.scss",
+        "schemeType": "light",
+        "lightBg": "#ff0000",
+        "darkBg": "#0000ff",
+        "lightSidebar": "#ffff00",
+        "darkSidebar": "#ff8800",
+        "lightIcon": "#ff0000",
+        "darkIcon": "#000000",
+        "createBtn": "#00ff00"
+      },
+      {
+        "name": "theme1-2",
+        "manifestKey": "src/styles/style.scss",
+        "schemeType": "light",
+        "// missing some attributes": ""
+      }
+    ]
+  }
+}