@pattern-stack/frontend-patterns 0.2.0-alpha.0 → 0.2.0-alpha.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.
Files changed (160) 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 +8793 -18275
  112. package/dist/index.es.js.map +1 -1
  113. package/dist/index.js +8790 -18271
  114. package/dist/index.js.map +1 -1
  115. package/dist/molecules/layout/AppHeader/AppHeader.d.ts.map +1 -1
  116. package/dist/molecules/layout/BulkSelectionBar.d.ts +14 -2
  117. package/dist/molecules/layout/BulkSelectionBar.d.ts.map +1 -1
  118. package/dist/molecules/layout/FieldGrid/FieldGrid.d.ts +61 -0
  119. package/dist/molecules/layout/FieldGrid/FieldGrid.d.ts.map +1 -0
  120. package/dist/molecules/layout/FieldGrid/index.d.ts +2 -0
  121. package/dist/molecules/layout/FieldGrid/index.d.ts.map +1 -0
  122. package/dist/molecules/layout/ListToolbar/ListToolbar.d.ts +37 -0
  123. package/dist/molecules/layout/ListToolbar/ListToolbar.d.ts.map +1 -0
  124. package/dist/molecules/layout/ListToolbar/index.d.ts +2 -0
  125. package/dist/molecules/layout/ListToolbar/index.d.ts.map +1 -0
  126. package/dist/molecules/layout/PageTitle/PageTitle.d.ts +17 -0
  127. package/dist/molecules/layout/PageTitle/PageTitle.d.ts.map +1 -0
  128. package/dist/molecules/layout/PageTitle/index.d.ts +2 -0
  129. package/dist/molecules/layout/PageTitle/index.d.ts.map +1 -0
  130. package/dist/molecules/layout/index.d.ts +3 -0
  131. package/dist/molecules/layout/index.d.ts.map +1 -1
  132. package/dist/molecules/layout/navigation-context.d.ts.map +1 -1
  133. package/dist/sync/EntityStoreProvider.d.ts +35 -0
  134. package/dist/sync/EntityStoreProvider.d.ts.map +1 -0
  135. package/dist/sync/createEntityHooks.d.ts +29 -0
  136. package/dist/sync/createEntityHooks.d.ts.map +1 -0
  137. package/dist/sync/createStore.d.ts +65 -0
  138. package/dist/sync/createStore.d.ts.map +1 -0
  139. package/dist/sync/index.d.ts +6 -0
  140. package/dist/sync/index.d.ts.map +1 -0
  141. package/dist/sync/types.d.ts +383 -0
  142. package/dist/sync/types.d.ts.map +1 -0
  143. package/dist/templates/ListPageTemplate.d.ts +21 -0
  144. package/dist/templates/ListPageTemplate.d.ts.map +1 -0
  145. package/dist/templates/admin/AdminCRUDTemplate.d.ts.map +1 -1
  146. package/dist/templates/factory.d.ts +11 -0
  147. package/dist/templates/factory.d.ts.map +1 -1
  148. package/dist/templates/index.d.ts +1 -0
  149. package/dist/templates/index.d.ts.map +1 -1
  150. package/package.json +11 -7
  151. package/cli/commands/generate-hooks.ts +0 -316
  152. package/cli/commands/init.ts +0 -33
  153. package/cli/commands/scaffold.ts +0 -224
  154. package/cli/index.ts +0 -122
  155. package/cli/src/codegen/openapi/client-generator.js +0 -659
  156. package/cli/src/codegen/openapi/hook-generator.js +0 -725
  157. package/cli/src/codegen/openapi/parser.js +0 -274
  158. package/cli/src/codegen/openapi/type-generator.js +0 -329
  159. package/dist/codegen/openapi/bulk-types.d.ts +0 -142
  160. package/dist/codegen/openapi/bulk-types.d.ts.map +0 -1
