Browse Source

configure biome for core package excluding utils and models

Futa Arai 10 tháng trước cách đây
mục cha
commit
ff5fdaeb8c
34 tập tin đã thay đổi với 511 bổ sung405 xóa
  1. 2 1
      biome.json
  2. 4 0
      packages/core/.eslintignore
  3. 1 3
      packages/core/.eslintrc.cjs
  4. 1 1
      packages/core/package.json
  5. 2 1
      packages/core/src/consts/accepted-upload-file-type.ts
  6. 2 1
      packages/core/src/consts/growi-plugin.ts
  7. 4 2
      packages/core/src/consts/system.ts
  8. 1 1
      packages/core/src/consts/ydoc-status.ts
  9. 14 14
      packages/core/src/interfaces/attachment.ts
  10. 1 1
      packages/core/src/interfaces/color-scheme.ts
  11. 1 6
      packages/core/src/interfaces/common.spec.ts
  12. 18 14
      packages/core/src/interfaces/common.ts
  13. 20 9
      packages/core/src/interfaces/config-manager.ts
  14. 4 4
      packages/core/src/interfaces/external-account.ts
  15. 17 17
      packages/core/src/interfaces/growi-app-info.ts
  16. 4 4
      packages/core/src/interfaces/growi-facade.ts
  17. 41 26
      packages/core/src/interfaces/growi-theme-metadata.ts
  18. 1 1
      packages/core/src/interfaces/has-object-id.ts
  19. 1 1
      packages/core/src/interfaces/lang.ts
  20. 117 84
      packages/core/src/interfaces/page.ts
  21. 121 99
      packages/core/src/interfaces/primitive/string.spec.ts
  22. 16 6
      packages/core/src/interfaces/primitive/string.ts
  23. 18 18
      packages/core/src/interfaces/revision.ts
  24. 9 8
      packages/core/src/interfaces/subscription.ts
  25. 3 3
      packages/core/src/interfaces/tag.ts
  26. 33 33
      packages/core/src/interfaces/user.ts
  27. 7 7
      packages/core/src/interfaces/vite.ts
  28. 3 3
      packages/core/src/remark-plugins/interfaces/option-parser.ts
  29. 14 13
      packages/core/src/remark-plugins/util/option-parser.spec.ts
  30. 1 4
      packages/core/src/remark-plugins/util/option-parser.ts
  31. 23 10
      packages/core/src/swr/use-swr-static.ts
  32. 4 1
      packages/core/src/swr/with-utils.ts
  33. 2 6
      packages/core/tsconfig.json
  34. 1 3
      packages/core/vitest.config.ts

+ 2 - 1
biome.json

@@ -19,7 +19,8 @@
       ".stylelintrc.json",
       "package.json",
       "./apps/**",
-      "./packages/core/**",
+      "./packages/core/src/utils/**",
+      "./packages/core/src/models/**",
       "./packages/editor/**",
       "./packages/pdf-converter-client/**"
     ]

+ 4 - 0
packages/core/.eslintignore

@@ -1 +1,5 @@
 /dist/**
+/src/consts/**
+/src/interfaces/**
+/src/remark-plugins/**
+/src/swr/**

+ 1 - 3
packages/core/.eslintrc.cjs

@@ -1,5 +1,3 @@
 module.exports = {
-  extends: [
-    'plugin:vitest/recommended',
-  ],
+  extends: ['plugin:vitest/recommended'],
 };

+ 1 - 1
packages/core/package.json

@@ -60,7 +60,7 @@
     "clean": "shx rm -rf dist",
     "dev": "vite build --mode dev",
     "watch": "pnpm run dev -w --emptyOutDir=false",
-    "lint:js": "eslint **/*.{js,ts}",
+    "lint:js": "biome check",
     "lint:typecheck": "vue-tsc --noEmit",
     "lint": "npm-run-all -p lint:*",
     "test": "vitest run --coverage"

+ 2 - 1
packages/core/src/consts/accepted-upload-file-type.ts

@@ -3,4 +3,5 @@ export const AcceptedUploadFileType = {
   IMAGE: 'image',
   NONE: 'none',
 } as const;
-export type AcceptedUploadFileType = typeof AcceptedUploadFileType[keyof typeof AcceptedUploadFileType];
+export type AcceptedUploadFileType =
+  (typeof AcceptedUploadFileType)[keyof typeof AcceptedUploadFileType];

+ 2 - 1
packages/core/src/consts/growi-plugin.ts

@@ -4,4 +4,5 @@ export const GrowiPluginType = {
   Theme: 'theme',
   Script: 'script',
 } as const;
-export type GrowiPluginType = typeof GrowiPluginType[keyof typeof GrowiPluginType];
+export type GrowiPluginType =
+  (typeof GrowiPluginType)[keyof typeof GrowiPluginType];

+ 4 - 2
packages/core/src/consts/system.ts

@@ -12,6 +12,8 @@ export const GrowiDeploymentType = {
   others: 'others',
 } as const;
 
-export type GrowiServiceType = typeof GrowiServiceType[keyof typeof GrowiServiceType]
+export type GrowiServiceType =
+  (typeof GrowiServiceType)[keyof typeof GrowiServiceType];
 
-export type GrowiDeploymentType = typeof GrowiDeploymentType[keyof typeof GrowiDeploymentType]
+export type GrowiDeploymentType =
+  (typeof GrowiDeploymentType)[keyof typeof GrowiDeploymentType];

+ 1 - 1
packages/core/src/consts/ydoc-status.ts

@@ -12,4 +12,4 @@ export const YDocStatus = {
   OUTDATED: 'outdated',
   ISOLATED: 'isolated',
 } as const;
-export type YDocStatus = typeof YDocStatus[keyof typeof YDocStatus]
+export type YDocStatus = (typeof YDocStatus)[keyof typeof YDocStatus];

+ 14 - 14
packages/core/src/interfaces/attachment.ts

@@ -1,25 +1,25 @@
 import type { Ref } from './common';
-import { HasObjectId } from './has-object-id';
+import type { HasObjectId } from './has-object-id';
 import type { IPage } from './page';
 import type { IUser } from './user';
 
 export type IAttachment = {
-  page?: Ref<IPage>,
-  creator?: Ref<IUser>,
-  filePath?: string, // DEPRECATED: remains for backward compatibility for v3.3.x or below
-  fileName: string,
-  fileFormat: string,
-  fileSize: number,
-  originalName: string,
-  temporaryUrlCached?: string,
-  temporaryUrlExpiredAt?: Date,
-  attachmentType: string,
+  page?: Ref<IPage>;
+  creator?: Ref<IUser>;
+  filePath?: string; // DEPRECATED: remains for backward compatibility for v3.3.x or below
+  fileName: string;
+  fileFormat: string;
+  fileSize: number;
+  originalName: string;
+  temporaryUrlCached?: string;
+  temporaryUrlExpiredAt?: Date;
+  attachmentType: string;
 
-  createdAt: Date,
+  createdAt: Date;
 
   // virtual property
-  filePathProxied: string,
-  downloadPathProxied: string,
+  filePathProxied: string;
+  downloadPathProxied: string;
 };
 
 export type IAttachmentHasId = IAttachment & HasObjectId;

