polen 0.11.0-next.3 → 0.11.0-next.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"get-route-paths.d.ts","sourceRoot":"","sources":["../../../../src/template/server/ssg/get-route-paths.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,MAAM,EAAE,CA+DvD,CAAA"}
1
+ {"version":3,"file":"get-route-paths.d.ts","sourceRoot":"","sources":["../../../../src/template/server/ssg/get-route-paths.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,cAAc,QAAa,OAAO,CAAC,MAAM,EAAE,CAkGvD,CAAA"}
@@ -10,23 +10,40 @@ import { routes } from '../../routes.js';
10
10
  // Maybe we can figure something out too.
11
11
  const knownParameterizedRouteExpressions = {
12
12
  reference_type: `/reference/:type`,
13
+ reference_type_field: `/reference/:type/:field`,
14
+ reference_version: `/reference/version/:version`,
13
15
  reference_versioned_type: `/reference/version/:version/:type`,
16
+ reference_versioned_type_field: `/reference/version/:version/:type/:field`,
14
17
  };
15
18
  export const getRoutesPaths = async () => {
16
19
  const paths = new Set();
17
20
  const routeExpressions = ReactRouterAid.getRouteExpressions(routes);
18
21
  // Helper function to load schema from filesystem and add type paths
19
- const addTypePathsForVersion = async (version, pathPrefix) => {
22
+ const addTypePathsForVersion = async (version, pathPrefix, includeFields = false) => {
20
23
  try {
21
24
  const schemaFilePath = NodePath.join(PROJECT_DATA.paths.project.absolute.build.assets.schemas, `${version}.json`);
22
25
  const schemaContent = await NodeFs.readFile(schemaFilePath, 'utf-8');
23
26
  const schemaAst = JSON.parse(schemaContent);
24
27
  visit(schemaAst, {
25
28
  ObjectTypeDefinition(node) {
26
- paths.add(`${pathPrefix}/${node.name.value}`);
29
+ const typePath = `${pathPrefix}/${node.name.value}`;
30
+ paths.add(typePath);
31
+ // Add field paths if requested
32
+ if (includeFields && node.fields) {
33
+ for (const field of node.fields) {
34
+ paths.add(`${typePath}/${field.name.value}`);
35
+ }
36
+ }
27
37
  },
28
38
  InterfaceTypeDefinition(node) {
29
- paths.add(`${pathPrefix}/${node.name.value}`);
39
+ const typePath = `${pathPrefix}/${node.name.value}`;
40
+ paths.add(typePath);
41
+ // Add field paths if requested
42
+ if (includeFields && node.fields) {
43
+ for (const field of node.fields) {
44
+ paths.add(`${typePath}/${field.name.value}`);
45
+ }
46
+ }
30
47
  },
31
48
  EnumTypeDefinition(node) {
32
49
  paths.add(`${pathPrefix}/${node.name.value}`);
@@ -56,6 +73,20 @@ export const getRoutesPaths = async () => {
56
73
  await addTypePathsForVersion(Api.Schema.VERSION_LATEST, `/reference`);
57
74
  }
58
75
  }
76
+ else if (exp === knownParameterizedRouteExpressions.reference_version) {
77
+ if (hasSchema) {
78
+ // Add paths for version pages themselves (without type)
79
+ for (const version of availableVersions) {
80
+ paths.add(`/reference/version/${version}`);
81
+ }
82
+ }
83
+ }
84
+ else if (exp === knownParameterizedRouteExpressions.reference_type_field) {
85
+ if (hasSchema) {
86
+ // Add paths for latest version fields
87
+ await addTypePathsForVersion(Api.Schema.VERSION_LATEST, `/reference`, true);
88
+ }
89
+ }
59
90
  else if (exp === knownParameterizedRouteExpressions.reference_versioned_type) {
60
91
  if (hasSchema) {
61
92
  // Add paths for all versions using new route structure
@@ -64,6 +95,14 @@ export const getRoutesPaths = async () => {
64
95
  }
65
96
  }
66
97
  }
98
+ else if (exp === knownParameterizedRouteExpressions.reference_versioned_type_field) {
99
+ if (hasSchema) {
100
+ // Add paths for all versions with fields
101
+ for (const version of availableVersions) {
102
+ await addTypePathsForVersion(version, `/reference/version/${version}`, true);
103
+ }
104
+ }
105
+ }
67
106
  else if (ReactRouterAid.isParameterizedPath(exp)) {
68
107
  throw new Error(`Unhandled parameterized path: ${exp}`);
69
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"get-route-paths.js","sourceRoot":"","sources":["../../../../src/template/server/ssg/get-route-paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"get-route-paths.js","sourceRoot":"","sources":["../../../../src/template/server/ssg/get-route-paths.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polen",
3
- "version": "0.11.0-next.3",
3
+ "version": "0.11.0-next.4",
4
4
  "type": "module",
5
5
  "description": "A framework for delightful GraphQL developer portals",
6
6
  "author": {
@@ -0,0 +1,132 @@
1
+ import { beforeEach, describe, expect, test, vi } from 'vitest'
2
+
3
+ // Mock node:fs/promises
4
+ vi.mock('node:fs/promises', () => ({
5
+ readFile: vi.fn(),
6
+ }))
7
+
8
+ // Mock the virtual import
9
+ vi.mock('virtual:polen/project/data.jsonsuper', () => ({
10
+ default: {
11
+ paths: {
12
+ project: {
13
+ absolute: {
14
+ build: {
15
+ assets: {
16
+ schemas: '/mock/schemas',
17
+ },
18
+ },
19
+ },
20
+ },
21
+ },
22
+ },
23
+ }))
24
+
25
+ // Mock the routes
26
+ vi.mock('../../routes.js', () => ({
27
+ routes: [
28
+ {
29
+ path: 'reference',
30
+ children: [
31
+ {
32
+ path: 'version/:version',
33
+ children: [
34
+ {
35
+ path: ':type',
36
+ },
37
+ ],
38
+ },
39
+ {
40
+ path: ':type',
41
+ },
42
+ ],
43
+ },
44
+ ],
45
+ }))
46
+
47
+ // Mock the API
48
+ vi.mock('#api/index', () => ({
49
+ Api: {
50
+ Schema: {
51
+ getMetadata: vi.fn(),
52
+ VERSION_LATEST: 'latest',
53
+ },
54
+ },
55
+ }))
56
+
57
+ describe('getRoutesPaths', () => {
58
+ beforeEach(() => {
59
+ vi.resetAllMocks()
60
+ })
61
+
62
+ test('should handle versioned routes without type parameter', async () => {
63
+ // Mock schema metadata
64
+ const { Api } = await import('#api/index')
65
+ vi.mocked(Api.Schema.getMetadata).mockResolvedValue({
66
+ hasSchema: true,
67
+ versions: ['2024-01-01', '2024-02-01'],
68
+ })
69
+
70
+ // Mock file system reads with proper GraphQL AST
71
+ const NodeFs = await import('node:fs/promises')
72
+ vi.mocked(NodeFs.readFile).mockImplementation(async (path) => {
73
+ if (typeof path === 'string' && path.includes('.json')) {
74
+ // Return a minimal GraphQL document AST
75
+ return JSON.stringify({
76
+ kind: 'Document',
77
+ definitions: [],
78
+ })
79
+ }
80
+ throw new Error(`Unexpected file read: ${path}`)
81
+ })
82
+
83
+ const { getRoutesPaths } = await import('./get-route-paths.js')
84
+
85
+ // This should not throw "Unhandled parameterized path: /reference/version/:version"
86
+ await expect(getRoutesPaths()).resolves.toBeDefined()
87
+ })
88
+
89
+ test('should generate paths for all schema versions', async () => {
90
+ const { Api } = await import('#api/index')
91
+ vi.mocked(Api.Schema.getMetadata).mockResolvedValue({
92
+ hasSchema: true,
93
+ versions: ['2024-01-01', '2024-02-01'],
94
+ })
95
+
96
+ // Mock schema with types - proper GraphQL AST
97
+ const mockSchema = {
98
+ kind: 'Document',
99
+ definitions: [
100
+ {
101
+ kind: 'ObjectTypeDefinition',
102
+ name: { kind: 'Name', value: 'User' },
103
+ },
104
+ {
105
+ kind: 'ObjectTypeDefinition',
106
+ name: { kind: 'Name', value: 'Post' },
107
+ },
108
+ ],
109
+ }
110
+
111
+ const NodeFs = await import('node:fs/promises')
112
+ vi.mocked(NodeFs.readFile).mockImplementation(async (path) => {
113
+ if (typeof path === 'string' && path.includes('.json')) {
114
+ return JSON.stringify(mockSchema)
115
+ }
116
+ throw new Error(`Unexpected file read: ${path}`)
117
+ })
118
+
119
+ const { getRoutesPaths } = await import('./get-route-paths.js')
120
+ const paths = await getRoutesPaths()
121
+
122
+ // Should include versioned paths
123
+ expect(paths).toContain('/reference/version/2024-01-01/User')
124
+ expect(paths).toContain('/reference/version/2024-01-01/Post')
125
+ expect(paths).toContain('/reference/version/2024-02-01/User')
126
+ expect(paths).toContain('/reference/version/2024-02-01/Post')
127
+
128
+ // Should include unversioned paths
129
+ expect(paths).toContain('/reference/User')
130
+ expect(paths).toContain('/reference/Post')
131
+ })
132
+ })
@@ -11,7 +11,10 @@ import { routes } from '../../routes.js'
11
11
  // Maybe we can figure something out too.
12
12
  const knownParameterizedRouteExpressions = {
13
13
  reference_type: `/reference/:type`,
14
+ reference_type_field: `/reference/:type/:field`,
15
+ reference_version: `/reference/version/:version`,
14
16
  reference_versioned_type: `/reference/version/:version/:type`,
17
+ reference_versioned_type_field: `/reference/version/:version/:type/:field`,
15
18
  }
16
19
 
17
20
  export const getRoutesPaths = async (): Promise<string[]> => {
@@ -19,7 +22,7 @@ export const getRoutesPaths = async (): Promise<string[]> => {
19
22
  const routeExpressions = ReactRouterAid.getRouteExpressions(routes)
20
23
 
21
24
  // Helper function to load schema from filesystem and add type paths
22
- const addTypePathsForVersion = async (version: string, pathPrefix: string) => {
25
+ const addTypePathsForVersion = async (version: string, pathPrefix: string, includeFields = false) => {
23
26
  try {
24
27
  const schemaFilePath = NodePath.join(PROJECT_DATA.paths.project.absolute.build.assets.schemas, `${version}.json`)
25
28
  const schemaContent = await NodeFs.readFile(schemaFilePath, 'utf-8')
@@ -27,10 +30,26 @@ export const getRoutesPaths = async (): Promise<string[]> => {
27
30
 
28
31
  visit(schemaAst, {
29
32
  ObjectTypeDefinition(node) {
30
- paths.add(`${pathPrefix}/${node.name.value}`)
33
+ const typePath = `${pathPrefix}/${node.name.value}`
34
+ paths.add(typePath)
35
+
36
+ // Add field paths if requested
37
+ if (includeFields && node.fields) {
38
+ for (const field of node.fields) {
39
+ paths.add(`${typePath}/${field.name.value}`)
40
+ }
41
+ }
31
42
  },
32
43
  InterfaceTypeDefinition(node) {
33
- paths.add(`${pathPrefix}/${node.name.value}`)
44
+ const typePath = `${pathPrefix}/${node.name.value}`
45
+ paths.add(typePath)
46
+
47
+ // Add field paths if requested
48
+ if (includeFields && node.fields) {
49
+ for (const field of node.fields) {
50
+ paths.add(`${typePath}/${field.name.value}`)
51
+ }
52
+ }
34
53
  },
35
54
  EnumTypeDefinition(node) {
36
55
  paths.add(`${pathPrefix}/${node.name.value}`)
@@ -61,6 +80,18 @@ export const getRoutesPaths = async (): Promise<string[]> => {
61
80
  // Add paths for latest version (no version in URL)
62
81
  await addTypePathsForVersion(Api.Schema.VERSION_LATEST, `/reference`)
63
82
  }
83
+ } else if (exp === knownParameterizedRouteExpressions.reference_version) {
84
+ if (hasSchema) {
85
+ // Add paths for version pages themselves (without type)
86
+ for (const version of availableVersions) {
87
+ paths.add(`/reference/version/${version}`)
88
+ }
89
+ }
90
+ } else if (exp === knownParameterizedRouteExpressions.reference_type_field) {
91
+ if (hasSchema) {
92
+ // Add paths for latest version fields
93
+ await addTypePathsForVersion(Api.Schema.VERSION_LATEST, `/reference`, true)
94
+ }
64
95
  } else if (exp === knownParameterizedRouteExpressions.reference_versioned_type) {
65
96
  if (hasSchema) {
66
97
  // Add paths for all versions using new route structure
@@ -68,6 +99,13 @@ export const getRoutesPaths = async (): Promise<string[]> => {
68
99
  await addTypePathsForVersion(version, `/reference/version/${version}`)
69
100
  }
70
101
  }
102
+ } else if (exp === knownParameterizedRouteExpressions.reference_versioned_type_field) {
103
+ if (hasSchema) {
104
+ // Add paths for all versions with fields
105
+ for (const version of availableVersions) {
106
+ await addTypePathsForVersion(version, `/reference/version/${version}`, true)
107
+ }
108
+ }
71
109
  } else if (ReactRouterAid.isParameterizedPath(exp)) {
72
110
  throw new Error(`Unhandled parameterized path: ${exp}`)
73
111
  } else {