Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,9 @@ jobs:
retention-days: 7
if-no-files-found: error

- name: Setup Docker Registry Mirrors
uses: ./.github/actions/setup-docker-registry-mirrors

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4

Expand Down Expand Up @@ -1175,6 +1178,9 @@ jobs:
- name: Extract public app artifacts
run: tar -xzf e2e-public-apps.tar.gz

- name: Setup Docker Registry Mirrors
uses: ./.github/actions/setup-docker-registry-mirrors

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
with:
Expand Down Expand Up @@ -1275,6 +1281,9 @@ jobs:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Setup Docker Registry Mirrors
uses: ./.github/actions/setup-docker-registry-mirrors

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4

Expand All @@ -1298,9 +1307,6 @@ jobs:
image-tags: ${{ needs.job_build_e2e_image.outputs.image-tags }}
artifact-name: docker-image-e2e

- name: Setup Docker Registry Mirrors
uses: ./.github/actions/setup-docker-registry-mirrors

- uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6
with:
Expand Down
2 changes: 1 addition & 1 deletion .secretlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
{
"name": "credential in URL query string",
"patterns": [
"/[?&](?:token|api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|secret|password)=(?<CREDENTIAL>(?!p\\.)[^&\\s\"'<>]{16,})/i"
"/[?&](?:token|api[_-]?key|access[_-]?token|auth[_-]?token|client[_-]?secret|secret|password)=(?<CREDENTIAL>(?!p\\.|\\$\\{)[^&\\s\"'<>]{16,})/i"
]
},
{
Expand Down
4 changes: 1 addition & 3 deletions apps/activitypub/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryghost/activitypub",
"version": "3.1.14",
"version": "3.1.16",
"license": "MIT",
"repository": {
"type": "git",
Expand Down Expand Up @@ -39,13 +39,11 @@
"devDependencies": {
"@playwright/test": "1.59.1",
"@testing-library/react": "14.3.1",
"@types/dompurify": "3.2.0",
"@types/jest": "29.5.14",
"@types/react": "18.3.28",
"@types/react-dom": "18.3.7",
"jest": "29.7.0",
"tailwindcss": "^4.2.2",
"ts-jest": "29.4.9",
"vite": "5.4.21",
"vitest": "1.6.1"
},
Expand Down
2 changes: 0 additions & 2 deletions apps/admin-x-design-system/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"@codemirror/lang-html": "6.4.11",
"@codemirror/state": "6.6.0",
"@dnd-kit/utilities": "^3.2.2",
"@radix-ui/react-tooltip": "1.2.8",
"@storybook/addon-docs": "10.3.5",
"@storybook/addon-links": "10.3.5",
"@storybook/react-vite": "10.3.5",
Expand All @@ -54,7 +53,6 @@
"postcss-import": "16.1.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"rollup-plugin-node-builtins": "2.1.2",
"sinon": "18.0.1",
"storybook": "10.3.5",
"tailwindcss": "4.2.1",
Expand Down
1 change: 0 additions & 1 deletion apps/admin-x-framework/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@
"glob": "^10.5.0",
"jsdom": "28.1.0",
"msw": "2.12.14",
"sinon": "18.0.1",
"typescript": "5.9.3",
"vite": "5.4.21",
"vite-plugin-css-injected-by-js": "3.5.2",
Expand Down
1 change: 0 additions & 1 deletion apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"@tryghost/posts": "workspace:*",
"@tryghost/shade": "workspace:*",
"@tryghost/stats": "workspace:*",
"lodash": "4.18.1",
"mingo": "2.5.3",
"react": "18.3.1",
"react-dom": "18.3.1",
Expand Down
3 changes: 1 addition & 2 deletions apps/announcement-bar/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryghost/announcement-bar",
"version": "1.1.18",
"version": "1.1.19",
"license": "MIT",
"repository": "https://github.com/TryGhost/Ghost",
"author": "Ghost Foundation",
Expand All @@ -14,7 +14,6 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"@tryghost/content-api": "1.12.6",
"react": "17.0.2",
"react-dom": "17.0.2"
},
Expand Down
3 changes: 1 addition & 2 deletions apps/comments-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryghost/comments-ui",
"version": "1.4.10",
"version": "1.4.11",
"license": "MIT",
"repository": "https://github.com/TryGhost/Ghost",
"author": "Ghost Foundation",
Expand Down Expand Up @@ -64,7 +64,6 @@
"@playwright/test": "1.59.1",
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "12.1.5",
"@testing-library/user-event": "14.6.1",
"@tryghost/i18n": "workspace:*",
"@vitejs/plugin-react": "4.7.0",
"@vitest/coverage-v8": "0.34.6",
Expand Down
3 changes: 1 addition & 2 deletions apps/portal/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tryghost/portal",
"version": "2.68.29",
"version": "2.68.30",
"license": "MIT",
"repository": "https://github.com/TryGhost/Ghost",
"author": "Ghost Foundation",
Expand Down Expand Up @@ -109,7 +109,6 @@
]
},
"devDependencies": {
"@babel/eslint-parser": "7.28.4",
"@doist/react-interpolate": "2.2.1",
"@sentry/react": "7.120.4",
"@testing-library/jest-dom": "6.9.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/posts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@
"@tryghost/nql-lang": "0.6.4",
"@tryghost/shade": "workspace:*",
"i18n-iso-countries": "7.14.0",
"moment": "2.24.0",
"moment-timezone": "0.5.45",
"papaparse": "5.5.3",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-router": "7.14.0",
"sonner": "2.0.7",
"temporal-polyfill": "0.3.0",
"use-debounce": "10.1.1",
"zod": "4.1.12"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {ValueSource, ValueSourceParams, ValueSourceState} from '@tryghost/shade/patterns';
import {FilterOption, ValueSource, ValueSourceParams, ValueSourceState} from '@tryghost/shade/patterns';
import {ValueSourceHook, ValueSourceHookOptions} from './create-remote-value-source';
import {mergeFilterOptions} from './utils';
import {useCallback, useMemo} from 'react';

export function createCombinedValueSource<T = string>(
useFirstSource: ValueSourceHook<T>,
useSecondSource: ValueSourceHook<T>
useSecondSource: ValueSourceHook<T>,
getMissingSelectedOption?: (selectedValue: T) => FilterOption<T>
): ValueSourceHook<T> {
return function useCombinedValueSource(options?: ValueSourceHookOptions): ValueSource<T> {
const firstSource = useFirstSource(options);
Expand All @@ -14,9 +15,19 @@ export function createCombinedValueSource<T = string>(
const useOptions = useCallback(({query, selectedValues}: ValueSourceParams<T>): ValueSourceState<T> => {
const firstState = firstSource.useOptions({query, selectedValues});
const secondState = secondSource.useOptions({query, selectedValues});
const mergedOptions = mergeFilterOptions(firstState.options, secondState.options);
const fallbackOptions = getMissingSelectedOption ? selectedValues.flatMap((selectedValue) => {
const hasMatch = mergedOptions.some(option => option.value === selectedValue);

if (hasMatch) {
return [];
}

return [getMissingSelectedOption(selectedValue)];
}) : [];

return {
options: mergeFilterOptions(firstState.options, secondState.options),
options: mergeFilterOptions(mergedOptions, fallbackOptions),
isInitialLoad: firstState.options.length === 0 &&
secondState.options.length === 0 &&
(firstState.isInitialLoad || secondState.isInitialLoad),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface CreateGhostBrowseValueSourceConfig<Item, Data> {
debounceMs?: number;
selectItems: (data: Data | undefined) => Item[] | undefined;
toOption: (item: Item) => FilterOption<string>;
getMissingSelectedOption?: (selectedValue: string) => FilterOption<string>;
useQuery: (
options: {enabled: boolean; searchParams: Record<string, string>}
) => InfiniteBrowseResult<Data>;
Expand Down Expand Up @@ -53,6 +54,7 @@ export function createGhostBrowseValueSource<Item, Data extends GhostBrowseRespo
debounceMs,
selectItems,
toOption,
getMissingSelectedOption,
useQuery
}: CreateGhostBrowseValueSourceConfig<Item, Data>) {
return createRemoteValueSource<Item>({
Expand Down Expand Up @@ -93,6 +95,7 @@ export function createGhostBrowseValueSource<Item, Data extends GhostBrowseRespo
};
},
toOption,
getMissingSelectedOption,
debounceMs
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ interface RemoteValueSourceConfig<Item, T = string> {
useBrowse: (query: string, options: ValueSourceHookOptions) => BrowseState<Item>;
useHydrate?: (selectedValues: T[], options: ValueSourceHookOptions) => HydrateState<Item>;
toOption: (item: Item) => FilterOption<T>;
getMissingSelectedOption?: (selectedValue: T) => FilterOption<T>;
debounceMs?: number;
}

Expand All @@ -52,6 +53,26 @@ export type RemoteValueSource<T = string, Item = unknown> = ValueSource<T> & {

export type RemoteValueSourceHook<T = string, Item = unknown> = (options?: ValueSourceHookOptions) => RemoteValueSource<T, Item>;

function buildFallbackOptions<T>(
selectedValues: T[],
mergedOptions: FilterOption<T>[],
getMissingSelectedOption?: (selectedValue: T) => FilterOption<T>
): FilterOption<T>[] {
if (!getMissingSelectedOption) {
return [];
}

return selectedValues.flatMap((selectedValue) => {
const hasMatch = mergedOptions.some(option => option.value === selectedValue);

if (hasMatch) {
return [];
}

return [getMissingSelectedOption(selectedValue)];
});
}

export function createRemoteValueSource<Item, T = string>(
config: RemoteValueSourceConfig<Item, T>
): RemoteValueSourceHook<T, Item> {
Expand Down Expand Up @@ -88,6 +109,13 @@ export function createRemoteValueSource<Item, T = string>(
const mergedOptions = useMemo(() => {
return mergeFilterOptions(hydratedOptions, visibleOptions);
}, [hydratedOptions, visibleOptions]);
const fallbackOptions = useMemo(() => {
return buildFallbackOptions(
selectedValues,
mergedOptions,
config.getMissingSelectedOption
);
}, [mergedOptions, selectedValues]);

if (!enabled) {
return {
Expand All @@ -101,7 +129,7 @@ export function createRemoteValueSource<Item, T = string>(
}

return {
options: mergedOptions,
options: mergeFilterOptions(fallbackOptions, mergedOptions),
isInitialLoad: browse.isLoading && mergedOptions.length === 0,
isSearching: !browse.isLoading && browse.isRefreshing && !browse.isLoadingMore,
isLoadingMore: browse.isLoadingMore,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const useRemoteMemberValueSource = createGhostBrowseValueSource<Member, MembersI
order: 'created_at DESC',
...(query ? {search: query} : {})
}),
getMissingSelectedOption: value => ({
value,
label: `ID: ${value}`
}),
selectItems: data => data?.members,
useQuery: ({enabled, searchParams}) => {
return useBrowseMembersInfinite({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ const usePublishedPageValueSource = createGhostBrowseValueSource<Page, PagesResp

const useCombinedPostResourceValueSource = createCombinedValueSource(
usePublishedPostValueSource,
usePublishedPageValueSource
usePublishedPageValueSource,
value => ({
value,
label: `ID: ${value}`
})
);

export function usePostResourceValueSource(): ValueSource<string> {
Expand Down
Loading
Loading