+ 1 - 1
packages/core/src/interfaces/color-scheme.ts

@@ -2,4 +2,4 @@ export const ColorScheme = {
   LIGHT: 'light',
   DARK: 'dark',
 } as const;
-export type ColorScheme = typeof ColorScheme[keyof typeof ColorScheme];
+export type ColorScheme = (typeof ColorScheme)[keyof typeof ColorScheme];

+ 1 - 6
packages/core/src/interfaces/common.spec.ts

@@ -4,10 +4,9 @@ import { mock } from 'vitest-mock-extended';
 
 import { getIdForRef, isPopulated } from './common';
 import type { IPageHasId } from './page';
-import { type IPage } from './page';
+import type { IPage } from './page';
 
 describe('isPopulated', () => {
-
   it('should return true when the argument implements HasObjectId', () => {
     // Arrange
     const ref = mock<IPageHasId>();
@@ -51,12 +50,9 @@ describe('isPopulated', () => {
     // Assert
     expect(result).toBe(false);
   });
-
 });
 
-
 describe('getIdForRef', () => {
-
   it('should return the id string when the argument is populated', () => {
     // Arrange
     const id = new Types.ObjectId();
@@ -106,5 +102,4 @@ describe('getIdForRef', () => {
     // Assert
     expect(result).toStrictEqual(ref);
   });
-
 });

+ 18 - 14
packages/core/src/interfaces/common.ts

@@ -9,29 +9,33 @@ import { isValidObjectId } from '../utils/objectid-utils';
 type ObjectId = Types.ObjectId;
 
 // Foreign key field
-export type Ref<T> = string | ObjectId | T & { _id: string | ObjectId };
+export type Ref<T> = string | ObjectId | (T & { _id: string | ObjectId });
 
 export type Nullable<T> = T | null | undefined;
 
 export const isRef = <T>(obj: unknown): obj is Ref<T> => {
-  return obj != null
-    && (
-      (typeof obj === 'string' && isValidObjectId(obj))
-        || (typeof obj === 'object' && '_bsontype' in obj && obj._bsontype === 'ObjectID')
-        || (typeof obj === 'object' && '_id' in obj)
-    );
+  return (
+    obj != null &&
+    ((typeof obj === 'string' && isValidObjectId(obj)) ||
+      (typeof obj === 'object' &&
+        '_bsontype' in obj &&
+        obj._bsontype === 'ObjectID') ||
+      (typeof obj === 'object' && '_id' in obj))
+  );
 };
 
-export const isPopulated = <T>(ref: Ref<T>): ref is T & { _id: string | ObjectId } => {
-  return ref != null
-    && typeof ref !== 'string'
-    && !('_bsontype' in ref && ref._bsontype === 'ObjectID');
+export const isPopulated = <T>(
+  ref: Ref<T>,
+): ref is T & { _id: string | ObjectId } => {
+  return (
+    ref != null &&
+    typeof ref !== 'string' &&
+    !('_bsontype' in ref && ref._bsontype === 'ObjectID')
+  );
 };
 
 export const getIdForRef = <T>(ref: Ref<T>): string | ObjectId => {
-  return isPopulated(ref)
-    ? ref._id
-    : ref;
+  return isPopulated(ref) ? ref._id : ref;
 };
 
 export const getIdStringForRef = <T>(ref: Ref<T>): string => {

+ 20 - 9
packages/core/src/interfaces/config-manager.ts

@@ -5,7 +5,7 @@ export const ConfigSource = {
   env: 'env',
   db: 'db',
 } as const;
-export type ConfigSource = typeof ConfigSource[keyof typeof ConfigSource];
+export type ConfigSource = (typeof ConfigSource)[keyof typeof ConfigSource];
 
 /**
  * Metadata for a configuration value
@@ -19,7 +19,9 @@ export interface ConfigDefinition<T> {
 /**
  * Helper function for defining configurations with type safety
  */
-export const defineConfig = <T>(config: ConfigDefinition<T>): ConfigDefinition<T> => config;
+export const defineConfig = <T>(
+  config: ConfigDefinition<T>,
+): ConfigDefinition<T> => config;
 
 /**
  * Interface for loading configuration values
@@ -38,10 +40,13 @@ export interface IConfigLoader<K extends string, V extends Record<K, any>> {
 }
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type RawConfigData<K extends string, V extends Record<K, any>> = Record<K, {
-  value: V[K];
-  definition?: ConfigDefinition<V[K]>;
-}>;
+export type RawConfigData<K extends string, V extends Record<K, any>> = Record<
+  K,
+  {
+    value: V[K];
+    definition?: ConfigDefinition<V[K]>;
+  }
+>;
 
 export type UpdateConfigOptions = {
   skipPubsub?: boolean;
@@ -67,12 +72,19 @@ export interface IConfigManager<K extends string, V extends Record<K, any>> {
   /**
    * Update a configuration value
    */
-  updateConfig<T extends K>(key: T, value: V[T], options?: UpdateConfigOptions): Promise<void>;
+  updateConfig<T extends K>(
+    key: T,
+    value: V[T],
+    options?: UpdateConfigOptions,
+  ): Promise<void>;
 
   /**
    * Update multiple configuration values
    */
-  updateConfigs(updates: Partial<{ [T in K]: V[T] }>, options?: UpdateConfigOptions): Promise<void>;
+  updateConfigs(
+    updates: Partial<{ [T in K]: V[T] }>,
+    options?: UpdateConfigOptions,
+  ): Promise<void>;
 
   /**
    * Remove multiple configuration values
@@ -83,5 +95,4 @@ export interface IConfigManager<K extends string, V extends Record<K, any>> {
    * Get environment variables managed with ConfigDefinitions
    */
   getManagedEnvVars(showSecretValues: boolean): Record<string, string>;
-
 }

+ 4 - 4
packages/core/src/interfaces/external-account.ts

@@ -2,7 +2,7 @@ import type { Ref } from './common';
 import type { IUser } from './user';
 
 export type IExternalAccount<P> = {
-  providerType: P,
-  accountId: string,
-  user: Ref<IUser>,
-}
+  providerType: P;
+  accountId: string;
+  user: Ref<IUser>;
+};

+ 17 - 17
packages/core/src/interfaces/growi-app-info.ts

@@ -3,29 +3,29 @@ import type * as os from 'node:os';
 import type { GrowiDeploymentType, GrowiServiceType } from '../consts/system';
 
 export const GrowiWikiType = { open: 'open', closed: 'closed' } as const;
-type GrowiWikiType = typeof GrowiWikiType[keyof typeof GrowiWikiType]
+type GrowiWikiType = (typeof GrowiWikiType)[keyof typeof GrowiWikiType];
 
 interface IGrowiOSInfo {
-  type?: ReturnType<typeof os.type>
-  platform?: ReturnType<typeof os.platform>
-  arch?: ReturnType<typeof os.arch>
-  totalmem?: ReturnType<typeof os.totalmem>
+  type?: ReturnType<typeof os.type>;
+  platform?: ReturnType<typeof os.platform>;
+  arch?: ReturnType<typeof os.arch>;
+  totalmem?: ReturnType<typeof os.totalmem>;
 }
 
 export interface IGrowiAdditionalInfo {
-  installedAt: Date
-  installedAtByOldestUser: Date | null
-  currentUsersCount: number
-  currentActiveUsersCount: number
+  installedAt: Date;
+  installedAtByOldestUser: Date | null;
+  currentUsersCount: number;
+  currentActiveUsersCount: number;
 }
 
 export interface IGrowiInfo<A extends object = IGrowiAdditionalInfo> {
-  serviceInstanceId: string
-  appSiteUrl: string
-  osInfo: IGrowiOSInfo
-  version: string
-  type: GrowiServiceType
-  wikiType: GrowiWikiType
-  deploymentType: GrowiDeploymentType
-  additionalInfo?: A
+  serviceInstanceId: string;
+  appSiteUrl: string;
+  osInfo: IGrowiOSInfo;
+  version: string;
+  type: GrowiServiceType;
+  wikiType: GrowiWikiType;
+  deploymentType: GrowiDeploymentType;
+  additionalInfo?: A;
 }

+ 4 - 4
packages/core/src/interfaces/growi-facade.ts

@@ -5,8 +5,8 @@ export type GrowiFacade = {
       customGenerateViewOptions?: any;
       generatePreviewOptions?: any;
       customGeneratePreviewOptions?: any;
-    },
-    optionsMutators?: any,
-  },
-  react?: any,
+    };
+    optionsMutators?: any;
+  };
+  react?: any;
 };

