@pattern-stack/frontend-patterns 0.2.0-alpha.1 → 0.2.0-alpha.12

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.
Files changed (170) hide show
  1. package/dist/atoms/components/core/Badge/Badge.d.ts +1 -1
  2. package/dist/atoms/components/data/DataTable/ColumnFilterDropdown.d.ts +32 -0
  3. package/dist/atoms/components/data/DataTable/ColumnFilterDropdown.d.ts.map +1 -0
  4. package/dist/atoms/components/data/DataTable/ColumnVisibilityToggle.d.ts +32 -0
  5. package/dist/atoms/components/data/DataTable/ColumnVisibilityToggle.d.ts.map +1 -0
  6. package/dist/atoms/components/data/DataTable/DataTable.d.ts +5 -2
  7. package/dist/atoms/components/data/DataTable/DataTable.d.ts.map +1 -1
  8. package/dist/atoms/components/data/DataTable/DataTable.expansion.d.ts +91 -0
  9. package/dist/atoms/components/data/DataTable/DataTable.expansion.d.ts.map +1 -0
  10. package/dist/atoms/components/data/DataTable/DataTable.filters.d.ts +271 -0
  11. package/dist/atoms/components/data/DataTable/DataTable.filters.d.ts.map +1 -0
  12. package/dist/atoms/components/data/DataTable/DataTable.types.d.ts +155 -5
  13. package/dist/atoms/components/data/DataTable/DataTable.types.d.ts.map +1 -1
  14. package/dist/atoms/components/data/DataTable/ExpandButton.d.ts +37 -0
  15. package/dist/atoms/components/data/DataTable/ExpandButton.d.ts.map +1 -0
  16. package/dist/atoms/components/data/DataTable/FilterPill.d.ts +25 -0
  17. package/dist/atoms/components/data/DataTable/FilterPill.d.ts.map +1 -0
  18. package/dist/atoms/components/data/DataTable/QuickFilterBar.d.ts +35 -0
  19. package/dist/atoms/components/data/DataTable/QuickFilterBar.d.ts.map +1 -0
  20. package/dist/atoms/components/data/DataTable/filters/BooleanFilterEditor.d.ts +10 -0
  21. package/dist/atoms/components/data/DataTable/filters/BooleanFilterEditor.d.ts.map +1 -0
  22. package/dist/atoms/components/data/DataTable/filters/DateFilterEditor.d.ts +11 -0
  23. package/dist/atoms/components/data/DataTable/filters/DateFilterEditor.d.ts.map +1 -0
  24. package/dist/atoms/components/data/DataTable/filters/MultiSelectFilterEditor.d.ts +10 -0
  25. package/dist/atoms/components/data/DataTable/filters/MultiSelectFilterEditor.d.ts.map +1 -0
  26. package/dist/atoms/components/data/DataTable/filters/NumberFilterEditor.d.ts +10 -0
  27. package/dist/atoms/components/data/DataTable/filters/NumberFilterEditor.d.ts.map +1 -0
  28. package/dist/atoms/components/data/DataTable/filters/SelectFilterEditor.d.ts +10 -0
  29. package/dist/atoms/components/data/DataTable/filters/SelectFilterEditor.d.ts.map +1 -0
  30. package/dist/atoms/components/data/DataTable/filters/TextFilterEditor.d.ts +10 -0
  31. package/dist/atoms/components/data/DataTable/filters/TextFilterEditor.d.ts.map +1 -0
  32. package/dist/atoms/components/data/DataTable/filters/index.d.ts +14 -0
  33. package/dist/atoms/components/data/DataTable/filters/index.d.ts.map +1 -0
  34. package/dist/atoms/components/data/DataTable/index.d.ts +9 -0
  35. package/dist/atoms/components/data/DataTable/index.d.ts.map +1 -1
  36. package/dist/atoms/components/data/ProgressBar/ProgressBar.d.ts +1 -1
  37. package/dist/atoms/components/data/ProgressBar/ProgressBar.d.ts.map +1 -1
  38. package/dist/atoms/components/data/index.d.ts +3 -2
  39. package/dist/atoms/components/data/index.d.ts.map +1 -1
  40. package/dist/atoms/composed/ConnectionStatus/ConnectionStatus.d.ts +16 -0
  41. package/dist/atoms/composed/ConnectionStatus/ConnectionStatus.d.ts.map +1 -0
  42. package/dist/atoms/composed/ConnectionStatus/index.d.ts +3 -0
  43. package/dist/atoms/composed/ConnectionStatus/index.d.ts.map +1 -0
  44. package/dist/atoms/hooks/index.d.ts +9 -0
  45. package/dist/atoms/hooks/index.d.ts.map +1 -1
  46. package/dist/atoms/hooks/useAdaptiveTable.d.ts +49 -0
  47. package/dist/atoms/hooks/useAdaptiveTable.d.ts.map +1 -0
  48. package/dist/atoms/hooks/useApi.d.ts +1 -1
  49. package/dist/atoms/hooks/useApi.d.ts.map +1 -1
  50. package/dist/atoms/hooks/useColumnVisibility.d.ts +75 -0
  51. package/dist/atoms/hooks/useColumnVisibility.d.ts.map +1 -0
  52. package/dist/atoms/hooks/useEntityData.d.ts +36 -0
  53. package/dist/atoms/hooks/useEntityData.d.ts.map +1 -0
  54. package/dist/atoms/hooks/useEntityDetail.d.ts +43 -0
  55. package/dist/atoms/hooks/useEntityDetail.d.ts.map +1 -0
  56. package/dist/atoms/hooks/useExpandedRows.d.ts +66 -0
  57. package/dist/atoms/hooks/useExpandedRows.d.ts.map +1 -0
  58. package/dist/atoms/hooks/useFieldMetadata.d.ts +18 -0
  59. package/dist/atoms/hooks/useFieldMetadata.d.ts.map +1 -0
  60. package/dist/atoms/hooks/useOnlineStatus.d.ts +16 -0
  61. package/dist/atoms/hooks/useOnlineStatus.d.ts.map +1 -0
  62. package/dist/atoms/hooks/useResponsiveTable.d.ts +123 -0
  63. package/dist/atoms/hooks/useResponsiveTable.d.ts.map +1 -0
  64. package/dist/atoms/hooks/useTableFilters.d.ts +92 -0
  65. package/dist/atoms/hooks/useTableFilters.d.ts.map +1 -0
  66. package/dist/atoms/index.d.ts +1 -0
  67. package/dist/atoms/index.d.ts.map +1 -1
  68. package/dist/atoms/primitives/sheet.d.ts +23 -0
  69. package/dist/atoms/primitives/sheet.d.ts.map +1 -0
  70. package/dist/atoms/primitives/table.d.ts.map +1 -1
  71. package/dist/atoms/services/api/client.d.ts +12 -2
  72. package/dist/atoms/services/api/client.d.ts.map +1 -1
  73. package/dist/atoms/services/auth-service.d.ts +15 -0
  74. package/dist/atoms/services/auth-service.d.ts.map +1 -1
  75. package/dist/atoms/services/index.d.ts +2 -2
  76. package/dist/atoms/services/index.d.ts.map +1 -1
  77. package/dist/atoms/shared/config/table-config.d.ts +79 -0
  78. package/dist/atoms/shared/config/table-config.d.ts.map +1 -0
  79. package/dist/atoms/shared/index.d.ts +1 -0
  80. package/dist/atoms/shared/index.d.ts.map +1 -1
  81. package/dist/atoms/types/auth.d.ts +95 -2
  82. package/dist/atoms/types/auth.d.ts.map +1 -1
  83. package/dist/atoms/types/index.d.ts +1 -0
  84. package/dist/atoms/types/index.d.ts.map +1 -1
  85. package/dist/atoms/types/navigation.d.ts +1 -1
  86. package/dist/atoms/types/navigation.d.ts.map +1 -1
  87. package/dist/atoms/types/ui-config.d.ts +46 -11
  88. package/dist/atoms/types/ui-config.d.ts.map +1 -1
  89. package/dist/atoms/types/ui-metadata.d.ts +103 -0
  90. package/dist/atoms/types/ui-metadata.d.ts.map +1 -0
  91. package/dist/atoms/utils/entity-card-mapping.d.ts +105 -0
  92. package/dist/atoms/utils/entity-card-mapping.d.ts.map +1 -0
  93. package/dist/atoms/utils/field-detection.d.ts +2 -2
  94. package/dist/atoms/utils/field-detection.d.ts.map +1 -1
  95. package/dist/atoms/utils/icon-map.d.ts +48 -0
  96. package/dist/atoms/utils/icon-map.d.ts.map +1 -1
  97. package/dist/atoms/utils/index.d.ts +2 -0
  98. package/dist/atoms/utils/index.d.ts.map +1 -1
  99. package/dist/atoms/utils/ui-mapping.d.ts +9 -3
  100. package/dist/atoms/utils/ui-mapping.d.ts.map +1 -1
  101. package/dist/features/auth/components/ProtectedRoute.d.ts +3 -1
  102. package/dist/features/auth/components/ProtectedRoute.d.ts.map +1 -1
  103. package/dist/features/auth/hooks/useAuth.d.ts.map +1 -1
  104. package/dist/features/auth/providers/NoAuthProvider.d.ts +17 -0
  105. package/dist/features/auth/providers/NoAuthProvider.d.ts.map +1 -0
  106. package/dist/features/auth/providers/index.d.ts +1 -0
  107. package/dist/features/auth/providers/index.d.ts.map +1 -1
  108. package/dist/frontend-patterns.css +1 -4554
  109. package/dist/index.d.ts +12 -4
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.es.js +8816 -18278
  112. package/dist/index.es.js.map +1 -1
  113. package/dist/index.js +8813 -18274
  114. package/dist/index.js.map +1 -1
  115. package/dist/molecules/layout/AppHeader/AppHeader.d.ts +19 -3
  116. package/dist/molecules/layout/AppHeader/AppHeader.d.ts.map +1 -1
  117. package/dist/molecules/layout/AppHeader/index.d.ts +1 -1
  118. package/dist/molecules/layout/AppHeader/index.d.ts.map +1 -1
  119. package/dist/molecules/layout/AppLayout.d.ts +12 -1
  120. package/dist/molecules/layout/AppLayout.d.ts.map +1 -1
  121. package/dist/molecules/layout/BulkSelectionBar.d.ts +14 -2
  122. package/dist/molecules/layout/BulkSelectionBar.d.ts.map +1 -1
  123. package/dist/molecules/layout/FieldGrid/FieldGrid.d.ts +61 -0
  124. package/dist/molecules/layout/FieldGrid/FieldGrid.d.ts.map +1 -0
  125. package/dist/molecules/layout/FieldGrid/index.d.ts +2 -0
  126. package/dist/molecules/layout/FieldGrid/index.d.ts.map +1 -0
  127. package/dist/molecules/layout/ListToolbar/ListToolbar.d.ts +37 -0
  128. package/dist/molecules/layout/ListToolbar/ListToolbar.d.ts.map +1 -0
  129. package/dist/molecules/layout/ListToolbar/index.d.ts +2 -0
  130. package/dist/molecules/layout/ListToolbar/index.d.ts.map +1 -0
  131. package/dist/molecules/layout/PageTitle/PageTitle.d.ts +17 -0
  132. package/dist/molecules/layout/PageTitle/PageTitle.d.ts.map +1 -0
  133. package/dist/molecules/layout/PageTitle/index.d.ts +2 -0
  134. package/dist/molecules/layout/PageTitle/index.d.ts.map +1 -0
  135. package/dist/molecules/layout/index.d.ts +5 -2
  136. package/dist/molecules/layout/index.d.ts.map +1 -1
  137. package/dist/molecules/layout/navigation-context.d.ts.map +1 -1
  138. package/dist/sync/EntityStoreProvider.d.ts +35 -0
  139. package/dist/sync/EntityStoreProvider.d.ts.map +1 -0
  140. package/dist/sync/createEntityHooks.d.ts +29 -0
  141. package/dist/sync/createEntityHooks.d.ts.map +1 -0
  142. package/dist/sync/createStore.d.ts +65 -0
  143. package/dist/sync/createStore.d.ts.map +1 -0
  144. package/dist/sync/index.d.ts +6 -0
  145. package/dist/sync/index.d.ts.map +1 -0
  146. package/dist/sync/types.d.ts +383 -0
  147. package/dist/sync/types.d.ts.map +1 -0
  148. package/dist/templates/ListPageTemplate.d.ts +21 -0
  149. package/dist/templates/ListPageTemplate.d.ts.map +1 -0
  150. package/dist/templates/admin/AdminCRUDTemplate.d.ts.map +1 -1
  151. package/dist/templates/factory.d.ts +20 -0
  152. package/dist/templates/factory.d.ts.map +1 -1
  153. package/dist/templates/index.d.ts +1 -0
  154. package/dist/templates/index.d.ts.map +1 -1
  155. package/package.json +11 -7
  156. package/cli/commands/generate-hooks.ts +0 -325
  157. package/cli/commands/init.ts +0 -33
  158. package/cli/commands/scaffold.ts +0 -224
  159. package/cli/index.ts +0 -122
  160. package/cli/src/codegen/openapi/__tests__/naming-utils.test.js +0 -367
  161. package/cli/src/codegen/openapi/client-generator.js +0 -727
  162. package/cli/src/codegen/openapi/confidence-scorer.js +0 -93
  163. package/cli/src/codegen/openapi/hook-config.js +0 -48
  164. package/cli/src/codegen/openapi/hook-generator.js +0 -763
  165. package/cli/src/codegen/openapi/naming-constants.js +0 -98
  166. package/cli/src/codegen/openapi/naming-utils.js +0 -149
  167. package/cli/src/codegen/openapi/parser.js +0 -274
  168. package/cli/src/codegen/openapi/type-generator.js +0 -329
  169. package/dist/codegen/openapi/bulk-types.d.ts +0 -142
  170. package/dist/codegen/openapi/bulk-types.d.ts.map +0 -1