@@ -1,316 +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 { loadOpenAPISpec, parseOpenAPI } from '../../src/codegen/openapi/parser.js'
12
- import { generateTypes } from '../../src/codegen/openapi/type-generator.js'
13
- import { generateAPIClient } from '../../src/codegen/openapi/client-generator.js'
14
- import { generateHooks } from '../../src/codegen/openapi/hook-generator.js'
15
-
16
- interface GenerateHooksOptions {
17
- output: string
18
- prefix?: string
19
- client: 'axios' | 'fetch'
20
- auth: 'bearer' | 'apiKey' | 'basic'
21
- dryRun?: boolean
22
- }
23
-
24
- export async function generateHooksCommand(source: string, options: GenerateHooksOptions) {
25
- try {
26
- console.log('🚀 Pattern-Stack Hook Generator')
27
- console.log('================================')
28
- console.log()
29
-
30
- // Load and parse OpenAPI specification
31
- console.log('📥 Loading OpenAPI specification...')
32
- const spec = await loadOpenAPISpec(source)
33
- console.log(`✅ Loaded: ${spec.info.title} v${spec.info.version}`)
34
-
35
- console.log('🔍 Parsing specification...')
36
- const parsed = await parseOpenAPI(spec)
37
- console.log(`✅ Found ${parsed.endpoints.length} endpoints, ${parsed.schemas.length} schemas`)
38
-
39
- // Generate types
40
- console.log('🏗️ Generating TypeScript types...')
41
- const types = generateTypes(parsed, {
42
- prefix: options.prefix,
43
- includeJSDoc: true,
44
- includeExamples: true
45
- })
46
-
47
- // Generate API client
48
- console.log('🔧 Generating API client...')
49
- const client = generateAPIClient(parsed, {
50
- clientType: options.client,
51
- includeAuth: true,
52
- authType: options.auth,
53
- includeInterceptors: true
54
- })
55
-
56
- // Generate React hooks
57
- console.log('⚛️ Generating React hooks...')
58
- const hooks = await generateHooks(parsed, {
59
- includeInfiniteQueries: true,
60
- includeOptimisticUpdates: true,
61
- includeMutationHelpers: true,
62
- enableConfidenceScoring: true
63
- })
64
-
65
- if (options.dryRun) {
66
- console.log('\n📋 Dry run - files that would be generated:')
67
- console.log('Types:')
68
- console.log(' - schemas.ts')
69
- console.log(' - endpoints.ts')
70
- console.log(' - parameters.ts')
71
- console.log(' - responses.ts')
72
- console.log()
73
- console.log('API Client:')
74
- console.log(' - client.ts')
75
- console.log(' - methods.ts')
76
- console.log(' - types.ts')
77
- console.log(' - config.ts')
78
- console.log()
79
- console.log('React Hooks:')
80
- console.log(' - queries.ts')
81
- console.log(' - mutations.ts')
82
- console.log(' - keys.ts')
83
- console.log(' - types.ts')
84
- console.log()
85
- console.log('Generated code preview:')
86
- console.log('======================')
87
- console.log()
88
- console.log('Types (first 20 lines):')
89
- console.log(types.schemas.split('\n').slice(0, 20).join('\n'))
90
- console.log('\n...')
91
- return
92
- }
93
-
94
- // Create output directories
95
- console.log(`📁 Creating output directory: ${options.output}`)
96
- await ensureDir(options.output)
97
- await ensureDir(join(options.output, 'types'))
98
- await ensureDir(join(options.output, 'client'))
99
- await ensureDir(join(options.output, 'hooks'))
100
-
101
- // Write type files
102
- console.log('💾 Writing type definitions...')
103
- await writeFile(join(options.output, 'types', 'schemas.ts'), types.schemas)
104
- await writeFile(join(options.output, 'types', 'endpoints.ts'), types.endpoints)
105
- await writeFile(join(options.output, 'types', 'parameters.ts'), types.parameters)
106
- await writeFile(join(options.output, 'types', 'responses.ts'), types.responses)
107
- await writeFile(join(options.output, 'types', 'index.ts'), types.index)
108
-
109
- // Write client files
110
- console.log('💾 Writing API client...')
111
- await writeFile(join(options.output, 'client', 'client.ts'), client.client)
112
- await writeFile(join(options.output, 'client', 'methods.ts'), client.methods)
113
- await writeFile(join(options.output, 'client', 'types.ts'), client.types)
114
- await writeFile(join(options.output, 'client', 'config.ts'), client.config)
115
- await writeFile(join(options.output, 'client', 'index.ts'), client.index)
116
-
117
- // Write hook files
118
- console.log('💾 Writing React hooks...')
119
- await writeFile(join(options.output, 'hooks', 'queries.ts'), hooks.queries)
120
- await writeFile(join(options.output, 'hooks', 'mutations.ts'), hooks.mutations)
121
- await writeFile(join(options.output, 'hooks', 'keys.ts'), hooks.keys)
122
- await writeFile(join(options.output, 'hooks', 'types.ts'), hooks.types)
123
- await writeFile(join(options.output, 'hooks', 'index.ts'), hooks.index)
124
-
125
- // Write confidence report if available
126
- if (hooks.report) {
127
- await writeFile(join(options.output, 'hooks', 'confidence-report.md'), hooks.report)
128
- console.log('📊 Generated confidence report')
129
-
130
- // Check if there are low confidence names
131
- const lowConfidenceCount = (hooks.report.match(/## Low Confidence Names/g) || []).length
132
- if (lowConfidenceCount > 0) {
133
- console.log('\n⚠️ Some hook names have low confidence and may need review.')
134
- console.log('Run `npm run review:hooks` to interactively review and improve them.')
135
- }
136
- }
137
-
138
- // Write main index file
139
- const mainIndex = `/**
140
- * Generated API Integration
141
- *
142
- * Auto-generated from OpenAPI specification: ${spec.info.title}
143
- * Version: ${spec.info.version}
144
- * Generated: ${new Date().toISOString()}
145
- */
146
-
147
- export * from './types'
148
- export * from './client'
149
- export * from './hooks'
150
-
151
- // Quick start exports
152
- export { createAPIClient } from './client'
153
- export { queryKeys } from './hooks'`
154
-
155
- await writeFile(join(options.output, 'index.ts'), mainIndex)
156
-
157
- // Generate usage example
158
- const usageExample = generateUsageExample(spec.info.title, options)
159
- await writeFile(join(options.output, 'example.ts'), usageExample)
160
-
161
- console.log()
162
- console.log('✅ Generation complete!')
163
- console.log(`📦 Generated files in: ${options.output}`)
164
- console.log()
165
- console.log('🚀 Quick start:')
166
- console.log(`import { createAPIClient, useGetUsers } from './${options.output}'`)
167
- console.log()
168
- console.log('💡 See example.ts for detailed usage instructions')
169
-
170
- } catch (error) {
171
- console.error('❌ Generation failed:')
172
- console.error(error instanceof Error ? error.message : error)
173
- process.exit(1)
174
- }
175
- }
176
-
177
- async function ensureDir(dir: string) {
178
- try {
179
- await fs.mkdir(dir, { recursive: true })
180
- } catch {
181
- // Directory might already exist
182
- }
183
- }
184
-
185
- async function writeFile(path: string, content: string) {
186
- await ensureDir(dirname(path))
187
- await fs.writeFile(path, content, 'utf8')
188
- }
189
-
190
- function generateUsageExample(apiTitle: string, options: GenerateHooksOptions): string {
191
- return `/**
192
- * ${apiTitle} - Usage Example
193
- *
194
- * This file demonstrates how to use the generated API integration
195
- */
196
-
197
- import React from 'react'
198
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
199
- import { createAPIClient, useGetUsers, useCreateUser } from './'
200
-
201
- // 1. Set up the API client
202
- const apiClient = createAPIClient({
203
- baseUrl: 'https://api.example.com/v1',
204
- ${options.auth === 'bearer' ? `getAuthToken: () => localStorage.getItem('authToken'),` : ''}
205
- ${options.auth === 'apiKey' ? `getApiKey: () => process.env.REACT_APP_API_KEY,
206
- apiKeyHeader: 'X-API-Key',` : ''}
207
- onError: (error) => {
208
- console.error('API Error:', error)
209
- // Handle global errors (show toast, redirect to login, etc.)
210
- }
211
- })
212
-
213
- // 2. Set up React Query
214
- const queryClient = new QueryClient({
215
- defaultOptions: {
216
- queries: {
217
- staleTime: 5 * 60 * 1000, // 5 minutes
218
- cacheTime: 10 * 60 * 1000, // 10 minutes
219
- },
220
- },
221
- })
222
-
223
- // 3. Wrap your app with providers
224
- function App() {
225
- return (
226
- <QueryClientProvider client={queryClient}>
227
- <UserList />
228
- </QueryClientProvider>
229
- )
230
- }
231
-
232
- // 4. Use generated hooks in components
233
- function UserList() {
234
- // Query hook with automatic loading, error, and data states
235
- const { data: users, isLoading, error } = useGetUsers({
236
- limit: 10
237
- })
238
-
239
- // Mutation hook with optimistic updates
240
- const createUserMutation = useCreateUser({
241
- onSuccess: () => {
242
- console.log('User created successfully!')
243
- },
244
- onError: (error) => {
245
- console.error('Failed to create user:', error)
246
- }
247
- })
248
-
249
- const handleCreateUser = () => {
250
- createUserMutation.mutate({
251
- email: 'new@example.com',
252
- name: 'New User'
253
- })
254
- }
255
-
256
- if (isLoading) return <div>Loading users...</div>
257
- if (error) return <div>Error: {error.message}</div>
258
-
259
- return (
260
- <div>
261
- <h2>Users</h2>
262
- <button
263
- onClick={handleCreateUser}
264
- disabled={createUserMutation.isLoading}
265
- >
266
- {createUserMutation.isLoading ? 'Creating...' : 'Create User'}
267
- </button>
268
-
269
- <ul>
270
- {users?.map(user => (
271
- <li key={user.id}>
272
- {user.name} ({user.email})
273
- </li>
274
- ))}
275
- </ul>
276
- </div>
277
- )
278
- }
279
-
280
- // 5. Advanced usage with infinite queries
281
- function InfiniteUserList() {
282
- const {
283
- data,
284
- fetchNextPage,
285
- hasNextPage,
286
- isFetchingNextPage,
287
- } = useInfiniteGetUsers({
288
- limit: 20
289
- })
290
-
291
- return (
292
- <div>
293
- {data?.pages.map((page, i) => (
294
- <React.Fragment key={i}>
295
- {page.map(user => (
296
- <div key={user.id}>{user.name}</div>
297
- ))}
298
- </React.Fragment>
299
- ))}
300
-
301
- <button
302
- onClick={() => fetchNextPage()}
303
- disabled={!hasNextPage || isFetchingNextPage}
304
- >
305
- {isFetchingNextPage
306
- ? 'Loading more...'
307
- : hasNextPage
308
- ? 'Load More'
309
- : 'Nothing more to load'}
310
- </button>
311
- </div>
312
- )
313
- }
314
-
315
- export default App`
316
- }
@@ -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