+ 41 - 26
packages/core/src/interfaces/growi-theme-metadata.ts

@@ -4,36 +4,51 @@ export const GrowiThemeSchemeType = {
   ...ColorScheme,
   BOTH: 'both',
 } as const;
-export type GrowiThemeSchemeType = typeof GrowiThemeSchemeType[keyof typeof GrowiThemeSchemeType];
+export type GrowiThemeSchemeType =
+  (typeof GrowiThemeSchemeType)[keyof typeof GrowiThemeSchemeType];
 
 export type GrowiThemeMetadata = {
-  name: string,
-  manifestKey: string,
-  schemeType: GrowiThemeSchemeType,
-  lightBg: string,
-  darkBg: string,
-  lightSidebar: string,
-  darkSidebar: string,
-  lightIcon: string,
-  darkIcon: string,
-  createBtn: string,
-  isPresetTheme?: boolean,
+  name: string;
+  manifestKey: string;
+  schemeType: GrowiThemeSchemeType;
+  lightBg: string;
+  darkBg: string;
+  lightSidebar: string;
+  darkSidebar: string;
+  lightIcon: string;
+  darkIcon: string;
+  createBtn: string;
+  isPresetTheme?: boolean;
 };
 
-export const isGrowiThemeMetadata = (obj: unknown): obj is GrowiThemeMetadata => {
+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';
+  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'
+  );
 };

+ 1 - 1
packages/core/src/interfaces/has-object-id.ts

@@ -1,3 +1,3 @@
 export type HasObjectId = {
-  _id: string,
+  _id: string;
 };

+ 1 - 1
packages/core/src/interfaces/lang.ts

@@ -5,4 +5,4 @@ export const Lang = {
   fr_FR: 'fr_FR',
 } as const;
 export const AllLang = Object.values(Lang);
-export type Lang = typeof Lang[keyof typeof Lang];
+export type Lang = (typeof Lang)[keyof typeof Lang];

+ 117 - 84
packages/core/src/interfaces/page.ts

@@ -1,56 +1,69 @@
 import type { Ref } from './common';
 import type { HasObjectId } from './has-object-id';
-import type { IRevision, HasRevisionShortbody, IRevisionHasId } from './revision';
+import type {
+  HasRevisionShortbody,
+  IRevision,
+  IRevisionHasId,
+} from './revision';
 import type { SubscriptionStatusType } from './subscription';
 import type { ITag } from './tag';
-import type {
-  IUser, IUserGroup, IUserGroupHasId, IUserHasId,
-} from './user';
+import type { IUser, IUserGroup, IUserGroupHasId, IUserHasId } from './user';
 
