polen 0.11.0-next.1 → 0.11.0-next.11
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/api.d.ts +2 -1
- package/build/api/api.d.ts.map +1 -1
- package/build/api/api.js +5 -1
- package/build/api/api.js.map +1 -1
- package/build/api/config/configurator.d.ts +35 -23
- package/build/api/config/configurator.d.ts.map +1 -1
- package/build/api/config/configurator.js +0 -6
- package/build/api/config/configurator.js.map +1 -1
- package/build/api/config/merge.d.ts.map +1 -1
- package/build/api/config/merge.js +0 -11
- package/build/api/config/merge.js.map +1 -1
- package/build/api/content/metadata.d.ts +8 -2
- package/build/api/content/metadata.d.ts.map +1 -1
- package/build/api/content/metadata.js +1 -1
- package/build/api/content/metadata.js.map +1 -1
- package/build/api/iso/$$.d.ts +2 -0
- package/build/api/iso/$$.d.ts.map +1 -0
- package/build/api/iso/$$.js +2 -0
- package/build/api/iso/$$.js.map +1 -0
- package/build/api/iso/$.d.ts +2 -0
- package/build/api/iso/$.d.ts.map +1 -0
- package/build/api/iso/$.js +2 -0
- package/build/api/iso/$.js.map +1 -0
- package/build/api/iso/schema/$$.d.ts +4 -0
- package/build/api/iso/schema/$$.d.ts.map +1 -0
- package/build/api/iso/schema/$$.js +3 -0
- package/build/api/iso/schema/$$.js.map +1 -0
- package/build/api/iso/schema/$.d.ts +2 -0
- package/build/api/iso/schema/$.d.ts.map +1 -0
- package/build/api/iso/schema/$.js +2 -0
- package/build/api/iso/schema/$.js.map +1 -0
- package/build/api/iso/schema/constants.d.ts +25 -0
- package/build/api/iso/schema/constants.d.ts.map +1 -0
- package/build/api/iso/schema/constants.js +42 -0
- package/build/api/iso/schema/constants.js.map +1 -0
- package/build/api/iso/schema/routing.d.ts +22 -0
- package/build/api/iso/schema/routing.d.ts.map +1 -0
- package/build/api/iso/schema/routing.js +39 -0
- package/build/api/iso/schema/routing.js.map +1 -0
- package/build/api/iso.d.ts +2 -0
- package/build/api/iso.d.ts.map +1 -0
- package/build/api/iso.js +2 -0
- package/build/api/iso.js.map +1 -0
- package/build/api/schema/data-sources/data-sources.d.ts +1 -0
- package/build/api/schema/data-sources/data-sources.d.ts.map +1 -1
- package/build/api/schema/data-sources/data-sources.js +1 -0
- package/build/api/schema/data-sources/data-sources.js.map +1 -1
- package/build/api/schema/data-sources/introspection/introspection.d.ts +83 -0
- package/build/api/schema/data-sources/introspection/introspection.d.ts.map +1 -0
- package/build/api/schema/data-sources/introspection/introspection.js +110 -0
- package/build/api/schema/data-sources/introspection/introspection.js.map +1 -0
- package/build/api/schema/metadata.d.ts +11 -3
- package/build/api/schema/metadata.d.ts.map +1 -1
- package/build/api/schema/metadata.js +1 -1
- package/build/api/schema/metadata.js.map +1 -1
- package/build/api/schema/read.d.ts +83 -9
- package/build/api/schema/read.d.ts.map +1 -1
- package/build/api/schema/read.js +15 -6
- package/build/api/schema/read.js.map +1 -1
- package/build/api/schema/schema.d.ts +3 -25
- package/build/api/schema/schema.d.ts.map +1 -1
- package/build/api/schema/schema.js +5 -42
- package/build/api/schema/schema.js.map +1 -1
- package/build/api/schema-source/schema-source.d.ts +1 -1
- package/build/api/schema-source/schema-source.d.ts.map +1 -1
- package/build/api/schema-source/schema-source.js.map +1 -1
- package/build/api/static/manifest.d.ts +1 -2
- package/build/api/static/manifest.d.ts.map +1 -1
- package/build/api/static/manifest.js +1 -1
- package/build/api/static/manifest.js.map +1 -1
- package/build/api/vite/plugins/build.d.ts.map +1 -1
- package/build/api/vite/plugins/build.js +3 -0
- package/build/api/vite/plugins/build.js.map +1 -1
- package/build/api/vite/plugins/core.d.ts.map +1 -1
- package/build/api/vite/plugins/core.js +11 -14
- package/build/api/vite/plugins/core.js.map +1 -1
- package/build/api/vite/plugins/main.d.ts.map +1 -1
- package/build/api/vite/plugins/main.js +1 -8
- package/build/api/vite/plugins/main.js.map +1 -1
- package/build/api/vite/plugins/schema-assets.d.ts.map +1 -1
- package/build/api/vite/plugins/schema-assets.js +52 -11
- package/build/api/vite/plugins/schema-assets.js.map +1 -1
- package/build/cli/commands/open.js +1 -1
- package/build/cli/commands/open.js.map +1 -1
- package/build/lib/grafaid/schema/schema.d.ts +1 -1
- package/build/lib/grafaid/schema/schema.d.ts.map +1 -1
- package/build/lib/grafaid/schema/schema.js +1 -1
- package/build/lib/grafaid/schema/schema.js.map +1 -1
- package/build/lib/kit-temp.js +2 -2
- package/build/lib/kit-temp.js.map +1 -1
- package/build/lib/react-router-aid/react-router-aid.d.ts +5 -3
- package/build/lib/react-router-aid/react-router-aid.d.ts.map +1 -1
- package/build/lib/react-router-aid/react-router-aid.js +7 -4
- package/build/lib/react-router-aid/react-router-aid.js.map +1 -1
- package/build/template/components/GraphQLInteractive/lib/parser.d.ts.map +1 -1
- package/build/template/components/GraphQLInteractive/lib/parser.js +32 -10
- package/build/template/components/GraphQLInteractive/lib/parser.js.map +1 -1
- package/build/template/components/HamburgerMenu.d.ts +1 -0
- package/build/template/components/HamburgerMenu.d.ts.map +1 -1
- package/build/template/components/HamburgerMenu.js +2 -2
- package/build/template/components/HamburgerMenu.js.map +1 -1
- package/build/template/components/ReferenceLink.d.ts.map +1 -1
- package/build/template/components/ReferenceLink.js +2 -4
- package/build/template/components/ReferenceLink.js.map +1 -1
- package/build/template/components/VersionSelector.d.ts +3 -2
- package/build/template/components/VersionSelector.d.ts.map +1 -1
- package/build/template/components/VersionSelector.js +7 -15
- package/build/template/components/VersionSelector.js.map +1 -1
- package/build/template/components/sidebar/Sidebar.d.ts +3 -2
- package/build/template/components/sidebar/Sidebar.d.ts.map +1 -1
- package/build/template/components/sidebar/Sidebar.js +7 -6
- package/build/template/components/sidebar/Sidebar.js.map +1 -1
- package/build/template/components/sidebar/SidebarContext.d.ts +6 -0
- package/build/template/components/sidebar/SidebarContext.d.ts.map +1 -0
- package/build/template/components/sidebar/SidebarContext.js +3 -0
- package/build/template/components/sidebar/SidebarContext.js.map +1 -0
- package/build/template/components/sidebar/SidebarItem.d.ts.map +1 -1
- package/build/template/components/sidebar/SidebarItem.js +11 -4
- package/build/template/components/sidebar/SidebarItem.js.map +1 -1
- package/build/template/hooks/useVersionPath.d.ts.map +1 -1
- package/build/template/hooks/useVersionPath.js +3 -1
- package/build/template/hooks/useVersionPath.js.map +1 -1
- package/build/template/layouts/SidebarLayout.d.ts +3 -2
- package/build/template/layouts/SidebarLayout.d.ts.map +1 -1
- package/build/template/layouts/SidebarLayout.js +2 -2
- package/build/template/layouts/SidebarLayout.js.map +1 -1
- package/build/template/routes/changelog.js +2 -2
- package/build/template/routes/changelog.js.map +1 -1
- package/build/template/routes/index.js +2 -2
- package/build/template/routes/index.js.map +1 -1
- package/build/template/routes/pages.js +2 -2
- package/build/template/routes/pages.js.map +1 -1
- package/build/template/routes/reference.d.ts +27 -4
- package/build/template/routes/reference.d.ts.map +1 -1
- package/build/template/routes/reference.js +82 -24
- package/build/template/routes/reference.js.map +1 -1
- package/build/template/routes/root.js +3 -3
- package/build/template/routes/root.js.map +1 -1
- package/build/template/server/ssg/get-route-paths.d.ts.map +1 -1
- package/build/template/server/ssg/get-route-paths.js +81 -9
- package/build/template/server/ssg/get-route-paths.js.map +1 -1
- package/build/template/sources/schema-source.d.ts +1 -1
- package/build/template/sources/schema-source.d.ts.map +1 -1
- package/build/template/sources/schema-source.js +2 -1
- package/build/template/sources/schema-source.js.map +1 -1
- package/package.json +19 -17
- package/src/api/api.ts +7 -1
- package/src/api/config/configurator.ts +35 -30
- package/src/api/config/merge.ts +0 -16
- package/src/api/content/metadata.ts +1 -1
- package/src/api/iso/$$.ts +1 -0
- package/src/api/iso/$.ts +1 -0
- package/src/api/iso/schema/$$.ts +5 -0
- package/src/api/iso/schema/$.ts +1 -0
- package/src/api/iso/schema/constants.ts +49 -0
- package/src/api/iso/schema/routing.ts +53 -0
- package/src/api/iso.ts +1 -0
- package/src/api/schema/data-sources/data-sources.ts +1 -0
- package/src/api/schema/data-sources/introspection/introspection.ts +213 -0
- package/src/api/schema/metadata.ts +1 -1
- package/src/api/schema/read.ts +107 -16
- package/src/api/schema/schema.ts +6 -53
- package/src/api/schema-source/schema-source.ts +3 -3
- package/src/api/static/manifest.ts +1 -1
- package/src/api/vite/plugins/build.ts +3 -0
- package/src/api/vite/plugins/core.ts +11 -14
- package/src/api/vite/plugins/main.ts +1 -9
- package/src/api/vite/plugins/schema-assets.ts +59 -12
- package/src/cli/commands/open.ts +1 -1
- package/src/lib/grafaid/schema/schema.ts +1 -0
- package/src/lib/kit-temp.ts +2 -2
- package/src/lib/mask/$.test.ts +3 -3
- package/src/lib/react-router-aid/react-router-aid.ts +12 -6
- package/src/template/components/GraphQLInteractive/lib/parser.ts +32 -16
- package/src/template/components/HamburgerMenu.tsx +3 -1
- package/src/template/components/ReferenceLink.tsx +7 -4
- package/src/template/components/VersionSelector.tsx +10 -18
- package/src/template/components/sidebar/Sidebar.tsx +20 -16
- package/src/template/components/sidebar/SidebarContext.tsx +7 -0
- package/src/template/components/sidebar/SidebarItem.tsx +11 -4
- package/src/template/hooks/useVersionPath.ts +3 -1
- package/src/template/layouts/SidebarLayout.tsx +5 -3
- package/src/template/routes/changelog.tsx +2 -2
- package/src/template/routes/index.tsx +2 -2
- package/src/template/routes/pages.tsx +2 -2
- package/src/template/routes/reference.tsx +90 -25
- package/src/template/routes/root.tsx +3 -3
- package/src/template/server/ssg/get-route-paths.test.ts +145 -0
- package/src/template/server/ssg/get-route-paths.ts +80 -9
- package/src/template/sources/schema-source.ts +2 -1
- package/build/template/lib/schema-utils/constants.d.ts +0 -5
- package/build/template/lib/schema-utils/constants.d.ts.map +0 -1
- package/build/template/lib/schema-utils/constants.js +0 -5
- package/build/template/lib/schema-utils/constants.js.map +0 -1
- package/build/template/routes/reference.$type.$field.d.ts +0 -5
- package/build/template/routes/reference.$type.$field.d.ts.map +0 -1
- package/build/template/routes/reference.$type.$field.js +0 -31
- package/build/template/routes/reference.$type.$field.js.map +0 -1
- package/build/template/routes/reference.$type.d.ts +0 -9
- package/build/template/routes/reference.$type.d.ts.map +0 -1
- package/build/template/routes/reference.$type.js +0 -25
- package/build/template/routes/reference.$type.js.map +0 -1
- package/build/template/routes/reference.version.$version.$type.$field.d.ts +0 -6
- package/build/template/routes/reference.version.$version.$type.$field.d.ts.map +0 -1
- package/build/template/routes/reference.version.$version.$type.$field.js +0 -32
- package/build/template/routes/reference.version.$version.$type.$field.js.map +0 -1
- package/build/template/routes/reference.version.$version.$type.d.ts +0 -11
- package/build/template/routes/reference.version.$version.$type.d.ts.map +0 -1
- package/build/template/routes/reference.version.$version.$type.js +0 -26
- package/build/template/routes/reference.version.$version.$type.js.map +0 -1
- package/src/template/lib/schema-utils/constants.ts +0 -4
- package/src/template/routes/reference.$type.$field.tsx +0 -34
- package/src/template/routes/reference.$type.tsx +0 -29
- package/src/template/routes/reference.version.$version.$type.$field.tsx +0 -35
- package/src/template/routes/reference.version.$version.$type.tsx +0 -30
package/src/api/schema/schema.ts
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
import type { GraphqlChangeset } from '#lib/graphql-changeset/index'
|
2
2
|
|
3
|
-
export
|
4
|
-
|
5
|
-
export * from '
|
3
|
+
// Re-export everything from isomorphic layer
|
4
|
+
export * from '../iso/schema/constants.js'
|
5
|
+
export * as Routing from '../iso/schema/routing.js'
|
6
6
|
|
7
|
+
// Server-only exports
|
8
|
+
export * as DataSources from './data-sources/data-sources.js'
|
7
9
|
export * from './metadata.js'
|
10
|
+
export * from './read.js'
|
8
11
|
|
9
12
|
export type ChangeSets = GraphqlChangeset.ChangeSet[]
|
10
13
|
|
@@ -17,53 +20,3 @@ export interface ChangelogData {
|
|
17
20
|
changes: GraphqlChangeset.ChangeSet['changes']
|
18
21
|
date: string
|
19
22
|
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Constants for schema versioning
|
23
|
-
*/
|
24
|
-
|
25
|
-
/**
|
26
|
-
* The version identifier for the latest schema
|
27
|
-
*/
|
28
|
-
export const VERSION_LATEST = `latest`
|
29
|
-
|
30
|
-
/**
|
31
|
-
* Fallback version name when date parsing fails
|
32
|
-
*/
|
33
|
-
export const VERSION_UNKNOWN_FALLBACK = `unknown`
|
34
|
-
|
35
|
-
/**
|
36
|
-
* Convert a date to a version string in YYYY-MM-DD format
|
37
|
-
*/
|
38
|
-
export const dateToVersionString = (date: Date): string => {
|
39
|
-
return date.toLocaleDateString('en-CA')
|
40
|
-
}
|
41
|
-
|
42
|
-
/**
|
43
|
-
* Determine if a version at the given index should have a changelog file.
|
44
|
-
* Only non-oldest versions get changelog files.
|
45
|
-
*/
|
46
|
-
export const shouldVersionHaveChangelog = (versionIndex: number, totalVersions: number): boolean => {
|
47
|
-
return versionIndex < totalVersions - 1
|
48
|
-
}
|
49
|
-
|
50
|
-
/**
|
51
|
-
* Convert a version string back to a Date
|
52
|
-
*/
|
53
|
-
export const versionStringToDate = (version: string): Date => {
|
54
|
-
if (version === VERSION_LATEST) {
|
55
|
-
return new Date()
|
56
|
-
}
|
57
|
-
|
58
|
-
// Use modern date parsing - the version string should be in YYYY-MM-DD format
|
59
|
-
// which is ISO 8601 compatible
|
60
|
-
const parsedDate = new Date(version + 'T00:00:00Z')
|
61
|
-
|
62
|
-
// Check if the date is valid
|
63
|
-
if (!isNaN(parsedDate.getTime())) {
|
64
|
-
return parsedDate
|
65
|
-
}
|
66
|
-
|
67
|
-
// Throw error for invalid dates instead of silently defaulting
|
68
|
-
throw new Error(`Invalid version string: ${version}`)
|
69
|
-
}
|
@@ -157,13 +157,13 @@ export const createSchemaSource = (config: SchemaSourceConfig) => {
|
|
157
157
|
},
|
158
158
|
|
159
159
|
writeAllAssets: async (
|
160
|
-
schemaData: Awaited<ReturnType<typeof Schema.readOrThrow
|
160
|
+
schemaData: Awaited<ReturnType<typeof Schema.readOrThrow>>['data'],
|
161
161
|
metadata: Schema.SchemaMetadata,
|
162
162
|
) => {
|
163
163
|
if (!schemaData) return
|
164
164
|
|
165
165
|
// Write schema and changelog files
|
166
|
-
for (const [index, version] of schemaData
|
166
|
+
for (const [index, version] of schemaData!.entries()) {
|
167
167
|
const versionName = index === 0 ? Schema.VERSION_LATEST : Schema.dateToVersionString(version.date)
|
168
168
|
|
169
169
|
// Write schema file
|
@@ -173,7 +173,7 @@ export const createSchemaSource = (config: SchemaSourceConfig) => {
|
|
173
173
|
)
|
174
174
|
|
175
175
|
// Write changelog file (except for the oldest/last version)
|
176
|
-
if (Schema.shouldVersionHaveChangelog(index, schemaData
|
176
|
+
if (Schema.shouldVersionHaveChangelog(index, schemaData!.length)) {
|
177
177
|
const changelogData = {
|
178
178
|
changes: version.changes,
|
179
179
|
date: version.date.toISOString(),
|
@@ -75,6 +75,9 @@ export const Build = (config: Config.Config): Vite.Plugin[] => {
|
|
75
75
|
// @see https://github.com/vitejs/vite/issues/20098
|
76
76
|
ssr: {
|
77
77
|
noExternal: true,
|
78
|
+
// Exclude lightningcss from bundling due to native bindings
|
79
|
+
// @see https://github.com/parcel-bundler/lightningcss/issues/701
|
80
|
+
external: ['lightningcss'],
|
78
81
|
},
|
79
82
|
environments: {
|
80
83
|
ssr: {
|
@@ -1,22 +1,18 @@
|
|
1
1
|
import type { Config } from '#api/config/index'
|
2
2
|
import { Content } from '#api/content/$'
|
3
3
|
import { createNavbar } from '#api/content/navbar'
|
4
|
+
import { Api } from '#api/index'
|
4
5
|
import { VitePluginSelfContainedMode } from '#cli/_/self-contained-mode'
|
5
|
-
import { Hono } from '#dep/hono/index'
|
6
6
|
import type { ReactRouter } from '#dep/react-router/index'
|
7
7
|
import type { Vite } from '#dep/vite/index'
|
8
8
|
import { VitePluginJson } from '#lib/vite-plugin-json/index'
|
9
9
|
import { ViteVirtual } from '#lib/vite-virtual/index'
|
10
10
|
import { debugPolen } from '#singletons/debug'
|
11
11
|
import { superjson } from '#singletons/superjson'
|
12
|
-
import * as HonoNodeServer from '@hono/node-server'
|
13
|
-
import { serveStatic } from '@hono/node-server/serve-static'
|
14
12
|
import { Json, Str } from '@wollybeard/kit'
|
15
|
-
import * as NodePath from 'node:path'
|
16
13
|
import type { ProjectData } from '../../../project-data.js'
|
17
14
|
import { SchemaAugmentation } from '../../schema-augmentation/index.js'
|
18
15
|
import { Schema } from '../../schema/index.js'
|
19
|
-
import { createLogger } from '../logger.js'
|
20
16
|
import { polenVirtual } from '../vi.js'
|
21
17
|
import { Pages } from './pages.js'
|
22
18
|
import { SchemaAssets } from './schema-assets.js'
|
@@ -35,15 +31,15 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
35
31
|
|
36
32
|
const readSchema = async () => {
|
37
33
|
if (schemaCache === null) {
|
38
|
-
const
|
34
|
+
const schemaResult = await Schema.readOrThrow({
|
39
35
|
...config.schema,
|
40
36
|
projectRoot: config.paths.project.rootDir,
|
41
37
|
})
|
42
38
|
// todo: augmentations scoped to a version
|
43
|
-
|
39
|
+
schemaResult.data?.forEach(version => {
|
44
40
|
SchemaAugmentation.apply(version.after, config.schemaAugmentations)
|
45
41
|
})
|
46
|
-
schemaCache =
|
42
|
+
schemaCache = schemaResult
|
47
43
|
}
|
48
44
|
return schemaCache
|
49
45
|
}
|
@@ -166,8 +162,8 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
166
162
|
const debug = debugPolen.sub(`module-project-schema`)
|
167
163
|
debug(`load`, { id: viProjectSchema.id })
|
168
164
|
|
169
|
-
const
|
170
|
-
return superjson.stringify(
|
165
|
+
const schemaResult = await readSchema()
|
166
|
+
return superjson.stringify(schemaResult.data)
|
171
167
|
},
|
172
168
|
},
|
173
169
|
{
|
@@ -191,18 +187,19 @@ export const Core = (config: Config.Config): Vite.PluginOption[] => {
|
|
191
187
|
|
192
188
|
debug(`load`, { id: viProjectData.id })
|
193
189
|
|
194
|
-
const
|
190
|
+
const schemaResult = await readSchema()
|
195
191
|
|
196
192
|
const navbar = []
|
197
193
|
|
198
194
|
// ━ Schema presence causes adding some navbar items
|
199
|
-
if (
|
195
|
+
if (schemaResult.data) {
|
200
196
|
// IMPORTANT: Always ensure paths start with '/' for React Router compatibility.
|
201
197
|
// Without the leading slash, React Router treats paths as relative, which causes
|
202
198
|
// hydration mismatches between SSR (where base path is prepended) and client
|
203
199
|
// (where basename is configured). This ensures consistent behavior.
|
204
|
-
|
205
|
-
|
200
|
+
const referencePath = Api.Schema.Routing.createReferenceBasePath()
|
201
|
+
navbar.push({ pathExp: referencePath, title: `Reference` })
|
202
|
+
if (schemaResult.data.length > 1) {
|
206
203
|
navbar.push({ pathExp: `/changelog`, title: `Changelog` })
|
207
204
|
}
|
208
205
|
}
|
@@ -2,9 +2,8 @@ import type { Config } from '#api/config/index'
|
|
2
2
|
import type { Vite } from '#dep/vite/index'
|
3
3
|
import { vitePluginSsrCss } from '@hiogawa/vite-plugin-ssr-css'
|
4
4
|
import ViteReact from '@vitejs/plugin-react-oxc'
|
5
|
-
import {
|
5
|
+
import { Path } from '@wollybeard/kit'
|
6
6
|
import Inspect from 'vite-plugin-inspect'
|
7
|
-
import Restart from 'vite-plugin-restart'
|
8
7
|
import { Branding } from './branding.js'
|
9
8
|
import { Build } from './build.js'
|
10
9
|
import { Core } from './core.js'
|
@@ -26,13 +25,6 @@ export const Main = (
|
|
26
25
|
plugins.push(plugin)
|
27
26
|
}
|
28
27
|
|
29
|
-
if (Arr.isntEmpty(config.watch.also)) {
|
30
|
-
const plugin = Restart({
|
31
|
-
restart: config.watch.also,
|
32
|
-
})
|
33
|
-
plugins.push(plugin)
|
34
|
-
}
|
35
|
-
|
36
28
|
plugins.push(
|
37
29
|
ViteReact(),
|
38
30
|
vitePluginSsrCss({
|
@@ -9,6 +9,7 @@ import { debugPolen } from '#singletons/debug'
|
|
9
9
|
import { Cache } from '@wollybeard/kit'
|
10
10
|
import * as NodeFs from 'node:fs/promises'
|
11
11
|
import * as NodePath from 'node:path'
|
12
|
+
import type { NonEmptyChangeSets } from '../../schema/schema.js'
|
12
13
|
import { polenVirtual } from '../vi.js'
|
13
14
|
|
14
15
|
export const viProjectSchemaMetadata = polenVirtual([`project`, `schema-metadata`])
|
@@ -35,27 +36,28 @@ export const SchemaAssets = (config: Config.Config): Vite.Plugin => {
|
|
35
36
|
|
36
37
|
// Helper to load and process schema data
|
37
38
|
const loadAndProcessSchemaData = Cache.memoize(async () => {
|
38
|
-
const
|
39
|
+
const schemaResult = await Schema.readOrThrow({
|
39
40
|
...config.schema,
|
40
41
|
projectRoot: config.paths.project.rootDir,
|
41
42
|
})
|
42
43
|
|
43
|
-
if (!
|
44
|
+
if (!schemaResult.data) {
|
44
45
|
const metadata: Schema.SchemaMetadata = { hasSchema: false, versions: [] }
|
45
46
|
return {
|
46
47
|
schemaData: null,
|
47
48
|
metadata,
|
49
|
+
source: schemaResult.source,
|
48
50
|
}
|
49
51
|
}
|
50
52
|
|
51
53
|
// Apply augmentations
|
52
|
-
|
54
|
+
schemaResult.data.forEach(version => {
|
53
55
|
SchemaAugmentation.apply(version.after, config.schemaAugmentations)
|
54
56
|
})
|
55
57
|
|
56
58
|
// Build metadata
|
57
59
|
const versionStrings: string[] = []
|
58
|
-
for (const [index, version] of
|
60
|
+
for (const [index, version] of schemaResult.data.entries()) {
|
59
61
|
const versionName = index === 0 ? Schema.VERSION_LATEST : Schema.dateToVersionString(version.date)
|
60
62
|
versionStrings.push(versionName)
|
61
63
|
}
|
@@ -65,11 +67,12 @@ export const SchemaAssets = (config: Config.Config): Vite.Plugin => {
|
|
65
67
|
versions: versionStrings,
|
66
68
|
}
|
67
69
|
|
68
|
-
debug(`schemaDataLoaded`, { versionCount:
|
70
|
+
debug(`schemaDataLoaded`, { versionCount: schemaResult.data.length })
|
69
71
|
|
70
72
|
return {
|
71
|
-
schemaData,
|
73
|
+
schemaData: schemaResult.data,
|
72
74
|
metadata,
|
75
|
+
source: schemaResult.source,
|
73
76
|
}
|
74
77
|
})
|
75
78
|
|
@@ -102,10 +105,10 @@ export const SchemaAssets = (config: Config.Config): Vite.Plugin => {
|
|
102
105
|
|
103
106
|
// Helper to write assets using schema-source API
|
104
107
|
const writeDevAssets = async (
|
105
|
-
schemaData:
|
108
|
+
schemaData: NonEmptyChangeSets,
|
106
109
|
metadata: Schema.SchemaMetadata,
|
107
110
|
) => {
|
108
|
-
|
111
|
+
// schemaData is now guaranteed to be non-null NonEmptyChangeSets
|
109
112
|
|
110
113
|
const devAssetsDir = config.paths.framework.devAssets.schemas
|
111
114
|
await NodeFs.mkdir(devAssetsDir, { recursive: true })
|
@@ -149,6 +152,13 @@ export const SchemaAssets = (config: Config.Config): Vite.Plugin => {
|
|
149
152
|
debug(`watchingSchemaFile`, { path: config.schema.dataSources.file.path })
|
150
153
|
}
|
151
154
|
|
155
|
+
if (config.schema?.dataSources?.introspection?.url) {
|
156
|
+
// Watch the introspection file if introspection is configured
|
157
|
+
const introspectionFilePath = NodePath.join(config.paths.project.rootDir, `schema.introspection.json`)
|
158
|
+
server.watcher.add(introspectionFilePath)
|
159
|
+
debug(`watchingIntrospectionFile`, { path: introspectionFilePath })
|
160
|
+
}
|
161
|
+
|
152
162
|
// Handle file removal
|
153
163
|
server.watcher.on('unlink', async (file) => {
|
154
164
|
const isSchemaFile = config.schema && (() => {
|
@@ -172,6 +182,15 @@ export const SchemaAssets = (config: Config.Config): Vite.Plugin => {
|
|
172
182
|
if (absoluteFile.startsWith(absoluteSchemaDir + NodePath.sep)) return true
|
173
183
|
}
|
174
184
|
|
185
|
+
// Check if file is the introspection file
|
186
|
+
if (config.schema.dataSources?.introspection?.url) {
|
187
|
+
const absoluteIntrospectionFile = NodePath.resolve(
|
188
|
+
config.paths.project.rootDir,
|
189
|
+
`schema.introspection.json`,
|
190
|
+
)
|
191
|
+
if (absoluteFile === absoluteIntrospectionFile) return true
|
192
|
+
}
|
193
|
+
|
175
194
|
return false
|
176
195
|
})()
|
177
196
|
|
@@ -181,14 +200,33 @@ export const SchemaAssets = (config: Config.Config): Vite.Plugin => {
|
|
181
200
|
try {
|
182
201
|
// Clear cache and regenerate
|
183
202
|
loadAndProcessSchemaData.clear()
|
184
|
-
const { schemaData, metadata } = await loadAndProcessSchemaData()
|
185
|
-
|
186
|
-
|
203
|
+
const { schemaData, metadata, source } = await loadAndProcessSchemaData()
|
204
|
+
|
205
|
+
// If file was deleted but can be recreated, attempt recreation
|
206
|
+
if (!schemaData && source.reCreate) {
|
207
|
+
debug(`attemptingSchemaRecreation`, { sourceType: source.type })
|
208
|
+
try {
|
209
|
+
const recreatedData = await source.reCreate()
|
210
|
+
if (recreatedData) {
|
211
|
+
// Clear cache again and reload after recreation
|
212
|
+
loadAndProcessSchemaData.clear()
|
213
|
+
const reloadResult = await loadAndProcessSchemaData()
|
214
|
+
if (reloadResult.schemaData) {
|
215
|
+
await writeDevAssets(reloadResult.schemaData, reloadResult.metadata)
|
216
|
+
debug(`hmr:schemaRecreatedAndWritten`, { versionCount: reloadResult.schemaData.length })
|
217
|
+
}
|
218
|
+
} else {
|
219
|
+
debug(`hmr:schemaRecreationFailed`, { reason: 'reCreate returned null' })
|
220
|
+
}
|
221
|
+
} catch (recreationError) {
|
222
|
+
debug(`hmr:schemaRecreationFailed`, { error: recreationError })
|
223
|
+
}
|
224
|
+
} else if (schemaData) {
|
187
225
|
// Write new assets without the removed file
|
188
226
|
await writeDevAssets(schemaData, metadata)
|
189
227
|
debug(`hmr:schemaAssetsUpdatedAfterRemoval`, { versionCount: schemaData.length })
|
190
228
|
} else {
|
191
|
-
// No schema data - clear all assets
|
229
|
+
// No schema data and cannot recreate - clear all assets
|
192
230
|
const schemaSource = createDevSchemaSource({ hasSchema: false, versions: [] })
|
193
231
|
await schemaSource.clearAllAssets()
|
194
232
|
debug(`hmr:allAssetsCleared`, {})
|
@@ -274,6 +312,15 @@ export const SchemaAssets = (config: Config.Config): Vite.Plugin => {
|
|
274
312
|
if (absoluteFile.startsWith(absoluteSchemaDir + NodePath.sep)) return true
|
275
313
|
}
|
276
314
|
|
315
|
+
// Check if file is the introspection file
|
316
|
+
if (config.schema.dataSources?.introspection?.url) {
|
317
|
+
const absoluteIntrospectionFile = NodePath.resolve(
|
318
|
+
config.paths.project.rootDir,
|
319
|
+
`schema.introspection.json`,
|
320
|
+
)
|
321
|
+
if (absoluteFile === absoluteIntrospectionFile) return true
|
322
|
+
}
|
323
|
+
|
277
324
|
return false
|
278
325
|
})()
|
279
326
|
if (isSchemaFile) {
|
package/src/cli/commands/open.ts
CHANGED
@@ -132,7 +132,7 @@ const wrapCache = <fn extends Fn.AnyAnyAsync>(fn: fn): fn => {
|
|
132
132
|
|
133
133
|
// todo: use a proper validation, e.g. zod, better yet: allow to specify the validation in molt itself
|
134
134
|
const parseHeaders = (headersJsonEncoded: string): Record<string, string> => {
|
135
|
-
const headersJson = Json.codec.
|
135
|
+
const headersJson = Json.codec.decode(headersJsonEncoded)
|
136
136
|
if (!Rec.is(headersJson)) {
|
137
137
|
console.log(`--introspection-headers must be a JSON object.`)
|
138
138
|
process.exit(1)
|
package/src/lib/kit-temp.ts
CHANGED
@@ -105,9 +105,9 @@ export const objPolicyFilter = <
|
|
105
105
|
const result: any = mode === `deny` ? { ...obj } : {}
|
106
106
|
|
107
107
|
if (mode === `allow`) {
|
108
|
-
// For allow mode, only add specified keys
|
108
|
+
// For allow mode, only add specified keys that are own properties
|
109
109
|
for (const key of keys) {
|
110
|
-
if (key
|
110
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
111
111
|
// @ts-expect-error
|
112
112
|
result[key] = obj[key]
|
113
113
|
}
|
package/src/lib/mask/$.test.ts
CHANGED
@@ -113,9 +113,9 @@ describe('property-based tests', () => {
|
|
113
113
|
// Result contains only keys that were in both mask and object
|
114
114
|
expect(resultKeys.every(key => keys.includes(key))).toBe(true)
|
115
115
|
|
116
|
-
// All requested keys that
|
116
|
+
// All requested keys that are own properties of obj are in result
|
117
117
|
keys.forEach(key => {
|
118
|
-
if (key
|
118
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
119
119
|
expect(result).toHaveProperty(key, (obj as any)[key])
|
120
120
|
}
|
121
121
|
})
|
@@ -169,7 +169,7 @@ describe('property-based tests', () => {
|
|
169
169
|
const result = Mask.apply(obj as any, Mask.create(keys))
|
170
170
|
|
171
171
|
keys.forEach(key => {
|
172
|
-
if (key
|
172
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
173
173
|
expect(result).toHaveProperty(key)
|
174
174
|
expect((result as any)[key]).toBe((obj as any)[key])
|
175
175
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import type { ReactRouter } from '#dep/react-router/index'
|
2
|
+
import type { React } from '#dep/react/index'
|
2
3
|
import type { Http } from '@wollybeard/kit'
|
3
4
|
|
4
5
|
export * from './get-paths-patterns.js'
|
@@ -18,23 +19,28 @@ export interface RouteHandle {
|
|
18
19
|
statusCode?: Http.Status.Code.All
|
19
20
|
}
|
20
21
|
|
21
|
-
export const
|
22
|
+
export const route = <routeObject extends RouteObject>(
|
22
23
|
routeObject: routeObject,
|
23
24
|
): routeObject => {
|
24
25
|
return {
|
25
|
-
id: routeObject.path,
|
26
26
|
...routeObject,
|
27
27
|
}
|
28
28
|
}
|
29
29
|
|
30
|
-
export type RouteObjectIndexInput =
|
30
|
+
export type RouteObjectIndexInput = RouteObjectIndexInputConfig | React.ComponentType
|
31
|
+
export type RouteObjectIndexInputConfig = Omit<RouteObjectIndex, `index` | `children`>
|
31
32
|
|
32
|
-
export const
|
33
|
-
|
33
|
+
export const routeIndex = (
|
34
|
+
input: RouteObjectIndexInput,
|
34
35
|
): RouteObjectIndex => {
|
36
|
+
const routeConfig: RouteObjectIndexInputConfig = isComponentType(input) ? { Component: input } : input
|
35
37
|
return {
|
36
|
-
...
|
38
|
+
...routeConfig,
|
37
39
|
index: true,
|
38
40
|
children: undefined,
|
39
41
|
}
|
40
42
|
}
|
43
|
+
|
44
|
+
const isComponentType = (value: unknown): value is React.ComponentType => {
|
45
|
+
return typeof value === 'function'
|
46
|
+
}
|
@@ -5,6 +5,7 @@
|
|
5
5
|
* analysis to create unified tokens for interactive code blocks.
|
6
6
|
*/
|
7
7
|
|
8
|
+
import { Api } from '#api/iso'
|
8
9
|
import type { CodeAnnotation } from 'codehike/code'
|
9
10
|
import {
|
10
11
|
getNamedType,
|
@@ -14,7 +15,6 @@ import {
|
|
14
15
|
GraphQLInputObjectType,
|
15
16
|
GraphQLInterfaceType,
|
16
17
|
GraphQLObjectType,
|
17
|
-
type GraphQLOutputType,
|
18
18
|
GraphQLScalarType,
|
19
19
|
type GraphQLSchema,
|
20
20
|
GraphQLUnionType,
|
@@ -24,12 +24,7 @@ import {
|
|
24
24
|
import graphqlWasmUrl from 'tree-sitter-graphql-grammar-wasm/grammar.wasm?url'
|
25
25
|
import * as WebTreeSitter from 'web-tree-sitter'
|
26
26
|
import treeSitterWasmUrl from 'web-tree-sitter/tree-sitter.wasm?url'
|
27
|
-
import {
|
28
|
-
isKeywordNodeType,
|
29
|
-
isLiteralNodeType,
|
30
|
-
isPunctuationNodeType,
|
31
|
-
type TreeSitterGraphQLNodeType,
|
32
|
-
} from './graphql-node-types.js'
|
27
|
+
import { isKeywordNodeType, isPunctuationNodeType, type TreeSitterGraphQLNodeType } from './graphql-node-types.js'
|
33
28
|
import type { SemanticNode } from './semantic-nodes.js'
|
34
29
|
import {
|
35
30
|
isArgument,
|
@@ -263,42 +258,63 @@ class UnifiedToken implements GraphQLToken {
|
|
263
258
|
|
264
259
|
// Arguments - use #<field>__<argument> pattern
|
265
260
|
if (isArgument(this.semantic)) {
|
266
|
-
|
261
|
+
const basePath = Api.Schema.Routing.createReferencePath({
|
262
|
+
type: this.semantic.parentType.name,
|
263
|
+
})
|
264
|
+
return `${basePath}#${this.semantic.parentField.name}__${this.semantic.argumentDef.name}`
|
267
265
|
}
|
268
266
|
|
269
267
|
// Output fields - use hash links since field routes aren't connected yet
|
270
268
|
if (isOutputField(this.semantic)) {
|
271
|
-
|
269
|
+
const basePath = Api.Schema.Routing.createReferencePath({
|
270
|
+
type: this.semantic.parentType.name,
|
271
|
+
})
|
272
|
+
return `${basePath}#${this.semantic.fieldDef.name}`
|
272
273
|
}
|
273
274
|
|
274
275
|
// Input fields - use hash links since field routes aren't connected yet
|
275
276
|
if (isInputField(this.semantic)) {
|
276
|
-
|
277
|
+
const basePath = Api.Schema.Routing.createReferencePath({
|
278
|
+
type: this.semantic.parentType.name,
|
279
|
+
})
|
280
|
+
return `${basePath}#${this.semantic.fieldDef.name}`
|
277
281
|
}
|
278
282
|
|
279
283
|
// Type references - use :type pattern
|
280
284
|
if (this.semantic instanceof GraphQLObjectType) {
|
281
|
-
return
|
285
|
+
return Api.Schema.Routing.createReferencePath({
|
286
|
+
type: this.semantic.name,
|
287
|
+
})
|
282
288
|
}
|
283
289
|
|
284
290
|
if (this.semantic instanceof GraphQLScalarType) {
|
285
|
-
return
|
291
|
+
return Api.Schema.Routing.createReferencePath({
|
292
|
+
type: this.semantic.name,
|
293
|
+
})
|
286
294
|
}
|
287
295
|
|
288
296
|
if (this.semantic instanceof GraphQLInterfaceType) {
|
289
|
-
return
|
297
|
+
return Api.Schema.Routing.createReferencePath({
|
298
|
+
type: this.semantic.name,
|
299
|
+
})
|
290
300
|
}
|
291
301
|
|
292
302
|
if (this.semantic instanceof GraphQLUnionType) {
|
293
|
-
return
|
303
|
+
return Api.Schema.Routing.createReferencePath({
|
304
|
+
type: this.semantic.name,
|
305
|
+
})
|
294
306
|
}
|
295
307
|
|
296
308
|
if (this.semantic instanceof GraphQLEnumType) {
|
297
|
-
return
|
309
|
+
return Api.Schema.Routing.createReferencePath({
|
310
|
+
type: this.semantic.name,
|
311
|
+
})
|
298
312
|
}
|
299
313
|
|
300
314
|
if (this.semantic instanceof GraphQLInputObjectType) {
|
301
|
-
return
|
315
|
+
return Api.Schema.Routing.createReferencePath({
|
316
|
+
type: this.semantic.name,
|
317
|
+
})
|
302
318
|
}
|
303
319
|
|
304
320
|
return null
|
@@ -9,6 +9,7 @@ export interface HamburgerMenuProps {
|
|
9
9
|
onToggle: () => void
|
10
10
|
onClose: () => void
|
11
11
|
sidebarData: Content.Item[]
|
12
|
+
basePath?: string
|
12
13
|
}
|
13
14
|
|
14
15
|
export const HamburgerMenu: React.FC<HamburgerMenuProps> = ({
|
@@ -16,6 +17,7 @@ export const HamburgerMenu: React.FC<HamburgerMenuProps> = ({
|
|
16
17
|
onToggle,
|
17
18
|
onClose,
|
18
19
|
sidebarData,
|
20
|
+
basePath,
|
19
21
|
}) => {
|
20
22
|
// Prevent body scroll when mobile menu is open
|
21
23
|
useEffect(() => {
|
@@ -87,7 +89,7 @@ export const HamburgerMenu: React.FC<HamburgerMenuProps> = ({
|
|
87
89
|
<Cross2Icon width='18' height='18' />
|
88
90
|
</IconButton>
|
89
91
|
</Flex>
|
90
|
-
<Sidebar data={sidebarData} />
|
92
|
+
<Sidebar data={sidebarData} basePath={basePath} />
|
91
93
|
</Box>
|
92
94
|
</>
|
93
95
|
)}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { Api } from '#api/iso'
|
1
2
|
import type { ReactNode } from 'react'
|
2
3
|
import { useVersionPath } from '../hooks/useVersionPath.js'
|
3
4
|
import { Link } from './Link.js'
|
@@ -21,10 +22,12 @@ interface Props {
|
|
21
22
|
export const ReferenceLink = ({ type, field, children }: Props) => {
|
22
23
|
const versionPath = useVersionPath()
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
const path = Api.Schema.Routing.joinSegmentsAndPaths(
|
26
|
+
Api.Schema.Routing.segmentLiterals.reference,
|
27
|
+
versionPath,
|
28
|
+
type,
|
29
|
+
field,
|
30
|
+
)
|
28
31
|
|
29
32
|
return (
|
30
33
|
<Link to={path}>
|
@@ -1,13 +1,14 @@
|
|
1
|
+
import { Api } from '#api/iso'
|
2
|
+
import type { React } from '#dep/react/index'
|
1
3
|
import { Select } from '@radix-ui/themes'
|
2
4
|
import { useNavigate, useParams } from 'react-router'
|
3
|
-
import { VERSION_LATEST } from '../lib/schema-utils/constants.js'
|
4
5
|
|
5
|
-
interface
|
6
|
+
interface Props {
|
6
7
|
availableVersions: string[]
|
7
8
|
currentVersion: string
|
8
9
|
}
|
9
10
|
|
10
|
-
export const VersionSelector = ({ availableVersions, currentVersion }
|
11
|
+
export const VersionSelector: React.FC<Props> = ({ availableVersions, currentVersion }) => {
|
11
12
|
const navigate = useNavigate()
|
12
13
|
const params = useParams()
|
13
14
|
|
@@ -17,20 +18,11 @@ export const VersionSelector = ({ availableVersions, currentVersion }: VersionSe
|
|
17
18
|
}
|
18
19
|
|
19
20
|
const handleVersionChange = (newVersion: string) => {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
if (newVersion !== VERSION_LATEST) {
|
26
|
-
newPath += `/version/${newVersion}`
|
27
|
-
}
|
28
|
-
if (currentType) {
|
29
|
-
newPath += `/${currentType}`
|
30
|
-
if (currentField) {
|
31
|
-
newPath += `/${currentField}`
|
32
|
-
}
|
33
|
-
}
|
21
|
+
const newPath = Api.Schema.Routing.createReferencePath({
|
22
|
+
version: newVersion,
|
23
|
+
type: params[`type`],
|
24
|
+
field: params[`field`],
|
25
|
+
})
|
34
26
|
|
35
27
|
navigate(newPath)
|
36
28
|
}
|
@@ -41,7 +33,7 @@ export const VersionSelector = ({ availableVersions, currentVersion }: VersionSe
|
|
41
33
|
<Select.Content>
|
42
34
|
{availableVersions.map(version => (
|
43
35
|
<Select.Item key={version} value={version}>
|
44
|
-
{version === VERSION_LATEST ? `Latest` : version}
|
36
|
+
{version === Api.Schema.VERSION_LATEST ? `Latest` : version}
|
45
37
|
</Select.Item>
|
46
38
|
))}
|
47
39
|
</Select.Content>
|