Skip to content

Commit

Permalink
Improve client-side graphql scalar types (stashapp#4511)
Browse files Browse the repository at this point in the history
* Add types to graphql scalars
* Upgrade dependencies
* Override UI config type
* Remove all IUIConfig casts
* Add tableColumns to IUIConfig
* Add BoolMap type, set strictScalars
* Add PluginConfigMap
* Replace any with unknown
* Add SavedObjectFilter and SavedUIOptions
* Remove unused items from CriterionType
  • Loading branch information
DingDongSoLong4 authored and dogwithakeyboard committed Feb 18, 2024
1 parent f8098e9 commit 11059d3
Show file tree
Hide file tree
Showing 121 changed files with 890 additions and 1,065 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

# GraphQL generated output
pkg/models/generated_*.go
ui/v2.5/src/core/generated-*.tsx
ui/v2.5/src/core/generated-graphql.ts

####
# Jetbrains
Expand Down
2 changes: 2 additions & 0 deletions gqlgen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ models:
model: github.com/stashapp/stash/internal/api.Timestamp
BoolMap:
model: github.com/stashapp/stash/internal/api.BoolMap
PluginConfigMap:
model: github.com/stashapp/stash/internal/api.PluginConfigMap
# define to force resolvers
Image:
model: github.com/stashapp/stash/pkg/models.Image
Expand Down
2 changes: 1 addition & 1 deletion graphql/schema/types/config.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ type ConfigResult {
scraping: ConfigScrapingResult!
defaults: ConfigDefaultSettingsResult!
ui: Map!
plugins(include: [String!]): Map!
plugins(include: [ID!]): PluginConfigMap!
}

"Directory structure of a path"
Expand Down
3 changes: 0 additions & 3 deletions graphql/schema/types/logging.graphql
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
"Log entries"
scalar Time

enum LogLevel {
Trace
Debug
Expand Down
2 changes: 0 additions & 2 deletions graphql/schema/types/metadata.graphql
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
scalar Upload

input GenerateMetadataInput {
covers: Boolean
sprites: Boolean
Expand Down
13 changes: 11 additions & 2 deletions graphql/schema/types/scalars.graphql
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
"An RFC3339 timestamp"
scalar Time

"""
Timestamp is a point in time. It is always output as RFC3339-compatible time points.
It can be input as a RFC3339 string, or as "<4h" for "4 hours in the past" or ">5m"
for "5 minutes in the future"
"""
scalar Timestamp

# generic JSON object
"A String -> Any map"
scalar Map

# string, boolean map
"A String -> Boolean map"
scalar BoolMap

"A plugin ID -> Map (String -> Any map) map"
scalar PluginConfigMap

scalar Any

scalar Int64

"A multipart file upload"
scalar Upload
37 changes: 37 additions & 0 deletions internal/api/plugin_map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package api

import (
"encoding/json"
"fmt"
"io"

"github.com/99designs/gqlgen/graphql"
)

func MarshalPluginConfigMap(val map[string]map[string]interface{}) graphql.Marshaler {
return graphql.WriterFunc(func(w io.Writer) {
err := json.NewEncoder(w).Encode(val)
if err != nil {
panic(err)
}
})
}

func UnmarshalPluginConfigMap(v interface{}) (map[string]map[string]interface{}, error) {
m, ok := v.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("%T is not a plugin config map", v)
}

result := make(map[string]map[string]interface{})
for k, v := range m {
val, ok := v.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("key %s (%T) is not a map", k, v)
}

result[k] = val
}

return result, nil
}
4 changes: 2 additions & 2 deletions internal/api/resolver_model_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import (
"github.com/stashapp/stash/internal/manager/config"
)

func (r *configResultResolver) Plugins(ctx context.Context, obj *ConfigResult, include []string) (map[string]interface{}, error) {
func (r *configResultResolver) Plugins(ctx context.Context, obj *ConfigResult, include []string) (map[string]map[string]interface{}, error) {
if len(include) == 0 {
ret := config.GetInstance().GetAllPluginConfiguration()
return ret, nil
}

ret := make(map[string]interface{})
ret := make(map[string]map[string]interface{})

for _, plugin := range include {
c := config.GetInstance().GetPluginConfiguration(plugin)
Expand Down
4 changes: 2 additions & 2 deletions internal/manager/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,11 +735,11 @@ func (i *Config) GetPluginsPath() string {
return i.getString(PluginsPath)
}

func (i *Config) GetAllPluginConfiguration() map[string]interface{} {
func (i *Config) GetAllPluginConfiguration() map[string]map[string]interface{} {
i.RLock()
defer i.RUnlock()

ret := make(map[string]interface{})
ret := make(map[string]map[string]interface{})

sub := i.viper(PluginsSetting).GetStringMap(PluginsSetting)
if sub == nil {
Expand Down
2 changes: 1 addition & 1 deletion ui/v2.5/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"version": "detect"
}
},
"ignorePatterns": ["node_modules/", "src/core/generated-graphql.tsx"],
"ignorePatterns": ["node_modules/", "src/core/generated-graphql.ts"],
"rules": {
"@typescript-eslint/lines-between-class-members": "off",
"@typescript-eslint/naming-convention": [
Expand Down
2 changes: 1 addition & 1 deletion ui/v2.5/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# generated
src/core/generated-*.tsx
src/core/generated-graphql.ts

# dependencies
/node_modules
Expand Down
2 changes: 1 addition & 1 deletion ui/v2.5/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ src/locales/**/*.json
/build

# generated
src/core/generated-graphql.tsx
src/core/generated-graphql.ts
42 changes: 42 additions & 0 deletions ui/v2.5/codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
schema: [
"../../graphql/schema/**/*.graphql",
"graphql/client-schema.graphql",
],
config: {
// makes conflicting fields override rather than error
onFieldTypeConflict: (_existing: unknown, other: unknown) => other,
},
documents: "graphql/**/*.graphql",
generates: {
"src/core/generated-graphql.ts": {
plugins: [
"time",
"typescript",
"typescript-operations",
"typescript-react-apollo",
],
config: {
strictScalars: true,
scalars: {
Time: "string",
Timestamp: "string",
Map: "{ [key: string]: unknown }",
BoolMap: "{ [key: string]: boolean }",
PluginConfigMap: "{ [id: string]: { [key: string]: unknown } }",
Any: "unknown",
Int64: "number",
Upload: "File",
UIConfig: "src/core/config#IUIConfig",
SavedObjectFilter: "src/models/list-filter/types#SavedObjectFilter",
SavedUIOptions: "src/models/list-filter/types#SavedUIOptions",
},
withRefetchFn: true,
},
},
},
};

export default config;
12 changes: 0 additions & 12 deletions ui/v2.5/codegen.yml

This file was deleted.

26 changes: 26 additions & 0 deletions ui/v2.5/graphql/client-schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
scalar UIConfig
scalar SavedObjectFilter
scalar SavedUIOptions

extend type ConfigResult {
ui: UIConfig!
}

extend type SavedFilter {
object_filter: SavedObjectFilter
ui_options: SavedUIOptions
}

extend input SaveFilterInput {
object_filter: SavedObjectFilter
ui_options: SavedUIOptions
}

extend input SetDefaultFilterInput {
object_filter: SavedObjectFilter
ui_options: SavedUIOptions
}

extend type Mutation {
configureUI(input: UIConfig!): UIConfig!
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ mutation ConfigureDefaults($input: ConfigDefaultSettingsInput!) {
}
}

mutation ConfigureUI($input: Map!) {
mutation ConfigureUI($input: UIConfig!) {
configureUI(input: $input)
}

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 10 additions & 10 deletions ui/v2.5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
"check": "tsc --noEmit",
"format": "prettier --write . ../../graphql",
"format-check": "prettier --check . ../../graphql",
"gqlgen": "gql-gen --config codegen.yml",
"gqlgen": "gql-gen --config codegen.ts",
"extract": "NODE_ENV=development extract-messages -l=en,de -o src/locale -d en --flat false 'src/**/!(*.test).tsx'"
},
"dependencies": {
"@ant-design/react-slick": "^1.0.0",
"@apollo/client": "^3.7.17",
"@apollo/client": "^3.8.10",
"@formatjs/intl-getcanonicallocales": "^2.0.5",
"@formatjs/intl-locale": "^3.0.11",
"@formatjs/intl-numberformat": "^8.3.3",
Expand All @@ -31,7 +31,7 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@silvermine/videojs-airplay": "^1.2.0",
"@silvermine/videojs-chromecast": "^1.4.1",
"apollo-upload-client": "^17.0.0",
"apollo-upload-client": "^18.0.1",
"base64-blob": "^1.4.1",
"bootstrap": "^4.6.2",
"classnames": "^2.3.2",
Expand All @@ -40,7 +40,7 @@
"formik": "^2.4.5",
"graphql": "^16.8.1",
"graphql-tag": "^2.12.6",
"graphql-ws": "^5.11.3",
"graphql-ws": "^5.14.3",
"i18n-iso-countries": "^7.5.0",
"intersection-observer": "^0.12.2",
"localforage": "^1.10.0",
Expand Down Expand Up @@ -78,12 +78,12 @@
},
"devDependencies": {
"@babel/core": "^7.20.12",
"@graphql-codegen/cli": "^3.0.0",
"@graphql-codegen/time": "^4.0.0",
"@graphql-codegen/typescript": "^3.0.0",
"@graphql-codegen/typescript-operations": "^3.0.0",
"@graphql-codegen/typescript-react-apollo": "^3.3.7",
"@types/apollo-upload-client": "^17.0.2",
"@graphql-codegen/cli": "^5.0.0",
"@graphql-codegen/time": "^5.0.0",
"@graphql-codegen/typescript": "^4.0.1",
"@graphql-codegen/typescript-operations": "^4.0.1",
"@graphql-codegen/typescript-react-apollo": "^4.1.0",
"@types/apollo-upload-client": "^18.0.0",
"@types/lodash-es": "^4.17.6",
"@types/mousetrap": "^1.6.11",
"@types/node": "^18.13.0",
Expand Down
4 changes: 1 addition & 3 deletions ui/v2.5/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import { ConfigurationProvider } from "./hooks/Config";
import { ManualProvider } from "./components/Help/context";
import { InteractiveProvider } from "./hooks/Interactive/context";
import { ReleaseNotesDialog } from "./components/Dialogs/ReleaseNotesDialog";
import { IUIConfig } from "./core/config";
import { releaseNotes } from "./docs/en/ReleaseNotes";
import { getPlatformURL } from "./core/createClient";
import { lazyComponent } from "./utils/lazyComponent";
Expand Down Expand Up @@ -324,8 +323,7 @@ export const App: React.FC = () => {
return;
}

const lastNoteSeen = (config.data?.configuration.ui as IUIConfig)
?.lastNoteSeen;
const lastNoteSeen = config.data?.configuration.ui.lastNoteSeen;
const notes = releaseNotes.filter((n) => {
return !lastNoteSeen || n.date > lastNoteSeen;
});
Expand Down
3 changes: 1 addition & 2 deletions ui/v2.5/src/components/FrontPage/FrontPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
FrontPageContent,
generateDefaultFrontPageContent,
getFrontPageContent,
IUIConfig,
} from "src/core/config";
import { useScrollToTopOnMount } from "src/hooks/scrollToTop";

Expand Down Expand Up @@ -59,7 +58,7 @@ const FrontPage: React.FC = () => {
return <FrontPageConfig onClose={(content) => onUpdateConfig(content)} />;
}

const ui = (configuration?.ui ?? {}) as IUIConfig;
const ui = configuration?.ui ?? {};

if (!ui.frontPageContent) {
const defaultContent = generateDefaultFrontPageContent(intl);
Expand Down
3 changes: 1 addition & 2 deletions ui/v2.5/src/components/FrontPage/FrontPageConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Button, Form, Modal } from "react-bootstrap";
import * as GQL from "src/core/generated-graphql";
import { ConfigurationContext } from "src/hooks/Config";
import {
IUIConfig,
ISavedFilterRow,
ICustomFilter,
FrontPageContent,
Expand Down Expand Up @@ -283,7 +282,7 @@ export const FrontPageConfig: React.FC<IFrontPageConfigProps> = ({
}) => {
const { configuration, loading } = React.useContext(ConfigurationContext);

const ui = configuration?.ui as IUIConfig;
const ui = configuration?.ui;

const { data: allFilters, loading: loading2 } = useFindSavedFilters();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export const GalleryEditPanel: React.FC<IProps> = ({

useRatingKeybinds(
isVisible,
stashConfig?.ui?.ratingSystemOptions?.type,
stashConfig?.ui.ratingSystemOptions?.type,
setRating
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export const ImageEditPanel: React.FC<IProps> = ({

useRatingKeybinds(
true,
configuration?.ui?.ratingSystemOptions?.type,
configuration?.ui.ratingSystemOptions?.type,
setRating
);

Expand Down
3 changes: 1 addition & 2 deletions ui/v2.5/src/components/Images/ImageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import { ExportDialog } from "../Shared/ExportDialog";
import { objectTitle } from "src/core/files";
import TextUtils from "src/utils/text";
import { ConfigurationContext } from "src/hooks/Config";
import { IUIConfig } from "src/core/config";
import { useContainerDimensions } from "../Shared/GridCard";

interface IImageWallProps {
Expand All @@ -45,7 +44,7 @@ interface IImageWallProps {

const ImageWall: React.FC<IImageWallProps> = ({ images, handleImageOpen }) => {
const { configuration } = useContext(ConfigurationContext);
const uiConfig = configuration?.ui as IUIConfig | undefined;
const uiConfig = configuration?.ui;

let photos: {
src: string;
Expand Down
Loading

0 comments on commit 11059d3

Please sign in to comment.