-export const GroupType = { userGroup: 'UserGroup', externalUserGroup: 'ExternalUserGroup' } as const;
-export type GroupType = typeof GroupType[keyof typeof GroupType];
+export const GroupType = {
+  userGroup: 'UserGroup',
+  externalUserGroup: 'ExternalUserGroup',
+} as const;
+export type GroupType = (typeof GroupType)[keyof typeof GroupType];
 
 export type IGrantedGroup = {
-  type: GroupType,
-  item: Ref<IUserGroup>,
-}
+  type: GroupType;
+  item: Ref<IUserGroup>;
+};
 
 export type IPage = {
-  path: string,
-  status: string,
-  revision?: Ref<IRevision>,
-  tags: Ref<ITag>[],
-  creator?: Ref<IUser>,
-  createdAt: Date,
-  updatedAt: Date,
-  seenUsers: Ref<IUser>[],
-  parent: Ref<IPage> | null,
-  descendantCount: number,
-  isEmpty: boolean,
-  grant: PageGrant,
-  grantedUsers: Ref<IUser>[],
-  grantedGroups: IGrantedGroup[],
-  lastUpdateUser?: Ref<IUser>,
-  liker: Ref<IUser>[],
-  commentCount: number
-  slackChannels: string,
-  deleteUser: Ref<IUser>,
-  deletedAt: Date,
-  latestRevision?: Ref<IRevision>,
-  latestRevisionBodyLength?: number,
-  expandContentWidth?: boolean,
-  wip?: boolean,
-  ttlTimestamp?: Date
-}
-
-export type IPagePopulatedToShowRevision = Omit<IPageHasId, 'lastUpdateUser'|'creator'|'deleteUser'|'grantedGroups'|'revision'|'author'> & {
-  lastUpdateUser?: IUserHasId,
-  creator?: IUserHasId,
-  deleteUser: IUserHasId,
-  grantedGroups: { type: GroupType, item: IUserGroupHasId }[],
-  revision?: IRevisionHasId,
-  author: IUserHasId,
-}
+  path: string;
+  status: string;
+  revision?: Ref<IRevision>;
+  tags: Ref<ITag>[];
+  creator?: Ref<IUser>;
+  createdAt: Date;
+  updatedAt: Date;
+  seenUsers: Ref<IUser>[];
+  parent: Ref<IPage> | null;
+  descendantCount: number;
+  isEmpty: boolean;
+  grant: PageGrant;
+  grantedUsers: Ref<IUser>[];
+  grantedGroups: IGrantedGroup[];
+  lastUpdateUser?: Ref<IUser>;
+  liker: Ref<IUser>[];
+  commentCount: number;
+  slackChannels: string;
+  deleteUser: Ref<IUser>;
+  deletedAt: Date;
+  latestRevision?: Ref<IRevision>;
+  latestRevisionBodyLength?: number;
+  expandContentWidth?: boolean;
+  wip?: boolean;
+  ttlTimestamp?: Date;
+};
+
+export type IPagePopulatedToShowRevision = Omit<
+  IPageHasId,
+  | 'lastUpdateUser'
+  | 'creator'
+  | 'deleteUser'
+  | 'grantedGroups'
+  | 'revision'
+  | 'author'
+> & {
+  lastUpdateUser?: IUserHasId;
+  creator?: IUserHasId;
+  deleteUser: IUserHasId;
+  grantedGroups: { type: GroupType; item: IUserGroupHasId }[];
+  revision?: IRevisionHasId;
+  author: IUserHasId;
+};
 
 export const PageGrant = {
   GRANT_PUBLIC: 1,
@@ -60,68 +73,83 @@ export const PageGrant = {
   GRANT_USER_GROUP: 5,
 } as const;
 type UnionPageGrantKeys = keyof typeof PageGrant;
-export type PageGrant = typeof PageGrant[UnionPageGrantKeys];
+export type PageGrant = (typeof PageGrant)[UnionPageGrantKeys];
 
 export const PageStatus = {
   STATUS_PUBLISHED: 'published',
   STATUS_DELETED: 'deleted',
 } as const;
-export type PageStatus = typeof PageStatus[keyof typeof PageStatus];
+export type PageStatus = (typeof PageStatus)[keyof typeof PageStatus];
 
 export type IPageHasId = IPage & HasObjectId;
 
 export type IPageInfo = {
-  isV5Compatible: boolean,
-  isEmpty: boolean,
-  isMovable: boolean,
-  isDeletable: boolean,
-  isAbleToDeleteCompletely: boolean,
-  isRevertible: boolean,
-}
+  isV5Compatible: boolean;
+  isEmpty: boolean;
+  isMovable: boolean;
+  isDeletable: boolean;
+  isAbleToDeleteCompletely: boolean;
+  isRevertible: boolean;
+};
 
 export type IPageInfoForEntity = IPageInfo & {
-  bookmarkCount: number,
-  sumOfLikers: number,
-  likerIds: string[],
-  sumOfSeenUsers: number,
-  seenUserIds: string[],
-  contentAge: number,
-  descendantCount: number,
-  commentCount: number,
-}
+  bookmarkCount: number;
+  sumOfLikers: number;
+  likerIds: string[];
+  sumOfSeenUsers: number;
+  seenUserIds: string[];
+  contentAge: number;
+  descendantCount: number;
+  commentCount: number;
+};
 
 export type IPageInfoForOperation = IPageInfoForEntity & {
-  isBookmarked?: boolean,
-  isLiked?: boolean,
-  subscriptionStatus?: SubscriptionStatusType,
-}
+  isBookmarked?: boolean;
+  isLiked?: boolean;
+  subscriptionStatus?: SubscriptionStatusType;
+};
 
 export type IPageInfoForListing = IPageInfoForEntity & HasRevisionShortbody;
 
