polen 0.11.0-next.17 → 0.11.0-next.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/builder/ssg/generate.d.ts.map +1 -1
- package/build/api/builder/ssg/generate.js +5 -5
- package/build/api/builder/ssg/generate.js.map +1 -1
- package/build/api/builder/ssg/page-generator.worker.js +13 -3
- package/build/api/builder/ssg/page-generator.worker.js.map +1 -1
- package/build/api/config/input.d.ts +88 -3
- package/build/api/config/input.d.ts.map +1 -1
- package/build/api/config/normalized.d.ts +92 -7
- package/build/api/config/normalized.d.ts.map +1 -1
- package/build/api/config/normalized.js +11 -3
- package/build/api/config/normalized.js.map +1 -1
- package/build/api/config-template/template.js +2 -2
- package/build/api/config-template/template.js.map +1 -1
- package/build/api/content/sidebar.d.ts.map +1 -1
- package/build/api/content/sidebar.js +2 -1
- package/build/api/content/sidebar.js.map +1 -1
- package/build/api/errors.d.ts +278 -0
- package/build/api/errors.d.ts.map +1 -0
- package/build/api/errors.js +153 -0
- package/build/api/errors.js.map +1 -0
- package/build/api/examples/config.d.ts +366 -3
- package/build/api/examples/config.d.ts.map +1 -1
- package/build/api/examples/config.js +25 -3
- package/build/api/examples/config.js.map +1 -1
- package/build/api/examples/diagnostic/diagnostic.d.ts +1 -1
- package/build/api/examples/diagnostic/validation-error.d.ts +3 -2
- package/build/api/examples/diagnostic/validation-error.d.ts.map +1 -1
- package/build/api/examples/diagnostic/validation-error.js +9 -3
- package/build/api/examples/diagnostic/validation-error.js.map +1 -1
- package/build/api/examples/diagnostic/validator.d.ts.map +1 -1
- package/build/api/examples/diagnostic/validator.js +115 -68
- package/build/api/examples/diagnostic/validator.js.map +1 -1
- package/build/api/examples/filter.d.ts.map +1 -1
- package/build/api/examples/filter.js +9 -6
- package/build/api/examples/filter.js.map +1 -1
- package/build/api/examples/scanner.d.ts.map +1 -1
- package/build/api/examples/scanner.js +89 -103
- package/build/api/examples/scanner.js.map +1 -1
- package/build/api/examples/type-usage-indexer.d.ts.map +1 -1
- package/build/api/examples/type-usage-indexer.js +17 -30
- package/build/api/examples/type-usage-indexer.js.map +1 -1
- package/build/api/iso/schema/routing.d.ts.map +1 -1
- package/build/api/iso/schema/routing.js +8 -8
- package/build/api/iso/schema/routing.js.map +1 -1
- package/build/api/iso/schema/validation.d.ts.map +1 -1
- package/build/api/iso/schema/validation.js +3 -2
- package/build/api/iso/schema/validation.js.map +1 -1
- package/build/api/schema/input-source/$$.d.ts +1 -0
- package/build/api/schema/input-source/$$.d.ts.map +1 -1
- package/build/api/schema/input-source/$$.js +1 -0
- package/build/api/schema/input-source/$$.js.map +1 -1
- package/build/api/schema/input-source/errors.d.ts +36 -0
- package/build/api/schema/input-source/errors.d.ts.map +1 -0
- package/build/api/schema/input-source/errors.js +17 -0
- package/build/api/schema/input-source/errors.js.map +1 -0
- package/build/api/schema/input-source/input-source.d.ts +1 -7
- package/build/api/schema/input-source/input-source.d.ts.map +1 -1
- package/build/api/schema/input-source/input-source.js +0 -6
- package/build/api/schema/input-source/input-source.js.map +1 -1
- package/build/api/schema/input-sources/directory.d.ts.map +1 -1
- package/build/api/schema/input-sources/directory.js +19 -6
- package/build/api/schema/input-sources/directory.js.map +1 -1
- package/build/api/schema/input-sources/file.d.ts.map +1 -1
- package/build/api/schema/input-sources/file.js +15 -4
- package/build/api/schema/input-sources/file.js.map +1 -1
- package/build/api/schema/input-sources/introspection-file.d.ts.map +1 -1
- package/build/api/schema/input-sources/introspection-file.js +28 -6
- package/build/api/schema/input-sources/introspection-file.js.map +1 -1
- package/build/api/schema/input-sources/introspection.d.ts.map +1 -1
- package/build/api/schema/input-sources/introspection.js +35 -7
- package/build/api/schema/input-sources/introspection.js.map +1 -1
- package/build/api/schema/input-sources/memory.d.ts.map +1 -1
- package/build/api/schema/input-sources/memory.js +15 -3
- package/build/api/schema/input-sources/memory.js.map +1 -1
- package/build/api/schema/input-sources/versioned-directory.d.ts.map +1 -1
- package/build/api/schema/input-sources/versioned-directory.js +23 -7
- package/build/api/schema/input-sources/versioned-directory.js.map +1 -1
- package/build/api/schema/load.d.ts +1 -1
- package/build/api/schema/load.d.ts.map +1 -1
- package/build/api/schema/load.js.map +1 -1
- package/build/cli/commands/hero-image.d.ts +1 -2
- package/build/cli/commands/hero-image.d.ts.map +1 -1
- package/build/cli/index.d.ts +1 -1
- package/build/lib/catalog/catalog.d.ts +43 -3
- package/build/lib/catalog/catalog.d.ts.map +1 -1
- package/build/lib/catalog/catalog.js +67 -5
- package/build/lib/catalog/catalog.js.map +1 -1
- package/build/lib/catalog/versioned.d.ts +11 -1
- package/build/lib/catalog/versioned.d.ts.map +1 -1
- package/build/lib/catalog/versioned.js +23 -5
- package/build/lib/catalog/versioned.js.map +1 -1
- package/build/lib/document/document.d.ts +55 -5
- package/build/lib/document/document.d.ts.map +1 -1
- package/build/lib/document/document.js +96 -2
- package/build/lib/document/document.js.map +1 -1
- package/build/lib/document/versioned.d.ts +2 -2
- package/build/lib/document/versioned.d.ts.map +1 -1
- package/build/lib/document/versioned.js +7 -7
- package/build/lib/document/versioned.js.map +1 -1
- package/build/lib/lifecycles/lifecycles.d.ts +5 -4
- package/build/lib/lifecycles/lifecycles.d.ts.map +1 -1
- package/build/lib/lifecycles/lifecycles.js +14 -12
- package/build/lib/lifecycles/lifecycles.js.map +1 -1
- package/build/lib/version-coverage/$$.d.ts +2 -0
- package/build/lib/version-coverage/$$.d.ts.map +1 -0
- package/build/lib/version-coverage/$$.js +2 -0
- package/build/lib/version-coverage/$$.js.map +1 -0
- package/build/lib/version-coverage/$.d.ts.map +1 -0
- package/build/lib/version-coverage/$.js.map +1 -0
- package/build/lib/{version-selection/version-selection.d.ts → version-coverage/version-coverage.d.ts} +1 -1
- package/build/lib/version-coverage/version-coverage.d.ts.map +1 -0
- package/build/lib/{version-selection/version-selection.js → version-coverage/version-coverage.js} +2 -2
- package/build/lib/version-coverage/version-coverage.js.map +1 -0
- package/build/template/components/GraphQLDocument.d.ts +1 -1
- package/build/template/components/GraphQLDocument.d.ts.map +1 -1
- package/build/template/components/GraphQLDocument.js +10 -39
- package/build/template/components/GraphQLDocument.js.map +1 -1
- package/build/template/components/GraphQLInteractive/lib/parser.d.ts +28 -0
- package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -1
- package/build/template/components/GraphQLInteractive/lib/parser.js +60 -27
- package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -1
- package/build/template/components/ReferenceVersionPicker.d.ts +9 -0
- package/build/template/components/ReferenceVersionPicker.d.ts.map +1 -0
- package/build/template/components/ReferenceVersionPicker.js +79 -0
- package/build/template/components/ReferenceVersionPicker.js.map +1 -0
- package/build/template/components/VersionCoveragePicker.d.ts +1 -1
- package/build/template/components/VersionCoveragePicker.d.ts.map +1 -1
- package/build/template/components/VersionCoveragePicker.js +4 -6
- package/build/template/components/VersionCoveragePicker.js.map +1 -1
- package/build/template/components/VersionPicker.d.ts +8 -3
- package/build/template/components/VersionPicker.d.ts.map +1 -1
- package/build/template/components/VersionPicker.js +12 -77
- package/build/template/components/VersionPicker.js.map +1 -1
- package/build/template/components/home/QuickStart.d.ts.map +1 -1
- package/build/template/components/home/QuickStart.js +8 -4
- package/build/template/components/home/QuickStart.js.map +1 -1
- package/build/template/hooks/use-highlighted.d.ts.map +1 -1
- package/build/template/hooks/use-highlighted.js +19 -13
- package/build/template/hooks/use-highlighted.js.map +1 -1
- package/build/template/lib/fetch-text.d.ts +18 -0
- package/build/template/lib/fetch-text.d.ts.map +1 -1
- package/build/template/lib/fetch-text.js +32 -4
- package/build/template/lib/fetch-text.js.map +1 -1
- package/build/template/routes/changelog/ChangelogBody.d.ts +6 -0
- package/build/template/routes/changelog/ChangelogBody.d.ts.map +1 -0
- package/build/template/{components/Changelog/Changelog.js → routes/changelog/ChangelogBody.js} +8 -58
- package/build/template/routes/changelog/ChangelogBody.js.map +1 -0
- package/build/template/routes/changelog/ChangelogSidebar.d.ts +7 -0
- package/build/template/routes/changelog/ChangelogSidebar.d.ts.map +1 -0
- package/build/template/routes/changelog/ChangelogSidebar.js +46 -0
- package/build/template/routes/changelog/ChangelogSidebar.js.map +1 -0
- package/build/template/routes/changelog/ChangelogSidebarItem.d.ts +11 -0
- package/build/template/routes/changelog/ChangelogSidebarItem.d.ts.map +1 -0
- package/build/template/routes/changelog/ChangelogSidebarItem.js +35 -0
- package/build/template/routes/changelog/ChangelogSidebarItem.js.map +1 -0
- package/build/template/routes/changelog/_.d.ts +3264 -0
- package/build/template/routes/changelog/_.d.ts.map +1 -0
- package/build/template/routes/changelog/_.js +111 -0
- package/build/template/routes/changelog/_.js.map +1 -0
- package/build/template/routes/changelog/utils.d.ts +3 -0
- package/build/template/routes/changelog/utils.d.ts.map +1 -0
- package/build/template/routes/changelog/utils.js +11 -0
- package/build/template/routes/changelog/utils.js.map +1 -0
- package/build/template/routes/examples/name.d.ts.map +1 -1
- package/build/template/routes/examples/name.js +4 -2
- package/build/template/routes/examples/name.js.map +1 -1
- package/build/template/routes/reference.js +2 -2
- package/build/template/routes/reference.js.map +1 -1
- package/build/template/routes/root.js +1 -1
- package/build/template/routes/root.js.map +1 -1
- package/build/template/stores/toast.d.ts.map +1 -1
- package/build/template/stores/toast.js +5 -3
- package/build/template/stores/toast.js.map +1 -1
- package/build/template/theme/swiss-sharp.css +14 -14
- package/build/vite/plugins/schemas.d.ts +1 -2
- package/build/vite/plugins/schemas.d.ts.map +1 -1
- package/build/vite/plugins/schemas.js +0 -1
- package/build/vite/plugins/schemas.js.map +1 -1
- package/package.json +7 -7
- package/src/api/builder/ssg/generate.ts +10 -5
- package/src/api/builder/ssg/page-generator.worker.ts +18 -3
- package/src/api/config/normalized.ts +12 -3
- package/src/api/config-template/template.ts +2 -2
- package/src/api/content/sidebar.ts +3 -3
- package/src/api/errors.ts +227 -0
- package/src/api/examples/config.test.ts +10 -0
- package/src/api/examples/config.ts +33 -4
- package/src/api/examples/diagnostic/validation-error.ts +9 -3
- package/src/api/examples/diagnostic/validator.test.ts +30 -0
- package/src/api/examples/diagnostic/validator.ts +148 -103
- package/src/api/examples/filter.ts +9 -6
- package/src/api/examples/scanner.ts +136 -117
- package/src/api/examples/type-usage-indexer.ts +24 -36
- package/src/api/iso/schema/routing.ts +10 -10
- package/src/api/iso/schema/validation.ts +3 -2
- package/src/api/schema/input-source/$$.ts +1 -0
- package/src/api/schema/input-source/errors.ts +26 -0
- package/src/api/schema/input-source/input-source.ts +1 -22
- package/src/api/schema/input-sources/directory.ts +20 -15
- package/src/api/schema/input-sources/file.ts +17 -4
- package/src/api/schema/input-sources/introspection-file.ts +30 -15
- package/src/api/schema/input-sources/introspection.ts +38 -7
- package/src/api/schema/input-sources/memory.ts +19 -3
- package/src/api/schema/input-sources/versioned-directory.ts +25 -27
- package/src/api/schema/load.ts +2 -1
- package/src/lib/catalog/catalog.ts +89 -6
- package/src/lib/catalog/versioned.ts +26 -5
- package/src/lib/document/document.ts +135 -2
- package/src/lib/document/versioned.ts +8 -8
- package/src/lib/lifecycles/lifecycles.ts +32 -27
- package/src/lib/version-coverage/$$.ts +1 -0
- package/src/lib/{version-selection/version-selection.ts → version-coverage/version-coverage.ts} +1 -1
- package/src/template/components/GraphQLDocument.tsx +11 -69
- package/src/template/components/GraphQLInteractive/lib/parser.ts +81 -29
- package/src/template/components/ReferenceVersionPicker.tsx +107 -0
- package/src/template/components/VersionCoveragePicker.tsx +4 -5
- package/src/template/components/VersionPicker.tsx +32 -98
- package/src/template/components/home/QuickStart.tsx +16 -7
- package/src/template/hooks/use-highlighted.ts +31 -19
- package/src/template/lib/fetch-text.ts +45 -4
- package/src/template/{components/Changelog/Changelog.tsx → routes/changelog/ChangelogBody.tsx} +7 -64
- package/src/template/routes/changelog/ChangelogSidebar.tsx +80 -0
- package/src/template/routes/changelog/ChangelogSidebarItem.tsx +68 -0
- package/src/template/routes/changelog/_.tsx +129 -0
- package/src/template/routes/changelog/utils.ts +13 -0
- package/src/template/routes/examples/name.tsx +4 -2
- package/src/template/routes/reference.tsx +2 -2
- package/src/template/routes/root.tsx +1 -1
- package/src/template/stores/toast.ts +6 -3
- package/src/template/theme/swiss-sharp.css +14 -14
- package/src/vite/plugins/schemas.ts +0 -1
- package/build/lib/graph/$$.d.ts +0 -2
- package/build/lib/graph/$$.d.ts.map +0 -1
- package/build/lib/graph/$$.js +0 -2
- package/build/lib/graph/$$.js.map +0 -1
- package/build/lib/graph/$.d.ts +0 -2
- package/build/lib/graph/$.d.ts.map +0 -1
- package/build/lib/graph/$.js +0 -2
- package/build/lib/graph/$.js.map +0 -1
- package/build/lib/graph/graph.d.ts +0 -127
- package/build/lib/graph/graph.d.ts.map +0 -1
- package/build/lib/graph/graph.js +0 -152
- package/build/lib/graph/graph.js.map +0 -1
- package/build/lib/mask/$$.d.ts +0 -3
- package/build/lib/mask/$$.d.ts.map +0 -1
- package/build/lib/mask/$$.js +0 -3
- package/build/lib/mask/$$.js.map +0 -1
- package/build/lib/mask/$.d.ts +0 -2
- package/build/lib/mask/$.d.ts.map +0 -1
- package/build/lib/mask/$.js +0 -2
- package/build/lib/mask/$.js.map +0 -1
- package/build/lib/mask/apply.d.ts +0 -86
- package/build/lib/mask/apply.d.ts.map +0 -1
- package/build/lib/mask/apply.js +0 -86
- package/build/lib/mask/apply.js.map +0 -1
- package/build/lib/mask/mask.d.ts +0 -124
- package/build/lib/mask/mask.d.ts.map +0 -1
- package/build/lib/mask/mask.js +0 -137
- package/build/lib/mask/mask.js.map +0 -1
- package/build/lib/mask/mask.test-d.d.ts +0 -2
- package/build/lib/mask/mask.test-d.d.ts.map +0 -1
- package/build/lib/mask/mask.test-d.js +0 -102
- package/build/lib/mask/mask.test-d.js.map +0 -1
- package/build/lib/version-selection/$$.d.ts +0 -2
- package/build/lib/version-selection/$$.d.ts.map +0 -1
- package/build/lib/version-selection/$$.js +0 -2
- package/build/lib/version-selection/$$.js.map +0 -1
- package/build/lib/version-selection/$.d.ts.map +0 -1
- package/build/lib/version-selection/$.js.map +0 -1
- package/build/lib/version-selection/version-selection.d.ts.map +0 -1
- package/build/lib/version-selection/version-selection.js.map +0 -1
- package/build/sandbox.d.ts +0 -2
- package/build/sandbox.d.ts.map +0 -1
- package/build/sandbox.js +0 -17
- package/build/sandbox.js.map +0 -1
- package/build/template/components/Changelog/Changelog.d.ts +0 -8
- package/build/template/components/Changelog/Changelog.d.ts.map +0 -1
- package/build/template/components/Changelog/Changelog.js.map +0 -1
- package/build/template/components/Changelog/ChangelogVersionPicker.d.ts +0 -8
- package/build/template/components/Changelog/ChangelogVersionPicker.d.ts.map +0 -1
- package/build/template/components/Changelog/ChangelogVersionPicker.js +0 -16
- package/build/template/components/Changelog/ChangelogVersionPicker.js.map +0 -1
- package/build/template/components/SimpleVersionPicker.d.ts +0 -15
- package/build/template/components/SimpleVersionPicker.d.ts.map +0 -1
- package/build/template/components/SimpleVersionPicker.js +0 -15
- package/build/template/components/SimpleVersionPicker.js.map +0 -1
- package/build/template/routes/changelog.d.ts +0 -1635
- package/build/template/routes/changelog.d.ts.map +0 -1
- package/build/template/routes/changelog.js +0 -168
- package/build/template/routes/changelog.js.map +0 -1
- package/src/lib/graph/$$.ts +0 -1
- package/src/lib/graph/$.ts +0 -1
- package/src/lib/graph/graph.ts +0 -197
- package/src/lib/mask/$$.ts +0 -2
- package/src/lib/mask/$.test.ts +0 -226
- package/src/lib/mask/$.ts +0 -1
- package/src/lib/mask/apply.ts +0 -134
- package/src/lib/mask/mask.test-d.ts +0 -156
- package/src/lib/mask/mask.ts +0 -244
- package/src/lib/version-selection/$$.ts +0 -1
- package/src/sandbox.ts +0 -15
- package/src/template/components/Changelog/ChangelogVersionPicker.tsx +0 -36
- package/src/template/components/SimpleVersionPicker.tsx +0 -48
- package/src/template/routes/changelog.tsx +0 -267
- /package/build/lib/{version-selection → version-coverage}/$.d.ts +0 -0
- /package/build/lib/{version-selection → version-coverage}/$.js +0 -0
- /package/src/lib/{version-selection → version-coverage}/$.ts +0 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
import { Api } from '#api/iso'
|
2
|
+
import type { React } from '#dep/react/index'
|
3
|
+
import { Version } from '#lib/version/$'
|
4
|
+
import { HashMap, Option } from 'effect'
|
5
|
+
import { useNavigate } from 'react-router'
|
6
|
+
import { schemasCatalog } from 'virtual:polen/project/schemas'
|
7
|
+
import { useReferencePath } from '../hooks/useReferencePath.js'
|
8
|
+
import { Stores } from '../stores/$.js'
|
9
|
+
import { tryWithToast } from '../utils/try-with-toast.js'
|
10
|
+
import { VersionPicker } from './VersionPicker.js'
|
11
|
+
|
12
|
+
interface Props {
|
13
|
+
data: readonly Version.Version[]
|
14
|
+
current: Version.Version
|
15
|
+
}
|
16
|
+
|
17
|
+
export const ReferenceVersionPicker: React.FC<Props> = ({ data, current }) => {
|
18
|
+
const navigate = useNavigate()
|
19
|
+
const currentPath = useReferencePath()
|
20
|
+
|
21
|
+
const handleVersionChange = async (version: Version.Version) => {
|
22
|
+
const newVersion = Version.encodeSync(version)
|
23
|
+
const error = await tryWithToast(async () => {
|
24
|
+
// Get the full catalog to find the target schema
|
25
|
+
if (!schemasCatalog) {
|
26
|
+
throw new Error('No catalog available')
|
27
|
+
}
|
28
|
+
const catalog = schemasCatalog
|
29
|
+
|
30
|
+
// This component is only used for versioned catalogs
|
31
|
+
if (catalog._tag !== 'CatalogVersioned') {
|
32
|
+
throw new Error('VersionPicker used with non-versioned catalog')
|
33
|
+
}
|
34
|
+
|
35
|
+
// Find the schema for the target version
|
36
|
+
// Note: newVersion is a string that we need to parse
|
37
|
+
const targetSchemaOption = Option.map(
|
38
|
+
HashMap.findFirst(catalog.entries, (_, key) => Version.encodeSync(key) === newVersion),
|
39
|
+
([, value]) => value,
|
40
|
+
)
|
41
|
+
|
42
|
+
if (Option.isNone(targetSchemaOption)) {
|
43
|
+
throw new Error(`Version ${newVersion} not found`)
|
44
|
+
}
|
45
|
+
|
46
|
+
const targetSchema = Option.getOrThrow(targetSchemaOption)
|
47
|
+
|
48
|
+
// Find fallback path if needed
|
49
|
+
const fallbackPath = Api.Schema.Validation.findFallbackPath(targetSchema.definition, currentPath)
|
50
|
+
// Get redirect description if path changed
|
51
|
+
const redirectDescription = Api.Schema.Validation.getRedirectDescription(
|
52
|
+
targetSchema.definition,
|
53
|
+
currentPath,
|
54
|
+
fallbackPath,
|
55
|
+
newVersion,
|
56
|
+
)
|
57
|
+
// Create the new path - parse newVersion string to Version type
|
58
|
+
const newPath = Api.Schema.Routing.createReferencePath({
|
59
|
+
version: Version.fromString(newVersion),
|
60
|
+
type: fallbackPath.type || '',
|
61
|
+
field: fallbackPath.field || '',
|
62
|
+
})
|
63
|
+
// Show toast notification if schema location redirect will occur
|
64
|
+
if (redirectDescription) {
|
65
|
+
Stores.Toast.store.info(redirectDescription, {
|
66
|
+
duration: 160_000,
|
67
|
+
actions: [
|
68
|
+
{
|
69
|
+
label: 'Go back',
|
70
|
+
onClick() {
|
71
|
+
navigate(-1)
|
72
|
+
},
|
73
|
+
},
|
74
|
+
{
|
75
|
+
label: 'View changelog',
|
76
|
+
onClick() {
|
77
|
+
// Navigate to changelog page
|
78
|
+
navigate('/changelog')
|
79
|
+
},
|
80
|
+
},
|
81
|
+
],
|
82
|
+
})
|
83
|
+
}
|
84
|
+
|
85
|
+
navigate(newPath)
|
86
|
+
}, 'Failed to switch version')
|
87
|
+
|
88
|
+
// Fallback logic if error occurred
|
89
|
+
if (error) {
|
90
|
+
// Fallback to simple navigation if schema loading fails
|
91
|
+
const newPath = Api.Schema.Routing.createReferencePath({
|
92
|
+
version: Version.fromString(newVersion),
|
93
|
+
type: currentPath.type || '',
|
94
|
+
field: currentPath.field || '',
|
95
|
+
})
|
96
|
+
navigate(newPath)
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
return (
|
101
|
+
<VersionPicker
|
102
|
+
versions={data}
|
103
|
+
currentVersion={current}
|
104
|
+
onVersionChange={handleVersionChange}
|
105
|
+
/>
|
106
|
+
)
|
107
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Catalog } from '#lib/catalog/$'
|
2
2
|
import { Document } from '#lib/document/$'
|
3
|
-
import { VersionCoverage } from '#lib/version-
|
3
|
+
import { VersionCoverage } from '#lib/version-coverage'
|
4
4
|
import { Select } from '@radix-ui/themes'
|
5
5
|
import { HashMap } from 'effect'
|
6
6
|
import type { FC } from 'react'
|
@@ -30,12 +30,11 @@ export const VersionCoveragePicker: FC<Props> = ({
|
|
30
30
|
<Select.Root
|
31
31
|
value={VersionCoverage.toLabel(current)}
|
32
32
|
onValueChange={(label) => {
|
33
|
-
// Find
|
33
|
+
// Find the full version coverage by label and pass it entirely
|
34
34
|
const selection = options.find(s => VersionCoverage.toLabel(s) === label)
|
35
35
|
if (selection) {
|
36
|
-
|
37
|
-
|
38
|
-
if (version) onChange(version)
|
36
|
+
// Pass the entire VersionCoverage, not just the first version
|
37
|
+
onChange(selection)
|
39
38
|
}
|
40
39
|
}}
|
41
40
|
>
|
@@ -1,108 +1,42 @@
|
|
1
|
-
import { Api } from '#api/iso'
|
2
|
-
import type { React } from '#dep/react/index'
|
3
|
-
import { Catalog } from '#lib/catalog/$'
|
4
1
|
import { Version } from '#lib/version/$'
|
5
|
-
import {
|
6
|
-
import
|
7
|
-
import { schemasCatalog } from 'virtual:polen/project/schemas'
|
8
|
-
import { useReferencePath } from '../hooks/useReferencePath.js'
|
9
|
-
import { Stores } from '../stores/$.js'
|
10
|
-
import { tryWithToast } from '../utils/try-with-toast.js'
|
11
|
-
import { SimpleVersionPicker } from './SimpleVersionPicker.js'
|
2
|
+
import { Select } from '@radix-ui/themes'
|
3
|
+
import type * as React from 'react'
|
12
4
|
|
13
5
|
interface Props {
|
14
|
-
|
15
|
-
|
6
|
+
versions: readonly Version.Version[]
|
7
|
+
currentVersion: Version.Version
|
8
|
+
onVersionChange: (version: Version.Version) => void
|
16
9
|
}
|
17
10
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
// This component is only used for versioned catalogs
|
32
|
-
if (catalog._tag !== 'CatalogVersioned') {
|
33
|
-
throw new Error('VersionPicker used with non-versioned catalog')
|
34
|
-
}
|
35
|
-
|
36
|
-
// Find the schema for the target version
|
37
|
-
// Note: newVersion is a string that we need to parse
|
38
|
-
const targetSchemaOption = Option.map(
|
39
|
-
HashMap.findFirst(catalog.entries, (_, key) => Version.encodeSync(key) === newVersion),
|
40
|
-
([, value]) => value,
|
41
|
-
)
|
42
|
-
|
43
|
-
if (Option.isNone(targetSchemaOption)) {
|
44
|
-
throw new Error(`Version ${newVersion} not found`)
|
45
|
-
}
|
46
|
-
|
47
|
-
const targetSchema = Option.getOrThrow(targetSchemaOption)
|
48
|
-
|
49
|
-
// Find fallback path if needed
|
50
|
-
const fallbackPath = Api.Schema.Validation.findFallbackPath(targetSchema.definition, currentPath)
|
51
|
-
// Get redirect description if path changed
|
52
|
-
const redirectDescription = Api.Schema.Validation.getRedirectDescription(
|
53
|
-
targetSchema.definition,
|
54
|
-
currentPath,
|
55
|
-
fallbackPath,
|
56
|
-
newVersion,
|
57
|
-
)
|
58
|
-
// Create the new path - parse newVersion string to Version type
|
59
|
-
const newPath = Api.Schema.Routing.createReferencePath({
|
60
|
-
version: Version.fromString(newVersion),
|
61
|
-
type: fallbackPath.type || '',
|
62
|
-
field: fallbackPath.field || '',
|
63
|
-
})
|
64
|
-
// Show toast notification if schema location redirect will occur
|
65
|
-
if (redirectDescription) {
|
66
|
-
Stores.Toast.store.info(redirectDescription, {
|
67
|
-
duration: 160_000,
|
68
|
-
actions: [
|
69
|
-
{
|
70
|
-
label: 'Go back',
|
71
|
-
onClick() {
|
72
|
-
navigate(-1)
|
73
|
-
},
|
74
|
-
},
|
75
|
-
{
|
76
|
-
label: 'View changelog',
|
77
|
-
onClick() {
|
78
|
-
// Navigate to changelog page
|
79
|
-
navigate('/changelog')
|
80
|
-
},
|
81
|
-
},
|
82
|
-
],
|
83
|
-
})
|
84
|
-
}
|
85
|
-
|
86
|
-
navigate(newPath)
|
87
|
-
}, 'Failed to switch version')
|
88
|
-
|
89
|
-
// Fallback logic if error occurred
|
90
|
-
if (error) {
|
91
|
-
// Fallback to simple navigation if schema loading fails
|
92
|
-
const newPath = Api.Schema.Routing.createReferencePath({
|
93
|
-
version: Version.fromString(newVersion),
|
94
|
-
type: currentPath.type || '',
|
95
|
-
field: currentPath.field || '',
|
96
|
-
})
|
97
|
-
navigate(newPath)
|
98
|
-
}
|
11
|
+
/**
|
12
|
+
* A generic version picker component that can be used for any versioned content.
|
13
|
+
* This is a controlled component - parent manages the state.
|
14
|
+
*/
|
15
|
+
export const VersionPicker: React.FC<Props> = ({
|
16
|
+
versions,
|
17
|
+
currentVersion,
|
18
|
+
onVersionChange,
|
19
|
+
}) => {
|
20
|
+
// Don't show selector if only one version
|
21
|
+
if (versions.length <= 1) {
|
22
|
+
return null
|
99
23
|
}
|
100
24
|
|
101
25
|
return (
|
102
|
-
<
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
26
|
+
<Select.Root
|
27
|
+
value={Version.encodeSync(currentVersion)}
|
28
|
+
onValueChange={(versionEncoded) => onVersionChange(Version.fromString(versionEncoded))}
|
29
|
+
>
|
30
|
+
<Select.Trigger style={{ minWidth: '120px' }}>
|
31
|
+
Version {Version.encodeSync(currentVersion)}
|
32
|
+
</Select.Trigger>
|
33
|
+
<Select.Content position='popper' sideOffset={5}>
|
34
|
+
{versions.map(version => (
|
35
|
+
<Select.Item key={Version.encodeSync(version)} value={Version.encodeSync(version)}>
|
36
|
+
Version {Version.encodeSync(version)}
|
37
|
+
</Select.Item>
|
38
|
+
))}
|
39
|
+
</Select.Content>
|
40
|
+
</Select.Root>
|
107
41
|
)
|
108
42
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { Box, Card, Heading, Section, Tabs, Text } from '@radix-ui/themes'
|
2
2
|
import { highlight } from 'codehike/code'
|
3
|
+
import { Effect } from 'effect'
|
3
4
|
import * as React from 'react'
|
4
5
|
import { CodeBlock } from '../CodeBlock.js'
|
5
6
|
|
@@ -73,14 +74,22 @@ export const QuickStartSection: React.FC<Props> = ({ examples = defaultExamples
|
|
73
74
|
|
74
75
|
React.useEffect(() => {
|
75
76
|
const highlightExamples = async () => {
|
76
|
-
const highlighted = await
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
const highlighted = await Effect.runPromise(
|
78
|
+
Effect.all(
|
79
|
+
examples.map((example) =>
|
80
|
+
Effect.tryPromise({
|
81
|
+
try: async () => ({
|
82
|
+
label: example.label,
|
83
|
+
codeblock: await highlight(
|
84
|
+
{ value: example.code, lang: example.language, meta: '' },
|
85
|
+
{ theme: 'github-light' },
|
86
|
+
),
|
87
|
+
}),
|
88
|
+
catch: (error) => new Error(`Failed to highlight ${example.label}: ${error}`),
|
89
|
+
})
|
82
90
|
),
|
83
|
-
|
91
|
+
{ concurrency: 'unbounded' },
|
92
|
+
),
|
84
93
|
)
|
85
94
|
setHighlightedExamples(highlighted)
|
86
95
|
}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import type { HighlightedCode } from 'codehike/code'
|
2
2
|
import { highlight } from 'codehike/code'
|
3
|
+
import { Duration, Effect } from 'effect'
|
3
4
|
import * as React from 'react'
|
4
5
|
|
5
6
|
/**
|
@@ -29,26 +30,37 @@ export const useHighlighted = (
|
|
29
30
|
const [highlightedCode, setHighlightedCode] = React.useState<HighlightedCode | null>(null)
|
30
31
|
|
31
32
|
React.useEffect(() => {
|
32
|
-
const
|
33
|
-
// Add a timeout to detect if highlight is hanging
|
34
|
-
const timeoutPromise = new Promise((_, reject) => {
|
35
|
-
setTimeout(() => reject(new Error('Highlight timeout after 5 seconds')), 5000)
|
36
|
-
})
|
37
|
-
|
38
|
-
const highlightPromise = highlight(
|
39
|
-
{
|
40
|
-
value: content,
|
41
|
-
lang: config.lang,
|
42
|
-
meta: metaString,
|
43
|
-
},
|
44
|
-
{
|
45
|
-
theme: 'github-light',
|
46
|
-
},
|
47
|
-
)
|
33
|
+
const HIGHLIGHT_TIMEOUT = Duration.seconds(5)
|
48
34
|
|
49
|
-
|
50
|
-
|
51
|
-
|
35
|
+
const highlightContent = async () => {
|
36
|
+
try {
|
37
|
+
const highlighted = await Effect.runPromise(
|
38
|
+
Effect.tryPromise({
|
39
|
+
try: () =>
|
40
|
+
highlight(
|
41
|
+
{
|
42
|
+
value: content,
|
43
|
+
lang: config.lang,
|
44
|
+
meta: metaString,
|
45
|
+
},
|
46
|
+
{
|
47
|
+
theme: 'github-light',
|
48
|
+
},
|
49
|
+
),
|
50
|
+
catch: (error) => new Error(`Highlight failed: ${error}`),
|
51
|
+
}).pipe(
|
52
|
+
Effect.timeout(HIGHLIGHT_TIMEOUT),
|
53
|
+
Effect.catchTag(
|
54
|
+
'TimeoutException',
|
55
|
+
() => Effect.fail(new Error(`Highlight timeout after ${Duration.toSeconds(HIGHLIGHT_TIMEOUT)} seconds`)),
|
56
|
+
),
|
57
|
+
),
|
58
|
+
)
|
59
|
+
setHighlightedCode(highlighted)
|
60
|
+
} catch (error) {
|
61
|
+
console.error('Failed to highlight code:', error)
|
62
|
+
setHighlightedCode(null)
|
63
|
+
}
|
52
64
|
}
|
53
65
|
highlightContent()
|
54
66
|
}, [content, config.lang, config.interactive])
|
@@ -1,13 +1,54 @@
|
|
1
|
+
import { Either } from 'effect'
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Error type for fetch failures
|
5
|
+
*/
|
6
|
+
export interface FetchError {
|
7
|
+
readonly _tag: 'FetchError'
|
8
|
+
readonly url: string
|
9
|
+
readonly status: number
|
10
|
+
readonly statusText: string
|
11
|
+
readonly message: string
|
12
|
+
}
|
13
|
+
|
14
|
+
const makeFetchError = (url: string, status: number, statusText: string): FetchError => ({
|
15
|
+
_tag: 'FetchError',
|
16
|
+
url,
|
17
|
+
status,
|
18
|
+
statusText,
|
19
|
+
message: `Failed to fetch: ${url} (${status} ${statusText})`,
|
20
|
+
})
|
21
|
+
|
1
22
|
/**
|
2
23
|
* Fetch text content from a URL
|
3
24
|
* @param url - The URL to fetch from
|
25
|
+
* @returns Either with text content on right or FetchError on left
|
26
|
+
*/
|
27
|
+
export const fetchTextEither = async (url: string): Promise<Either.Either<string, FetchError>> => {
|
28
|
+
try {
|
29
|
+
const response = await fetch(url)
|
30
|
+
if (!response.ok) {
|
31
|
+
return Either.left(makeFetchError(url, response.status, response.statusText))
|
32
|
+
}
|
33
|
+
const text = await response.text()
|
34
|
+
return Either.right(text)
|
35
|
+
} catch (error) {
|
36
|
+
// Network errors or other exceptions
|
37
|
+
return Either.left(makeFetchError(url, 0, 'Network Error'))
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Fetch text content from a URL (legacy throwing version)
|
43
|
+
* @param url - The URL to fetch from
|
4
44
|
* @returns Promise that resolves to the text content
|
5
45
|
* @throws Error if the request fails
|
46
|
+
* @deprecated Use fetchTextEither for better error handling
|
6
47
|
*/
|
7
48
|
export const fetchText = async (url: string): Promise<string> => {
|
8
|
-
const
|
9
|
-
if (
|
10
|
-
throw new Error(
|
49
|
+
const result = await fetchTextEither(url)
|
50
|
+
if (Either.isLeft(result)) {
|
51
|
+
throw new Error(result.left.message)
|
11
52
|
}
|
12
|
-
return
|
53
|
+
return result.right
|
13
54
|
}
|
package/src/template/{components/Changelog/Changelog.tsx → routes/changelog/ChangelogBody.tsx}
RENAMED
@@ -1,75 +1,18 @@
|
|
1
1
|
import { Catalog } from '#lib/catalog/$'
|
2
2
|
import { Change } from '#lib/change/$'
|
3
|
-
import { DateOnly } from '#lib/date-only/$'
|
4
3
|
import { Revision } from '#lib/revision/$'
|
5
4
|
import { Schema } from '#lib/schema/$'
|
6
|
-
import { Version } from '#lib/version/$'
|
7
|
-
import { HashMap, Option } from 'effect'
|
8
5
|
const CRITICALITY_LEVELS = ['BREAKING', 'DANGEROUS', 'NON_BREAKING'] as const
|
9
6
|
import type { CriticalityLevel } from '@graphql-inspector/core'
|
10
7
|
import { Box, Heading } from '@radix-ui/themes'
|
11
|
-
import React
|
8
|
+
import React from 'react'
|
12
9
|
import { useMemo } from 'react'
|
13
|
-
import {
|
14
|
-
import
|
15
|
-
import {
|
16
|
-
import
|
17
|
-
|
18
|
-
export const renderDate = (dateOnly: DateOnly.DateOnly) => {
|
19
|
-
const date = DateOnly.toDate(dateOnly)
|
20
|
-
const year = date.getUTCFullYear()
|
21
|
-
return `${year} ${
|
22
|
-
date.toLocaleString('default', {
|
23
|
-
month: 'long',
|
24
|
-
day: 'numeric',
|
25
|
-
timeZone: 'UTC',
|
26
|
-
})
|
27
|
-
}`
|
28
|
-
}
|
29
|
-
|
30
|
-
export const Changelog: React.FC<{ catalog: Catalog.Catalog }> = ({ catalog }) => {
|
31
|
-
const params = useParams()
|
32
|
-
const navigate = useNavigate()
|
33
|
-
const urlVersion = params['version']
|
34
|
-
|
35
|
-
// Redirect to latest version if versioned catalog and no version specified
|
36
|
-
useEffect(() => {
|
37
|
-
if (urlVersion) return
|
38
|
-
if (Catalog.Unversioned.is(catalog)) return
|
39
|
-
const latestSchema = Catalog.Versioned.getLatestOrThrow(catalog)
|
40
|
-
const latestVersion = Version.encodeSync(latestSchema.version)
|
41
|
-
navigate(`/changelog/version/${latestVersion}`, { replace: true })
|
42
|
-
}, [catalog, urlVersion, navigate])
|
43
|
-
|
44
|
-
// Get revisions and corresponding schema based on catalog type and URL params
|
45
|
-
const { revisions, schema } = useMemo(() => {
|
46
|
-
if (Catalog.Unversioned.is(catalog)) {
|
47
|
-
return {
|
48
|
-
revisions: catalog.schema.revisions,
|
49
|
-
schema: catalog.schema,
|
50
|
-
}
|
51
|
-
} else {
|
52
|
-
// For versioned catalogs, always show specific version (never all)
|
53
|
-
if (urlVersion) {
|
54
|
-
const entryOption = Option.map(
|
55
|
-
HashMap.findFirst(catalog.entries, (_, key) => Version.encodeSync(key) === urlVersion),
|
56
|
-
([, value]) => value,
|
57
|
-
)
|
58
|
-
return Option.match(entryOption, {
|
59
|
-
onNone: () => ({ revisions: [], schema: null }),
|
60
|
-
onSome: (entry) => ({ revisions: entry.revisions, schema: entry }),
|
61
|
-
})
|
62
|
-
}
|
63
|
-
// This shouldn't happen due to redirect above, but return empty as fallback
|
64
|
-
return { revisions: [], schema: null }
|
65
|
-
}
|
66
|
-
}, [catalog, urlVersion])
|
67
|
-
|
68
|
-
// Don't render anything while redirecting
|
69
|
-
if (Catalog.Versioned.is(catalog) && !urlVersion) {
|
70
|
-
return null
|
71
|
-
}
|
10
|
+
import { CriticalitySection } from '../../components/Changelog/CriticalitySection.js'
|
11
|
+
import * as Group from '../../components/Changelog/groups/index.js'
|
12
|
+
import { ComponentDispatch } from '../../components/ComponentDispatch.js'
|
13
|
+
import { renderDate } from './utils.js'
|
72
14
|
|
15
|
+
export const ChangelogBody: React.FC<{ schema: Schema.Schema }> = ({ schema }) => {
|
73
16
|
return (
|
74
17
|
<Box>
|
75
18
|
{/* Title bar - always shown */}
|
@@ -77,7 +20,7 @@ export const Changelog: React.FC<{ catalog: Catalog.Catalog }> = ({ catalog }) =
|
|
77
20
|
Changelog
|
78
21
|
</Heading>
|
79
22
|
|
80
|
-
{revisions.map(revision => <Changeset key={revision.date} revision={revision} schema={schema} />)}
|
23
|
+
{schema.revisions.map(revision => <Changeset key={revision.date} revision={revision} schema={schema} />)}
|
81
24
|
</Box>
|
82
25
|
)
|
83
26
|
}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import { Catalog } from '#lib/catalog/$'
|
2
|
+
import { Schema } from '#lib/schema/$'
|
3
|
+
import { Swiss } from '#lib/swiss/$'
|
4
|
+
import { Version } from '#lib/version'
|
5
|
+
import { Box, Text } from '@radix-ui/themes'
|
6
|
+
import { useEffect, useState } from 'react'
|
7
|
+
import { useNavigate, useParams } from 'react-router'
|
8
|
+
import { VersionPicker } from '../../components/VersionPicker.js'
|
9
|
+
import { ChangelogSidebarItem } from './ChangelogSidebarItem.js'
|
10
|
+
|
11
|
+
export const ChangelogSidebar: React.FC<{
|
12
|
+
catalog: Catalog.Catalog
|
13
|
+
schema: Schema.Schema
|
14
|
+
}> = ({ catalog, schema }) => {
|
15
|
+
{
|
16
|
+
const navigate = useNavigate()
|
17
|
+
|
18
|
+
// Get revisions for the current version (for sidebar)
|
19
|
+
const revisions = schema.revisions
|
20
|
+
|
21
|
+
const [activeRevision, setActiveRevision] = useState<string | null>(null)
|
22
|
+
// Track active revision based on URL hash
|
23
|
+
useEffect(() => {
|
24
|
+
const handleHashChange = () => {
|
25
|
+
const hash = window.location.hash.slice(1)
|
26
|
+
setActiveRevision(hash || null)
|
27
|
+
}
|
28
|
+
|
29
|
+
// Set initial active revision
|
30
|
+
handleHashChange()
|
31
|
+
|
32
|
+
// Listen for hash changes
|
33
|
+
window.addEventListener('hashchange', handleHashChange)
|
34
|
+
|
35
|
+
// Listen for pushState/replaceState (custom event we'll dispatch)
|
36
|
+
window.addEventListener('pushstate', handleHashChange)
|
37
|
+
|
38
|
+
return () => {
|
39
|
+
window.removeEventListener('hashchange', handleHashChange)
|
40
|
+
window.removeEventListener('pushstate', handleHashChange)
|
41
|
+
}
|
42
|
+
}, [])
|
43
|
+
|
44
|
+
return (
|
45
|
+
<Swiss.Item
|
46
|
+
cols={3}
|
47
|
+
style={{
|
48
|
+
position: 'sticky',
|
49
|
+
top: '2rem',
|
50
|
+
height: 'fit-content',
|
51
|
+
minWidth: '250px',
|
52
|
+
maxHeight: 'calc(100vh - 4rem)',
|
53
|
+
overflowY: 'auto',
|
54
|
+
}}
|
55
|
+
>
|
56
|
+
{Catalog.Versioned.is(catalog) && Schema.Versioned.is(schema) && (
|
57
|
+
<Box mb='3'>
|
58
|
+
<VersionPicker
|
59
|
+
versions={Catalog.Versioned.getVersions(catalog)}
|
60
|
+
currentVersion={schema.version}
|
61
|
+
onVersionChange={(newVersion) => {
|
62
|
+
navigate(`/changelog/version/${Version.encodeSync(newVersion)}`)
|
63
|
+
}}
|
64
|
+
/>
|
65
|
+
</Box>
|
66
|
+
)}
|
67
|
+
<Text size='2' weight='medium' mb='3' style={{ display: 'block' }}>
|
68
|
+
Revisions
|
69
|
+
</Text>
|
70
|
+
{revisions.map((revision) => (
|
71
|
+
<ChangelogSidebarItem
|
72
|
+
key={revision.date}
|
73
|
+
revision={revision}
|
74
|
+
isActive={activeRevision === revision.date}
|
75
|
+
/>
|
76
|
+
))}
|
77
|
+
</Swiss.Item>
|
78
|
+
)
|
79
|
+
}
|
80
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import { Change } from '#lib/change'
|
2
|
+
import { Revision } from '#lib/revision'
|
3
|
+
import { Box, Flex, Text } from '@radix-ui/themes'
|
4
|
+
import { renderDate } from './utils.js'
|
5
|
+
|
6
|
+
export const ChangelogSidebarItem: React.FC<{
|
7
|
+
revision: Revision.Revision
|
8
|
+
isActive: boolean
|
9
|
+
}> = ({ revision, isActive }) => {
|
10
|
+
const counts = calculateCounts(revision)
|
11
|
+
|
12
|
+
return (
|
13
|
+
<Box mb='2'>
|
14
|
+
<a
|
15
|
+
href={`#${revision.date}`}
|
16
|
+
style={{
|
17
|
+
textDecoration: 'none',
|
18
|
+
display: 'flex',
|
19
|
+
alignItems: 'center',
|
20
|
+
justifyContent: 'space-between',
|
21
|
+
padding: '0.5rem 0.75rem',
|
22
|
+
borderRadius: '4px',
|
23
|
+
backgroundColor: isActive ? 'var(--gray-a3)' : 'transparent',
|
24
|
+
color: 'inherit',
|
25
|
+
transition: 'background-color 0.2s',
|
26
|
+
}}
|
27
|
+
onClick={(e) => {
|
28
|
+
e.preventDefault()
|
29
|
+
// Update URL hash
|
30
|
+
window.history.pushState(null, '', `#${revision.date}`)
|
31
|
+
// Dispatch custom event for pushState
|
32
|
+
window.dispatchEvent(new Event('pushstate'))
|
33
|
+
// Smooth scroll to element
|
34
|
+
document.getElementById(revision.date)?.scrollIntoView({ behavior: 'smooth' })
|
35
|
+
}}
|
36
|
+
>
|
37
|
+
<Text size='2' weight={isActive ? 'medium' : 'regular'}>
|
38
|
+
{renderDate(revision.date)}
|
39
|
+
</Text>
|
40
|
+
<Flex gap='2' align='center'>
|
41
|
+
{counts.breaking > 0 && (
|
42
|
+
<Text size='1' weight='medium' style={{ color: '#ef4444' }}>
|
43
|
+
{counts.breaking}
|
44
|
+
</Text>
|
45
|
+
)}
|
46
|
+
{counts.dangerous > 0 && (
|
47
|
+
<Text size='1' weight='medium' style={{ color: '#f59e0b' }}>
|
48
|
+
{counts.dangerous}
|
49
|
+
</Text>
|
50
|
+
)}
|
51
|
+
{counts.safe > 0 && (
|
52
|
+
<Text size='1' weight='medium' style={{ color: '#10b981' }}>
|
53
|
+
{counts.safe}
|
54
|
+
</Text>
|
55
|
+
)}
|
56
|
+
</Flex>
|
57
|
+
</a>
|
58
|
+
</Box>
|
59
|
+
)
|
60
|
+
}
|
61
|
+
|
62
|
+
export const calculateCounts = (revision: Revision.Revision) => {
|
63
|
+
return {
|
64
|
+
breaking: revision.changes.filter(Change.isBreaking).length,
|
65
|
+
dangerous: revision.changes.filter(Change.isDangerous).length,
|
66
|
+
safe: revision.changes.filter(Change.isSafe).length,
|
67
|
+
}
|
68
|
+
}
|