@@ -1,325 +0,0 @@
1
- /**
2
- * Generate Hooks Command
3
- *
4
- * Implementation of the `pattern-stack generate hooks` command
5
- *
6
- * Part of FRO-6: Generate Hooks Command
7
- */
8
-
9
- import { promises as fs } from 'fs'
10
- import { join, dirname } from 'path'
11
- import { fileURLToPath } from 'url'
12
- import { loadOpenAPISpec, parseOpenAPI } from '../../src/codegen/openapi/parser.js'
13
- import { generateTypes } from '../../src/codegen/openapi/type-generator.js'
14
- import { generateAPIClient } from '../../src/codegen/openapi/client-generator.js'
15
- import { generateHooks } from '../../src/codegen/openapi/hook-generator.js'
16
-
17
- const __filename = fileURLToPath(import.meta.url)
18
- const __dirname = dirname(__filename)
19
-
20
- interface GenerateHooksOptions {
21
- output: string
22
- prefix?: string
23
- client: 'axios' | 'fetch'
24
- auth: 'bearer' | 'apiKey' | 'basic'
25
- dryRun?: boolean
26
- }
27
-
28
- export async function generateHooksCommand(source: string, options: GenerateHooksOptions) {
29
- try {
30
- console.log('🚀 Pattern-Stack Hook Generator')
31
- console.log('================================')
32
- console.log()
33
-
34
- // Load and parse OpenAPI specification
35
- console.log('📥 Loading OpenAPI specification...')
36
- const spec = await loadOpenAPISpec(source)
37
- console.log(`✅ Loaded: ${spec.info.title} v${spec.info.version}`)
38
-
39
- console.log('🔍 Parsing specification...')
40
- const parsed = await parseOpenAPI(spec)
41
- console.log(`✅ Found ${parsed.endpoints.length} endpoints, ${parsed.schemas.length} schemas`)
42
-
43
- // Generate types
44
- console.log('🏗️ Generating TypeScript types...')
45
- const types = generateTypes(parsed, {
46
- prefix: options.prefix,
47
- includeJSDoc: true,
48
- includeExamples: true
49
- })
50
-
51
- // Generate API client
52
- console.log('🔧 Generating API client...')
53
- const client = generateAPIClient(parsed, {
54
- clientType: options.client,
55
- includeAuth: true,
56
- authType: options.auth,
57
- includeInterceptors: true
58
- })
59
-
60
- // Generate React hooks
61
- console.log('⚛️ Generating React hooks...')
62
- const hooks = await generateHooks(parsed, {
63
- includeInfiniteQueries: true,
64
- includeOptimisticUpdates: true,
65
- includeMutationHelpers: true,
66
- enableConfidenceScoring: true
67
- })
68
-
69
- if (options.dryRun) {
70
- console.log('\n📋 Dry run - files that would be generated:')
71
- console.log('Types:')
72
- console.log(' - schemas.ts')
73
- console.log(' - endpoints.ts')
74
- console.log(' - parameters.ts')
75
- console.log(' - responses.ts')
76
- console.log()
77
- console.log('API Client:')
78
- console.log(' - client.ts')
79
- console.log(' - methods.ts')
80
- console.log(' - types.ts')
81
- console.log(' - config.ts')
82
- console.log()
83
- console.log('React Hooks:')
84
- console.log(' - queries.ts')
85
- console.log(' - mutations.ts')
86
- console.log(' - keys.ts')
87
- console.log(' - types.ts')
88
- console.log()
89
- console.log('Generated code preview:')
90
- console.log('======================')
91
- console.log()
92
- console.log('Types (first 20 lines):')
93
- console.log(types.schemas.split('\n').slice(0, 20).join('\n'))
94
- console.log('\n...')
95
- return
96
- }
97
-
98
- // Create output directories
99
- console.log(`📁 Creating output directory: ${options.output}`)
100
- await ensureDir(options.output)
101
- await ensureDir(join(options.output, 'types'))
102
- await ensureDir(join(options.output, 'client'))
103
- await ensureDir(join(options.output, 'hooks'))
104
-
105
- // Write type files
106
- console.log('💾 Writing type definitions...')
107
- await writeFile(join(options.output, 'types', 'schemas.ts'), types.schemas)
108
- await writeFile(join(options.output, 'types', 'endpoints.ts'), types.endpoints)
109
- await writeFile(join(options.output, 'types', 'parameters.ts'), types.parameters)
110
- await writeFile(join(options.output, 'types', 'responses.ts'), types.responses)
111
- await writeFile(join(options.output, 'types', 'index.ts'), types.index)
112
-
113
- // Write client files
114
- console.log('💾 Writing API client...')
115
- await writeFile(join(options.output, 'client', 'client.ts'), client.client)
116
- await writeFile(join(options.output, 'client', 'methods.ts'), client.methods)
117
- await writeFile(join(options.output, 'client', 'types.ts'), client.types)
118
- await writeFile(join(options.output, 'client', 'config.ts'), client.config)
119
- await writeFile(join(options.output, 'client', 'index.ts'), client.index)
120
-
121
- // Write hook files
122
- console.log('💾 Writing React hooks...')
123
- await writeFile(join(options.output, 'hooks', 'queries.ts'), hooks.queries)
124
- await writeFile(join(options.output, 'hooks', 'mutations.ts'), hooks.mutations)
125
- await writeFile(join(options.output, 'hooks', 'keys.ts'), hooks.keys)
126
- await writeFile(join(options.output, 'hooks', 'types.ts'), hooks.types)
127
- await writeFile(join(options.output, 'hooks', 'index.ts'), hooks.index)
128
-
129
- // Copy bulk-types.ts to output directory (referenced by hooks/types.ts)
130
- const bulkTypesPath = join(__dirname, '../../src/codegen/openapi/bulk-types.ts')
131
- const bulkTypesContent = await fs.readFile(bulkTypesPath, 'utf8')
132
- await writeFile(join(options.output, 'bulk-types.ts'), bulkTypesContent)
133
-
134
- // Write confidence report if available
135
- if (hooks.report) {
136
- await writeFile(join(options.output, 'hooks', 'confidence-report.md'), hooks.report)
137
- console.log('📊 Generated confidence report')
138
-
139
- // Check if there are low confidence names
140
- const lowConfidenceCount = (hooks.report.match(/## Low Confidence Names/g) || []).length
141
- if (lowConfidenceCount > 0) {
142
- console.log('\n⚠️ Some hook names have low confidence and may need review.')
143
- console.log('Run `npm run review:hooks` to interactively review and improve them.')
144
- }
145
- }
146
-
147
- // Write main index file
148
- const mainIndex = `/**
149
- * Generated API Integration
150
- *
151
- * Auto-generated from OpenAPI specification: ${spec.info.title}
152
- * Version: ${spec.info.version}
153
- * Generated: ${new Date().toISOString()}
154
- */
155
-
156
- export * from './types'
157
- export * from './client'
158
- export * from './hooks'
159
-
160
- // Quick start exports
161
- export { createAPIClient } from './client'
162
- export { queryKeys } from './hooks'`
163
-
164
- await writeFile(join(options.output, 'index.ts'), mainIndex)
165
-
166
- // Generate usage example (as .tsx since it contains JSX)
167
- const usageExample = generateUsageExample(spec.info.title, options)
168
- await writeFile(join(options.output, 'example.tsx'), usageExample)
169
-
170
- console.log()
171
- console.log('✅ Generation complete!')
172
- console.log(`📦 Generated files in: ${options.output}`)
173
- console.log()
174
- console.log('🚀 Quick start:')
175
- console.log(`import { createAPIClient, useGetUsers } from './${options.output}'`)
176
- console.log()
177
- console.log('💡 See example.tsx for detailed usage instructions')
178
-
179
- } catch (error) {
180
- console.error('❌ Generation failed:')
181
- console.error(error instanceof Error ? error.message : error)
182
- process.exit(1)
183
- }
184
- }
185
-
186
- async function ensureDir(dir: string) {
187
- try {
188
- await fs.mkdir(dir, { recursive: true })
189
- } catch {
190
- // Directory might already exist
191
- }
192
- }
193
-
194
- async function writeFile(path: string, content: string) {
195
- await ensureDir(dirname(path))
196
- await fs.writeFile(path, content, 'utf8')
197
- }
198
-
199
- function generateUsageExample(apiTitle: string, options: GenerateHooksOptions): string {
200
- return `/**
201
- * ${apiTitle} - Usage Example
202
- *
203
- * This file demonstrates how to use the generated API integration
204
- */
205
-
206
- import React from 'react'
207
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
208
- import { createAPIClient, useGetUsers, useCreateUser } from './'
209
-
210
- // 1. Set up the API client
211
- const apiClient = createAPIClient({
212
- baseUrl: 'https://api.example.com/v1',
213
- ${options.auth === 'bearer' ? `getAuthToken: () => localStorage.getItem('authToken'),` : ''}
214
- ${options.auth === 'apiKey' ? `getApiKey: () => process.env.REACT_APP_API_KEY,
215
- apiKeyHeader: 'X-API-Key',` : ''}
216
- onError: (error) => {
217
- console.error('API Error:', error)
218
- // Handle global errors (show toast, redirect to login, etc.)
219
- }
220
- })
221
-
222
- // 2. Set up React Query
223
- const queryClient = new QueryClient({
224
- defaultOptions: {
225
- queries: {
226
- staleTime: 5 * 60 * 1000, // 5 minutes
227
- cacheTime: 10 * 60 * 1000, // 10 minutes
228
- },
229
- },
230
- })
231
-
232
- // 3. Wrap your app with providers
233
- function App() {
234
- return (
235
- <QueryClientProvider client={queryClient}>
236
- <UserList />
237
- </QueryClientProvider>
238
- )
239
- }
240
-
241
- // 4. Use generated hooks in components
242
- function UserList() {
243
- // Query hook with automatic loading, error, and data states
244
- const { data: users, isLoading, error } = useGetUsers({
245
- limit: 10
246
- })
247
-
248
- // Mutation hook with optimistic updates
249
- const createUserMutation = useCreateUser({
250
- onSuccess: () => {
251
- console.log('User created successfully!')
252
- },
253
- onError: (error) => {
254
- console.error('Failed to create user:', error)
255
- }
256
- })
257
-
258
- const handleCreateUser = () => {
259
- createUserMutation.mutate({
260
- email: 'new@example.com',
261
- name: 'New User'
262
- })
263
- }
264
-
265
- if (isLoading) return <div>Loading users...</div>
266
- if (error) return <div>Error: {error.message}</div>
267
-
268
- return (
269
- <div>
270
- <h2>Users</h2>
271
- <button
272
- onClick={handleCreateUser}
273
- disabled={createUserMutation.isLoading}
274
- >
275
- {createUserMutation.isLoading ? 'Creating...' : 'Create User'}
276
- </button>
277
-
278
- <ul>
279
- {users?.map(user => (
280
- <li key={user.id}>
281
- {user.name} ({user.email})
282
- </li>
283
- ))}
284
- </ul>
285
- </div>
286
- )
287
- }
288
-
289
- // 5. Advanced usage with infinite queries
290
- function InfiniteUserList() {
291
- const {
292
- data,
293
- fetchNextPage,
294
- hasNextPage,
295
- isFetchingNextPage,
296
- } = useInfiniteGetUsers({
297
- limit: 20
298
- })
299
-
300
- return (
301
- <div>
302
- {data?.pages.map((page, i) => (
303
- <React.Fragment key={i}>
304
- {page.map(user => (
305
- <div key={user.id}>{user.name}</div>
306
- ))}
307
- </React.Fragment>
308
- ))}
309
-
310
- <button
311
- onClick={() => fetchNextPage()}
312
- disabled={!hasNextPage || isFetchingNextPage}
313
- >
314
- {isFetchingNextPage
315
- ? 'Loading more...'
316
- : hasNextPage
317
- ? 'Load More'
318
- : 'Nothing more to load'}
319
- </button>
320
- </div>
321
- )
322
- }
323
-
324
- export default App`
325
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * Init Command
3
- *
4
- * Implementation of the `pattern-stack init` command
5
- *
6
- * Part of FRO-14: Domain Template Initialization
7
- */
8
-
9
- interface InitOptions {
10
- name?: string
11
- dir?: string
12
- git?: boolean
13
- install?: boolean
14
- }
15
-
16
- export async function initCommand(template: string = 'basic', options: InitOptions) {
17
- console.log(`🚀 Initializing Pattern-Stack project with ${template} template`)
18
-
19
- if (options.name) {
20
- console.log(`📦 Project name: ${options.name}`)
21
- }
22
-
23
- if (options.dir) {
24
- console.log(`📁 Target directory: ${options.dir}`)
25
- }
26
-
27
- console.log('\n⚠️ Template initialization not yet implemented')
28
- console.log('This feature will be available in a future release.')
29
- console.log('\nFor now, you can:')
30
- console.log('1. Clone the Pattern-Stack repository')
31
- console.log('2. Use the generate hooks command to create API integrations')
32
- console.log('3. Use the scaffold command to create components')
33
- }
@@ -1,224 +0,0 @@
1
- /**
2
- * Scaffold Command
3
- *
4
- * Implementation of the `pattern-stack scaffold` command
5
- *
6
- * Part of FRO-15: Component Scaffolding Commands
7
- */
8
-
9
- import { promises as fs } from 'fs'
10
- import { join, dirname } from 'path'
11
-
12
- interface ScaffoldOptions {
13
- template?: string
14
- output?: string
15
- }
16
-
17
- export async function scaffoldCommand(type: string, name: string, options: ScaffoldOptions) {
18
- console.log(`🏗️ Scaffolding ${type}: ${name}`)
19
-
20
- switch (type) {
21
- case 'component':
22
- await scaffoldComponent(name, options)
23
- break
24
- case 'feature':
25
- await scaffoldFeature(name, options)
26
- break
27
- case 'template':
28
- await scaffoldTemplate(name, options)
29
- break
30
- default:
31
- console.error(`❌ Unknown scaffold type: ${type}`)
32
- console.log('Available types: component, feature, template')
33
- process.exit(1)
34
- }
35
- }
36
-
37
- async function scaffoldComponent(name: string, options: ScaffoldOptions) {
38
- const outputDir = options.output || `./src/atoms/composed/${name}`
39
-
40
- const componentContent = `/**
41
- * ${name} Component
42
- *
43
- * Generated by Pattern-Stack CLI
44
- */
45
-
46
- import React from 'react'
47
- import { cn } from '../../utils/utils'
48
-
49
- export interface ${name}Props {
50
- className?: string
51
- children?: React.ReactNode
52
- }
53
-
54
- export function ${name}({ className, children, ...props }: ${name}Props) {
55
- return (
56
- <div className={cn("", className)} {...props}>
57
- {children}
58
- </div>
59
- )
60
- }
61
-
62
- ${name}.displayName = "${name}"`
63
-
64
- const indexContent = `export { ${name} } from './${name}'
65
- export type { ${name}Props } from './${name}'`
66
-
67
- const testContent = `/**
68
- * ${name} Component Tests
69
- */
70
-
71
- import { render, screen } from '@testing-library/react'
72
- import { ${name} } from './${name}'
73
-
74
- describe('${name}', () => {
75
- it('renders children', () => {
76
- render(<${name}>Test content</${name}>)
77
- expect(screen.getByText('Test content')).toBeInTheDocument()
78
- })
79
-
80
- it('applies custom className', () => {
81
- const { container } = render(<${name} className="custom-class" />)
82
- expect(container.firstChild).toHaveClass('custom-class')
83
- })
84
- })`
85
-
86
- await ensureDir(outputDir)
87
- await writeFile(join(outputDir, `${name}.tsx`), componentContent)
88
- await writeFile(join(outputDir, 'index.ts'), indexContent)
89
- await writeFile(join(outputDir, `${name}.test.tsx`), testContent)
90
-
91
- console.log(`✅ Component scaffolded: ${outputDir}`)
92
- }
93
-
94
- async function scaffoldFeature(name: string, options: ScaffoldOptions) {
95
- const outputDir = options.output || `./src/features/${name.toLowerCase()}`
96
-
97
- // Feature hook
98
- const hookContent = `/**
99
- * ${name} Hooks
100
- *
101
- * Generated by Pattern-Stack CLI
102
- */
103
-
104
- import { useState, useEffect } from 'react'
105
-
106
- export function use${name}() {
107
- const [data, setData] = useState(null)
108
- const [loading, setLoading] = useState(false)
109
- const [error, setError] = useState<Error | null>(null)
110
-
111
- // Add your logic here
112
-
113
- return {
114
- data,
115
- loading,
116
- error,
117
- refetch: () => {
118
- // Implement refetch logic
119
- }
120
- }
121
- }`
122
-
123
- // Feature component
124
- const componentContent = `/**
125
- * ${name} Component
126
- *
127
- * Generated by Pattern-Stack CLI
128
- */
129
-
130
- import React from 'react'
131
- import { use${name} } from '../hooks/use${name}'
132
-
133
- export interface ${name}ComponentProps {
134
- className?: string
135
- }
136
-
137
- export function ${name}Component({ className }: ${name}ComponentProps) {
138
- const { data, loading, error } = use${name}()
139
-
140
- if (loading) return <div>Loading...</div>
141
- if (error) return <div>Error: {error.message}</div>
142
-
143
- return (
144
- <div className={className}>
145
- <h2>${name}</h2>
146
- {/* Add your UI here */}
147
- </div>
148
- )
149
- }`
150
-
151
- // Feature index
152
- const indexContent = `export { use${name} } from './hooks/use${name}'
153
- export { ${name}Component } from './components/${name}Component'
154
- export type { ${name}ComponentProps } from './components/${name}Component'`
155
-
156
- await ensureDir(join(outputDir, 'hooks'))
157
- await ensureDir(join(outputDir, 'components'))
158
- await writeFile(join(outputDir, 'hooks', `use${name}.ts`), hookContent)
159
- await writeFile(join(outputDir, 'hooks', 'index.ts'), `export { use${name} } from './use${name}'`)
160
- await writeFile(join(outputDir, 'components', `${name}Component.tsx`), componentContent)
161
- await writeFile(join(outputDir, 'components', 'index.ts'), `export { ${name}Component } from './${name}Component'`)
162
- await writeFile(join(outputDir, 'index.ts'), indexContent)
163
-
164
- console.log(`✅ Feature scaffolded: ${outputDir}`)
165
- }
166
-
167
- async function scaffoldTemplate(name: string, options: ScaffoldOptions) {
168
- const outputDir = options.output || `./src/templates/${name.toLowerCase()}`
169
-
170
- const templateContent = `/**
171
- * ${name} Template
172
- *
173
- * Generated by Pattern-Stack CLI
174
- */
175
-
176
- import React from 'react'
177
- import { PageTemplate } from '../PageTemplate'
178
-
179
- export interface ${name}TemplateProps {
180
- title?: string
181
- children?: React.ReactNode
182
- }
183
-
184
- export function ${name}Template({
185
- title = "${name}",
186
- children
187
- }: ${name}TemplateProps) {
188
- return (
189
- <PageTemplate>
190
- <div className="space-y-6">
191
- <header>
192
- <h1 className="text-3xl font-bold">{title}</h1>
193
- </header>
194
-
195
- <main>
196
- {children}
197
- </main>
198
- </div>
199
- </PageTemplate>
200
- )
201
- }`
202
-
203
- const indexContent = `export { ${name}Template } from './${name}Template'
204
- export type { ${name}TemplateProps } from './${name}Template'`
205
-
206
- await ensureDir(outputDir)
207
- await writeFile(join(outputDir, `${name}Template.tsx`), templateContent)
208
- await writeFile(join(outputDir, 'index.ts'), indexContent)
209
-
210
- console.log(`✅ Template scaffolded: ${outputDir}`)
211
- }
212
-
213
- async function ensureDir(dir: string) {
214
- try {
215
- await fs.mkdir(dir, { recursive: true })
216
- } catch {
217
- // Directory might already exist
218
- }
219
- }
220
-
221
- async function writeFile(path: string, content: string) {
222
- await ensureDir(dirname(path))
223
- await fs.writeFile(path, content, 'utf8')
224
- }
package/cli/index.ts DELETED
@@ -1,122 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Pattern-Stack CLI
5
- *
6
- * Code generation and scaffolding tools for Pattern-Stack applications
7
- *
8
- * Part of FRO-1: CLI Foundation Setup
9
- */
10
-
11
- import { Command } from 'commander'
12
- import { generateHooksCommand } from './commands/generate-hooks'
13
- import { scaffoldCommand } from './commands/scaffold'
14
- import { initCommand } from './commands/init'
15
-
16
- const program = new Command()
17
-
18
- program
19
- .name('pattern-stack')
20
- .description('Pattern-Stack CLI for code generation and scaffolding')
21
- .version('1.0.0')
22
-
23
- // Generate commands
24
- const generateCommand = program
25
- .command('generate')
26
- .alias('g')
27
- .description('Generate code from specifications')
28
-
29
- generateCommand
30
- .command('hooks')
31
- .description('Generate React hooks from OpenAPI specification')
32
- .argument('<source>', 'OpenAPI specification (URL or file path)')
33
- .option('-o, --output <dir>', 'Output directory', './src/generated')
34
- .option('--prefix <prefix>', 'Type name prefix', '')
35
- .option('--client <type>', 'API client type', 'axios')
36
- .option('--auth <type>', 'Authentication type', 'bearer')
37
- .option('--dry-run', 'Show what would be generated without writing files')
38
- .action(generateHooksCommand)
39
-
40
- // Scaffold commands
41
- program
42
- .command('scaffold')
43
- .alias('s')
44
- .description('Scaffold components and structures')
45
- .argument('<type>', 'Type to scaffold (component, feature, template)')
46
- .argument('<name>', 'Name of the item to scaffold')
47
- .option('-t, --template <template>', 'Template to use')
48
- .option('-o, --output <dir>', 'Output directory')
49
- .action(scaffoldCommand)
50
-
51
- // Init commands
52
- program
53
- .command('init')
54
- .description('Initialize a new Pattern-Stack project')
55
- .argument('[template]', 'Template to use (financial, ecommerce, analytics)')
56
- .option('-n, --name <name>', 'Project name')
57
- .option('-d, --dir <directory>', 'Target directory')
58
- .option('--git', 'Initialize git repository')
59
- .option('--install', 'Install dependencies')
60
- .action(initCommand)
61
-
62
- // Config commands
63
- program
64
- .command('config')
65
- .description('Manage Pattern-Stack configuration')
66
- .option('--show', 'Show current configuration')
67
- .option('--set <key=value>', 'Set configuration value')
68
- .action((options) => {
69
- if (options.show) {
70
- console.log('Current configuration:')
71
- // Show config
72
- }
73
- if (options.set) {
74
- const [key, value] = options.set.split('=')
75
- console.log(`Setting ${key} = ${value}`)
76
- // Set config
77
- }
78
- })
79
-
80
- // Help command
81
- program
82
- .command('help')
83
- .description('Display help for commands')
84
- .argument('[command]', 'Command to get help for')
85
- .action((command) => {
86
- if (command) {
87
- program.help()
88
- } else {
89
- console.log(`
90
- Pattern-Stack CLI
91
-
92
- Available commands:
93
- generate hooks <source> Generate React hooks from OpenAPI spec
94
- scaffold <type> <name> Scaffold components and structures
95
- init [template] Initialize new project from template
96
- config Manage configuration
97
-
98
- Examples:
99
- pattern-stack generate hooks ./api/openapi.json
100
- pattern-stack scaffold component UserCard
101
- pattern-stack init financial --name my-finance-app
102
-
103
- For more information on a command:
104
- pattern-stack <command> --help
105
- `)
106
- }
107
- })
108
-
109
- // Handle unknown commands
110
- program.on('command:*', () => {
111
- console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' '))
112
- process.exit(1)
113
- })
114
-
115
- // Parse arguments
116
- if (process.argv.length < 3) {
117
- program.help()
118
- } else {
119
- program.parse()
120
- }
121
-
122
- export default program