-export type IPageInfoAll = IPageInfo | IPageInfoForEntity | IPageInfoForOperation | IPageInfoForListing;
+export type IPageInfoAll =
+  | IPageInfo
+  | IPageInfoForEntity
+  | IPageInfoForOperation
+  | IPageInfoForListing;
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const isIPageInfo = (pageInfo: any | undefined): pageInfo is IPageInfo => {
-  return pageInfo != null && pageInfo instanceof Object
-    && ('isEmpty' in pageInfo);
+export const isIPageInfo = (
+  pageInfo: any | undefined,
+): pageInfo is IPageInfo => {
+  return (
+    pageInfo != null && pageInfo instanceof Object && 'isEmpty' in pageInfo
+  );
 };
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const isIPageInfoForEntity = (pageInfo: any | undefined): pageInfo is IPageInfoForEntity => {
-  return isIPageInfo(pageInfo)
-    && pageInfo.isEmpty === false;
+export const isIPageInfoForEntity = (
+  pageInfo: any | undefined,
+): pageInfo is IPageInfoForEntity => {
+  return isIPageInfo(pageInfo) && pageInfo.isEmpty === false;
 };
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const isIPageInfoForOperation = (pageInfo: any | undefined): pageInfo is IPageInfoForOperation => {
-  return isIPageInfoForEntity(pageInfo)
-    && ('isBookmarked' in pageInfo || 'isLiked' in pageInfo || 'subscriptionStatus' in pageInfo);
+export const isIPageInfoForOperation = (
+  pageInfo: any | undefined,
+): pageInfo is IPageInfoForOperation => {
+  return (
+    isIPageInfoForEntity(pageInfo) &&
+    ('isBookmarked' in pageInfo ||
+      'isLiked' in pageInfo ||
+      'subscriptionStatus' in pageInfo)
+  );
 };
 
 // eslint-disable-next-line @typescript-eslint/no-explicit-any
-export const isIPageInfoForListing = (pageInfo: any | undefined): pageInfo is IPageInfoForListing => {
-  return isIPageInfoForEntity(pageInfo)
-    && 'revisionShortBody' in pageInfo;
+export const isIPageInfoForListing = (
+  pageInfo: any | undefined,
+): pageInfo is IPageInfoForListing => {
+  return isIPageInfoForEntity(pageInfo) && 'revisionShortBody' in pageInfo;
 };
 
 // export type IPageInfoTypeResolver<T extends IPageInfo> =
@@ -141,11 +169,16 @@ export const isIPageInfoForListing = (pageInfo: any | undefined): pageInfo is IP
 // };
 
 export type IDataWithMeta<D = unknown, M = unknown> = {
-  data: D,
-  meta?: M,
-}
+  data: D;
+  meta?: M;
+};
 
 export type IPageWithMeta<M = IPageInfoAll> = IDataWithMeta<IPageHasId, M>;
 
-export type IPageToDeleteWithMeta<T = IPageInfoForEntity | unknown> = IDataWithMeta<HasObjectId & (IPage | { path: string, revision: string | null}), T>;
-export type IPageToRenameWithMeta<T = IPageInfoForEntity | unknown> = IPageToDeleteWithMeta<T>;
+export type IPageToDeleteWithMeta<T = IPageInfoForEntity | unknown> =
+  IDataWithMeta<
+    HasObjectId & (IPage | { path: string; revision: string | null }),
+    T
+  >;
+export type IPageToRenameWithMeta<T = IPageInfoForEntity | unknown> =
+  IPageToDeleteWithMeta<T>;

+ 121 - 99
packages/core/src/interfaces/primitive/string.spec.ts

@@ -1,147 +1,169 @@
 import { describe, expect, it } from 'vitest';
 
 import {
-  isNonEmptyString,
-  toNonEmptyString,
-  toNonEmptyStringOrUndefined,
   isNonBlankString,
+  isNonEmptyString,
   toNonBlankString,
   toNonBlankStringOrUndefined,
+  toNonEmptyString,
+  toNonEmptyStringOrUndefined,
 } from './string';
 
 describe('isNonEmptyString', () => {
   /* eslint-disable indent */
   it.each`
-    input         | expected      | description
-    ${'hello'}    | ${true}       | ${'non-empty string'}
-    ${'world'}    | ${true}       | ${'non-empty string'}
-    ${'a'}        | ${true}       | ${'single character'}
-    ${'1'}        | ${true}       | ${'numeric string'}
-    ${' '}        | ${true}       | ${'space character'}
-    ${'   '}      | ${true}       | ${'multiple spaces'}
-    ${''}         | ${false}      | ${'empty string'}
-    ${null}       | ${false}      | ${'null'}
-    ${undefined}  | ${false}      | ${'undefined'}
-  `('should return $expected for $description: $input', ({ input, expected }) => {
-  /* eslint-enable indent */
-    expect(isNonEmptyString(input)).toBe(expected);
-  });
+    input        | expected | description
+    ${'hello'}   | ${true}  | ${'non-empty string'}
+    ${'world'}   | ${true}  | ${'non-empty string'}
+    ${'a'}       | ${true}  | ${'single character'}
+    ${'1'}       | ${true}  | ${'numeric string'}
+    ${' '}       | ${true}  | ${'space character'}
+    ${'   '}     | ${true}  | ${'multiple spaces'}
+    ${''}        | ${false} | ${'empty string'}
+    ${null}      | ${false} | ${'null'}
+    ${undefined} | ${false} | ${'undefined'}
+  `(
+    'should return $expected for $description: $input',
+    ({ input, expected }) => {
+      /* eslint-enable indent */
+      expect(isNonEmptyString(input)).toBe(expected);
+    },
+  );
 });
 
 describe('isNonBlankString', () => {
   /* eslint-disable indent */
   it.each`
-    input         | expected      | description
-    ${'hello'}    | ${true}       | ${'non-blank string'}
-    ${'world'}    | ${true}       | ${'non-blank string'}
-    ${'a'}        | ${true}       | ${'single character'}
-    ${'1'}        | ${true}       | ${'numeric string'}
-    ${' '}        | ${false}      | ${'space character'}
-    ${'   '}      | ${false}      | ${'multiple spaces'}
-    ${'\t'}       | ${false}      | ${'tab character'}
-    ${'\n'}       | ${false}      | ${'newline character'}
-    ${''}         | ${false}      | ${'empty string'}
-    ${null}       | ${false}      | ${'null'}
-    ${undefined}  | ${false}      | ${'undefined'}
-  `('should return $expected for $description: $input', ({ input, expected }) => {
-  /* eslint-enable indent */
-    expect(isNonBlankString(input)).toBe(expected);
-  });
+    input        | expected | description
+    ${'hello'}   | ${true}  | ${'non-blank string'}
+    ${'world'}   | ${true}  | ${'non-blank string'}
+    ${'a'}       | ${true}  | ${'single character'}
+    ${'1'}       | ${true}  | ${'numeric string'}
+    ${' '}       | ${false} | ${'space character'}
+    ${'   '}     | ${false} | ${'multiple spaces'}
+    ${'\t'}      | ${false} | ${'tab character'}
+    ${'\n'}      | ${false} | ${'newline character'}
+    ${''}        | ${false} | ${'empty string'}
+    ${null}      | ${false} | ${'null'}
+    ${undefined} | ${false} | ${'undefined'}
+  `(
+    'should return $expected for $description: $input',
+    ({ input, expected }) => {
+      /* eslint-enable indent */
+      expect(isNonBlankString(input)).toBe(expected);
+    },
+  );
 });
 
 describe('toNonEmptyStringOrUndefined', () => {
   /* eslint-disable indent */
   it.each`
-    input         | expected      | description
-    ${'hello'}    | ${'hello'}    | ${'non-empty string'}
-    ${'world'}    | ${'world'}    | ${'non-empty string'}
-    ${'a'}        | ${'a'}        | ${'single character'}
-    ${'1'}        | ${'1'}        | ${'numeric string'}
-    ${' '}        | ${' '}        | ${'space character'}
-    ${'   '}      | ${'   '}      | ${'multiple spaces'}
-    ${''}         | ${undefined}  | ${'empty string'}
-    ${null}       | ${undefined}  | ${'null'}
-    ${undefined}  | ${undefined}  | ${'undefined'}
-  `('should return $expected for $description: $input', ({ input, expected }) => {
-  /* eslint-enable indent */
-    expect(toNonEmptyStringOrUndefined(input)).toBe(expected);
-  });
+    input        | expected     | description
+    ${'hello'}   | ${'hello'}   | ${'non-empty string'}
+    ${'world'}   | ${'world'}   | ${'non-empty string'}
+    ${'a'}       | ${'a'}       | ${'single character'}
+    ${'1'}       | ${'1'}       | ${'numeric string'}
+    ${' '}       | ${' '}       | ${'space character'}
+    ${'   '}     | ${'   '}     | ${'multiple spaces'}
+    ${''}        | ${undefined} | ${'empty string'}
+    ${null}      | ${undefined} | ${'null'}
+    ${undefined} | ${undefined} | ${'undefined'}
+  `(
+    'should return $expected for $description: $input',
+    ({ input, expected }) => {
+      /* eslint-enable indent */
+      expect(toNonEmptyStringOrUndefined(input)).toBe(expected);
+    },
+  );
 });
 
 describe('toNonBlankStringOrUndefined', () => {
   /* eslint-disable indent */
   it.each`
-    input         | expected      | description
-    ${'hello'}    | ${'hello'}    | ${'non-blank string'}
-    ${'world'}    | ${'world'}    | ${'non-blank string'}
-    ${'a'}        | ${'a'}        | ${'single character'}
-    ${'1'}        | ${'1'}        | ${'numeric string'}
-    ${' '}        | ${undefined}  | ${'space character'}
-    ${'   '}      | ${undefined}  | ${'multiple spaces'}
-    ${'\t'}       | ${undefined}  | ${'tab character'}
-    ${'\n'}       | ${undefined}  | ${'newline character'}
-    ${''}         | ${undefined}  | ${'empty string'}
-    ${null}       | ${undefined}  | ${'null'}
-    ${undefined}  | ${undefined}  | ${'undefined'}
-  `('should return $expected for $description: $input', ({ input, expected }) => {
-  /* eslint-enable indent */
-    expect(toNonBlankStringOrUndefined(input)).toBe(expected);
-  });
+    input        | expected     | description
+    ${'hello'}   | ${'hello'}   | ${'non-blank string'}
+    ${'world'}   | ${'world'}   | ${'non-blank string'}
+    ${'a'}       | ${'a'}       | ${'single character'}
+    ${'1'}       | ${'1'}       | ${'numeric string'}
+    ${' '}       | ${undefined} | ${'space character'}
+    ${'   '}     | ${undefined} | ${'multiple spaces'}
+    ${'\t'}      | ${undefined} | ${'tab character'}
+    ${'\n'}      | ${undefined} | ${'newline character'}
+    ${''}        | ${undefined} | ${'empty string'}
+    ${null}      | ${undefined} | ${'null'}
+    ${undefined} | ${undefined} | ${'undefined'}
+  `(
+    'should return $expected for $description: $input',
+    ({ input, expected }) => {
+      /* eslint-enable indent */
+      expect(toNonBlankStringOrUndefined(input)).toBe(expected);
+    },
+  );
 });
 
 describe('toNonEmptyString', () => {
   /* eslint-disable indent */
   it.each`
-    input         | expected      | description
-    ${'hello'}    | ${'hello'}    | ${'non-empty string'}
-    ${'world'}    | ${'world'}    | ${'non-empty string'}
-    ${'a'}        | ${'a'}        | ${'single character'}
-    ${'1'}        | ${'1'}        | ${'numeric string'}
-    ${' '}        | ${' '}        | ${'space character'}
-    ${'   '}      | ${'   '}      | ${'multiple spaces'}
-  `('should return $expected for valid $description: $input', ({ input, expected }) => {
-  /* eslint-enable indent */
-    expect(toNonEmptyString(input)).toBe(expected);
-  });
+    input      | expected   | description
+    ${'hello'} | ${'hello'} | ${'non-empty string'}
+    ${'world'} | ${'world'} | ${'non-empty string'}
+    ${'a'}     | ${'a'}     | ${'single character'}
+    ${'1'}     | ${'1'}     | ${'numeric string'}
+    ${' '}     | ${' '}     | ${'space character'}
+    ${'   '}   | ${'   '}   | ${'multiple spaces'}
+  `(
+    'should return $expected for valid $description: $input',
+    ({ input, expected }) => {
+      /* eslint-enable indent */
+      expect(toNonEmptyString(input)).toBe(expected);
+    },
+  );
 
   /* eslint-disable indent */
   it.each`
-    input         | description
-    ${''}         | ${'empty string'}
-    ${null}       | ${'null'}
-    ${undefined}  | ${'undefined'}
+    input        | description
+    ${''}        | ${'empty string'}
+    ${null}      | ${'null'}
+    ${undefined} | ${'undefined'}
   `('should throw error for invalid $description: $input', ({ input }) => {
-  /* eslint-enable indent */
-    expect(() => toNonEmptyString(input)).toThrow('Expected a non-empty string, but received:');
+    /* eslint-enable indent */
+    expect(() => toNonEmptyString(input)).toThrow(
+      'Expected a non-empty string, but received:',
+    );
   });
 });
 
 describe('toNonBlankString', () => {
   /* eslint-disable indent */
   it.each`
-    input         | expected      | description
-    ${'hello'}    | ${'hello'}    | ${'non-blank string'}
-    ${'world'}    | ${'world'}    | ${'non-blank string'}
-    ${'a'}        | ${'a'}        | ${'single character'}
-    ${'1'}        | ${'1'}        | ${'numeric string'}
-  `('should return $expected for valid $description: $input', ({ input, expected }) => {
-  /* eslint-enable indent */
-    expect(toNonBlankString(input)).toBe(expected);
-  });
+    input      | expected   | description
+    ${'hello'} | ${'hello'} | ${'non-blank string'}
+    ${'world'} | ${'world'} | ${'non-blank string'}
+    ${'a'}     | ${'a'}     | ${'single character'}
+    ${'1'}     | ${'1'}     | ${'numeric string'}
+  `(
+    'should return $expected for valid $description: $input',
+    ({ input, expected }) => {
+      /* eslint-enable indent */
+      expect(toNonBlankString(input)).toBe(expected);
+    },
+  );
 
   /* eslint-disable indent */
   it.each`
-    input         | description
-    ${' '}        | ${'space character'}
-    ${'   '}      | ${'multiple spaces'}
-    ${'\t'}       | ${'tab character'}
-    ${'\n'}       | ${'newline character'}
-    ${''}         | ${'empty string'}
-    ${null}       | ${'null'}
-    ${undefined}  | ${'undefined'}
+    input        | description
+    ${' '}       | ${'space character'}
+    ${'   '}     | ${'multiple spaces'}
+    ${'\t'}      | ${'tab character'}
+    ${'\n'}      | ${'newline character'}
+    ${''}        | ${'empty string'}
+    ${null}      | ${'null'}
+    ${undefined} | ${'undefined'}
   `('should throw error for invalid $description: $input', ({ input }) => {
-  /* eslint-enable indent */
-    expect(() => toNonBlankString(input)).toThrow('Expected a non-blank string, but received:');
+    /* eslint-enable indent */
+    expect(() => toNonBlankString(input)).toThrow(
+      'Expected a non-blank string, but received:',
+    );
   });
 });
 

+ 16 - 6
packages/core/src/interfaces/primitive/string.ts

@@ -9,7 +9,9 @@ export type NonEmptyString = string & { readonly __brand: unique symbol };
  * @param value - The value to check
  * @returns True if the value is a string with length > 0, false otherwise
  */
-export const isNonEmptyString = (value: string | null | undefined): value is NonEmptyString => {
+export const isNonEmptyString = (
+  value: string | null | undefined,
+): value is NonEmptyString => {
   return value != null && value.length > 0;
 };
 
@@ -21,7 +23,8 @@ export const isNonEmptyString = (value: string | null | undefined): value is Non
  */
 export const toNonEmptyString = (value: string): NonEmptyString => {
   // throw Error if the value is null, undefined or empty
-  if (!isNonEmptyString(value)) throw new Error(`Expected a non-empty string, but received: ${value}`);
+  if (!isNonEmptyString(value))
+    throw new Error(`Expected a non-empty string, but received: ${value}`);
   return value;
 };
 
@@ -30,7 +33,9 @@ export const toNonEmptyString = (value: string): NonEmptyString => {
  * @param value - The string to convert
  * @returns The string as NonEmptyString type, or undefined if the value is null, undefined, or empty
  */
-export const toNonEmptyStringOrUndefined = (value: string | null | undefined): NonEmptyString | undefined => {
+export const toNonEmptyStringOrUndefined = (
+  value: string | null | undefined,
+): NonEmptyString | undefined => {
   // return undefined if the value is null, undefined or empty
   if (!isNonEmptyString(value)) return undefined;
   return value;
@@ -49,7 +54,9 @@ export type NonBlankString = string & { readonly __brand: unique symbol };
  * @param value - The value to check
  * @returns True if the value is a string with trimmed length > 0, false otherwise
  */
-export const isNonBlankString = (value: string | null | undefined): value is NonBlankString => {
+export const isNonBlankString = (
+  value: string | null | undefined,
+): value is NonBlankString => {
   return value != null && value.trim().length > 0;
 };
 
@@ -61,7 +68,8 @@ export const isNonBlankString = (value: string | null | undefined): value is Non
  */
 export const toNonBlankString = (value: string): NonBlankString => {
   // throw Error if the value is null, undefined or empty
-  if (!isNonBlankString(value)) throw new Error(`Expected a non-blank string, but received: ${value}`);
+  if (!isNonBlankString(value))
+    throw new Error(`Expected a non-blank string, but received: ${value}`);
   return value;
 };
 
@@ -70,7 +78,9 @@ export const toNonBlankString = (value: string): NonBlankString => {
  * @param value - The string to convert
  * @returns The string as NonBlankString type, or undefined if the value is null, undefined, empty, or contains only whitespace characters
  */
-export const toNonBlankStringOrUndefined = (value: string | null | undefined): NonBlankString | undefined => {
+export const toNonBlankStringOrUndefined = (
+  value: string | null | undefined,
+): NonBlankString | undefined => {
   // return undefined if the value is null, undefined or blank (empty or whitespace only)
   if (!isNonBlankString(value)) return undefined;
   return value;

+ 18 - 18
packages/core/src/interfaces/revision.ts

@@ -8,33 +8,33 @@ export const Origin = {
   Editor: 'editor',
 } as const;
 
-export type Origin = typeof Origin[keyof typeof Origin];
+export type Origin = (typeof Origin)[keyof typeof Origin];
 
 export const allOrigin = Object.values(Origin);
 
 export type IRevision = {
-  pageId: Ref<IPage>,
-  body: string,
-  author: Ref<IUser>,
-  format: string,
+  pageId: Ref<IPage>;
+  body: string;
+  author: Ref<IUser>;
+  format: string;
   hasDiffToPrev?: boolean;
-  origin?: Origin,
-  createdAt: Date,
-  updatedAt: Date,
-}
+  origin?: Origin;
+  createdAt: Date;
+  updatedAt: Date;
+};
 
 export type IRevisionHasId = IRevision & HasObjectId;
 
 export type IRevisionsForPagination = {
-  revisions: IRevisionHasId[], // revisions in one pagination
-  totalCounts: number // total counts
-}
+  revisions: IRevisionHasId[]; // revisions in one pagination
+  totalCounts: number; // total counts
+};
 export type HasRevisionShortbody = {
-  revisionShortBody?: string,
-}
+  revisionShortBody?: string;
+};
 
 export type SWRInfinitePageRevisionsResponse = {
-  revisions: IRevisionHasId[],
-  totalCount: number,
-  offset: number,
-}
+  revisions: IRevisionHasId[];
+  totalCount: number;
+  offset: number;
+};

+ 9 - 8
packages/core/src/interfaces/subscription.ts

@@ -7,15 +7,16 @@ export const SubscriptionStatusType = {
   UNSUBSCRIBE: 'UNSUBSCRIBE',
 } as const;
 export const AllSubscriptionStatusType = Object.values(SubscriptionStatusType);
-export type SubscriptionStatusType = typeof SubscriptionStatusType[keyof typeof SubscriptionStatusType];
+export type SubscriptionStatusType =
+  (typeof SubscriptionStatusType)[keyof typeof SubscriptionStatusType];
 
 export interface ISubscription {
-  user: Ref<IUser>
-  targetModel: string
-  target: Ref<IPage>
-  status: string
-  createdAt: Date
+  user: Ref<IUser>;
+  targetModel: string;
+  target: Ref<IPage>;
+  status: string;
+  createdAt: Date;
 
-  isSubscribing(): boolean
-  isUnsubscribing(): boolean
+  isSubscribing(): boolean;
+  isUnsubscribing(): boolean;
 }

+ 3 - 3
packages/core/src/interfaces/tag.ts

@@ -1,4 +1,4 @@
 export type ITag<ID = string> = {
-  _id: ID
-  name: string,
-}
+  _id: ID;
+  name: string;
+};

+ 33 - 33
packages/core/src/interfaces/user.ts

@@ -4,40 +4,40 @@ import type { HasObjectId } from './has-object-id';
 import type { Lang } from './lang';
 
 export type IUser = {
-  name: string,
-  username: string,
-  email: string,
-  password: string,
-  image?: string, // for backward conpatibility
-  imageAttachment?: Ref<IAttachment>,
-  imageUrlCached: string,
-  isGravatarEnabled: boolean,
-  admin: boolean,
-  readOnly: boolean,
-  apiToken?: string,
-  isEmailPublished: boolean,
-  isInvitationEmailSended: boolean,
-  lang: Lang,
-  slackMemberId?: string,
-  createdAt: Date,
-  lastLoginAt?: Date,
-  introduction: string,
-  status: IUserStatus,
-  isQuestionnaireEnabled: boolean,
-}
+  name: string;
+  username: string;
+  email: string;
+  password: string;
+  image?: string; // for backward conpatibility
+  imageAttachment?: Ref<IAttachment>;
+  imageUrlCached: string;
+  isGravatarEnabled: boolean;
+  admin: boolean;
+  readOnly: boolean;
+  apiToken?: string;
+  isEmailPublished: boolean;
+  isInvitationEmailSended: boolean;
+  lang: Lang;
+  slackMemberId?: string;
+  createdAt: Date;
+  lastLoginAt?: Date;
+  introduction: string;
+  status: IUserStatus;
+  isQuestionnaireEnabled: boolean;
+};
 
 export type IUserGroupRelation = {
-  relatedGroup: Ref<IUserGroup>,
-  relatedUser: Ref<IUser>,
-  createdAt: Date,
-}
+  relatedGroup: Ref<IUserGroup>;
+  relatedUser: Ref<IUser>;
+  createdAt: Date;
+};
 
 export type IUserGroup = {
   name: string;
   createdAt: Date;
   description: string;
   parent: Ref<IUserGroup> | null;
-}
+};
 
 export const USER_STATUS = {
   REGISTERED: 1,
@@ -46,16 +46,16 @@ export const USER_STATUS = {
   DELETED: 4,
   INVITED: 5,
 } as const;
-export type IUserStatus = typeof USER_STATUS[keyof typeof USER_STATUS]
+export type IUserStatus = (typeof USER_STATUS)[keyof typeof USER_STATUS];
 
 export type IUserHasId = IUser & HasObjectId;
 export type IUserGroupHasId = IUserGroup & HasObjectId;
 export type IUserGroupRelationHasId = IUserGroupRelation & HasObjectId;
 
 export type IAdminExternalAccount<P> = {
-  _id: string,
-  providerType: P,
-  accountId: string,
-  user: IUser,
-  createdAt: Date,
-}
+  _id: string;
+  providerType: P;
+  accountId: string;
+  user: IUser;
+  createdAt: Date;
+};

+ 7 - 7
packages/core/src/interfaces/vite.ts

@@ -1,10 +1,10 @@
 export type ViteManifestValue = {
-  file: string,
-  src: string,
-  isEntry?: boolean,
-  css?: string[],
-}
+  file: string;
+  src: string;
+  isEntry?: boolean;
+  css?: string[];
+};
 
 export type ViteManifest = {
-  [key: string]: ViteManifestValue,
-}
+  [key: string]: ViteManifestValue;
+};

+ 3 - 3
packages/core/src/remark-plugins/interfaces/option-parser.ts

@@ -1,4 +1,4 @@
 export type ParseRangeResult = {
-  start: number,
-  end: number,
-}
+  start: number;
+  end: number;
+};

+ 14 - 13
packages/core/src/remark-plugins/util/option-parser.spec.ts

@@ -1,26 +1,27 @@
 import { OptionParser } from './option-parser';
 
 describe('option-parser', () => {
-
   test.concurrent.each`
     arg
     ${'aaa'}
     ${'5++2'}
     ${'5:+2'}
-  `('.parseRange(\'$arg\') returns null', ({ arg }) => {
+  `(".parseRange('$arg') returns null", ({ arg }) => {
     expect(OptionParser.parseRange(arg)).toBeNull();
   });
 
   test.concurrent.each`
-    arg       | start | end
-    ${'1'}    | ${1} | ${1}
-    ${'2:1'}  | ${2} | ${1}
-    ${'2:'}   | ${2} | ${-1}
-    ${'10:-3'}   | ${10} | ${-3}
-    ${'5+2'}   | ${5} | ${7}
-    ${'5+'}   | ${5} | ${5}
-  `('.parseRange(\'$arg\') returns { start: $start, end : $end }', ({ arg, start, end }) => {
-    expect(OptionParser.parseRange(arg)).toEqual({ start, end });
-  });
-
+    arg        | start | end
+    ${'1'}     | ${1}  | ${1}
+    ${'2:1'}   | ${2}  | ${1}
+    ${'2:'}    | ${2}  | ${-1}
+    ${'10:-3'} | ${10} | ${-3}
+    ${'5+2'}   | ${5}  | ${7}
+    ${'5+'}    | ${5}  | ${5}
+  `(
+    ".parseRange('$arg') returns { start: $start, end : $end }",
+    ({ arg, start, end }) => {
+      expect(OptionParser.parseRange(arg)).toEqual({ start, end });
+    },
+  );
 });

+ 1 - 4
packages/core/src/remark-plugins/util/option-parser.ts

@@ -4,7 +4,6 @@ import type { ParseRangeResult } from '../interfaces/option-parser';
  * Options parser for custom tag
  */
 export class OptionParser {
-
   /**
    * Parse range expression
    *
@@ -46,8 +45,7 @@ export class OptionParser {
       // determine end
       if (operator === ':') {
         end = +match[4] || -1; // set last(-1) if undefined
-      }
-      else if (operator === '+') {
+      } else if (operator === '+') {
         end = +match[4] || 0; // plus zero if undefined
         end += start;
       }
@@ -60,5 +58,4 @@ export class OptionParser {
 
     return { start, end };
   }
-
 }

+ 23 - 10
packages/core/src/swr/use-swr-static.ts

@@ -1,18 +1,31 @@
 import {
-  Key, SWRConfiguration, SWRResponse, useSWRConfig,
+  type Key,
+  type SWRConfiguration,
+  type SWRResponse,
+  useSWRConfig,
 } from 'swr';
 import useSWRImmutable from 'swr/immutable';
 
-
 export function useSWRStatic<Data, Error>(key: Key): SWRResponse<Data, Error>;
-export function useSWRStatic<Data, Error>(key: Key, data: Data | undefined): SWRResponse<Data, Error>;
-export function useSWRStatic<Data, Error>(key: Key, data: Data | undefined,
-  configuration: SWRConfiguration<Data, Error> | undefined): SWRResponse<Data, Error>;
+export function useSWRStatic<Data, Error>(
+  key: Key,
+  data: Data | undefined,
+): SWRResponse<Data, Error>;
+export function useSWRStatic<Data, Error>(
+  key: Key,
+  data: Data | undefined,
+  configuration: SWRConfiguration<Data, Error> | undefined,
+): SWRResponse<Data, Error>;
 
 export function useSWRStatic<Data, Error>(
-    ...args: readonly [Key]
+  ...args:
+    | readonly [Key]
     | readonly [Key, Data | undefined]
-    | readonly [Key, Data | undefined, SWRConfiguration<Data, Error> | undefined]
+    | readonly [
+        Key,
+        Data | undefined,
+        SWRConfiguration<Data, Error> | undefined,
+      ]
 ): SWRResponse<Data, Error> {
   const [key, data, configuration] = args;
 
@@ -23,9 +36,9 @@ export function useSWRStatic<Data, Error>(
   const { cache } = useSWRConfig();
   const swrResponse = useSWRImmutable(key, null, {
     ...configuration,
-    fallbackData: configuration?.fallbackData ?? (
-      key != null ? cache.get(key?.toString())?.data : undefined
-    ),
+    fallbackData:
+      configuration?.fallbackData ??
+      (key != null ? cache.get(key?.toString())?.data : undefined),
   });
 
   // update data

+ 4 - 1
packages/core/src/swr/with-utils.ts

@@ -2,6 +2,9 @@ import type { SWRResponse } from 'swr';
 
 export type SWRResponseWithUtils<U, D = any, E = any> = SWRResponse<D, E> & U;
 
-export const withUtils = <U, D = any, E = any>(response: SWRResponse<D, E>, utils: U): SWRResponseWithUtils<U, D, E> => {
+export const withUtils = <U, D = any, E = any>(
+  response: SWRResponse<D, E>,
+  utils: U,
+): SWRResponseWithUtils<U, D, E> => {
   return Object.assign(response, utils);
 };

+ 2 - 6
packages/core/tsconfig.json

@@ -6,11 +6,7 @@
     "paths": {
       "~/*": ["./src/*"]
     },
-    "types": [
-      "vitest/globals"
-    ]
+    "types": ["vitest/globals"]
   },
-  "include": [
-    "src", "test"
-  ]
+  "include": ["src", "test"]
 }

+ 1 - 3
packages/core/vitest.config.ts

@@ -2,9 +2,7 @@ import tsconfigPaths from 'vite-tsconfig-paths';
 import { defineConfig } from 'vitest/config';
 
 export default defineConfig({
-  plugins: [
-    tsconfigPaths(),
-  ],
+  plugins: [tsconfigPaths()],
   test: {
     environment: 'node',
     clearMocks: true,