bunsane 0.1.4 → 0.2.0

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 (257) hide show
  1. package/.claude/settings.local.json +47 -0
  2. package/.claude/skills/update-memory.md +74 -0
  3. package/.prettierrc +4 -0
  4. package/.serena/memories/architectural-decision-no-dependency-injection.md +76 -0
  5. package/.serena/memories/architecture.md +154 -0
  6. package/.serena/memories/cache-interface-refactoring-2026-01-24.md +165 -0
  7. package/.serena/memories/code_style_and_conventions.md +76 -0
  8. package/.serena/memories/project_overview.md +43 -0
  9. package/.serena/memories/schema-dsl-plan.md +107 -0
  10. package/.serena/memories/suggested_commands.md +80 -0
  11. package/.serena/memories/typescript-compilation-status.md +54 -0
  12. package/.serena/project.yml +114 -0
  13. package/TODO.md +1 -7
  14. package/bun.lock +150 -4
  15. package/bunfig.toml +10 -0
  16. package/config/cache.config.ts +77 -0
  17. package/config/upload.config.ts +4 -5
  18. package/core/App.ts +870 -123
  19. package/core/ArcheType.ts +2268 -377
  20. package/core/BatchLoader.ts +181 -71
  21. package/core/Config.ts +153 -0
  22. package/core/Decorators.ts +4 -1
  23. package/core/Entity.ts +621 -92
  24. package/core/EntityHookManager.ts +1 -1
  25. package/core/EntityInterface.ts +3 -1
  26. package/core/EntityManager.ts +1 -13
  27. package/core/ErrorHandler.ts +8 -2
  28. package/core/Logger.ts +9 -0
  29. package/core/Middleware.ts +34 -0
  30. package/core/RequestContext.ts +5 -1
  31. package/core/RequestLoaders.ts +227 -93
  32. package/core/SchedulerManager.ts +193 -52
  33. package/core/cache/CacheAnalytics.ts +399 -0
  34. package/core/cache/CacheFactory.ts +145 -0
  35. package/core/cache/CacheManager.ts +520 -0
  36. package/core/cache/CacheProvider.ts +34 -0
  37. package/core/cache/CacheWarmer.ts +157 -0
  38. package/core/cache/CompressionUtils.ts +110 -0
  39. package/core/cache/MemoryCache.ts +251 -0
  40. package/core/cache/MultiLevelCache.ts +180 -0
  41. package/core/cache/NoOpCache.ts +53 -0
  42. package/core/cache/RedisCache.ts +464 -0
  43. package/core/cache/TTLStrategy.ts +254 -0
  44. package/core/cache/index.ts +6 -0
  45. package/core/components/BaseComponent.ts +120 -0
  46. package/core/{ComponentRegistry.ts → components/ComponentRegistry.ts} +148 -54
  47. package/core/components/Decorators.ts +88 -0
  48. package/core/components/Interfaces.ts +7 -0
  49. package/core/components/index.ts +5 -0
  50. package/core/decorators/EntityHooks.ts +0 -3
  51. package/core/decorators/IndexedField.ts +26 -0
  52. package/core/decorators/ScheduledTask.ts +0 -47
  53. package/core/events/EntityLifecycleEvents.ts +1 -1
  54. package/core/health.ts +112 -0
  55. package/core/metadata/definitions/ArcheType.ts +14 -0
  56. package/core/metadata/definitions/Component.ts +9 -0
  57. package/core/metadata/definitions/gqlObject.ts +1 -1
  58. package/core/metadata/index.ts +42 -1
  59. package/core/metadata/metadata-storage.ts +28 -2
  60. package/core/middleware/AccessLog.ts +59 -0
  61. package/core/middleware/RequestId.ts +38 -0
  62. package/core/middleware/SecurityHeaders.ts +62 -0
  63. package/core/middleware/index.ts +3 -0
  64. package/core/scheduler/DistributedLock.ts +266 -0
  65. package/core/scheduler/index.ts +15 -0
  66. package/core/validateEnv.ts +92 -0
  67. package/database/DatabaseHelper.ts +416 -40
  68. package/database/IndexingStrategy.ts +342 -0
  69. package/database/PreparedStatementCache.ts +226 -0
  70. package/database/index.ts +32 -7
  71. package/database/sqlHelpers.ts +14 -2
  72. package/endpoints/archetypes.ts +362 -0
  73. package/endpoints/components.ts +58 -0
  74. package/endpoints/entity.ts +80 -0
  75. package/endpoints/index.ts +27 -0
  76. package/endpoints/query.ts +93 -0
  77. package/endpoints/stats.ts +76 -0
  78. package/endpoints/tables.ts +212 -0
  79. package/endpoints/types.ts +155 -0
  80. package/gql/ArchetypeOperations.ts +32 -86
  81. package/gql/Generator.ts +27 -315
  82. package/gql/GeneratorV2.ts +37 -0
  83. package/gql/builders/InputTypeBuilder.ts +99 -0
  84. package/gql/builders/ResolverBuilder.ts +234 -0
  85. package/gql/builders/TypeDefBuilder.ts +105 -0
  86. package/gql/builders/index.ts +3 -0
  87. package/gql/decorators/Upload.ts +1 -1
  88. package/gql/depthLimit.ts +85 -0
  89. package/gql/graph/GraphNode.ts +224 -0
  90. package/gql/graph/SchemaGraph.ts +278 -0
  91. package/gql/helpers.ts +8 -2
  92. package/gql/index.ts +56 -4
  93. package/gql/middleware.ts +79 -0
  94. package/gql/orchestration/GraphQLSchemaOrchestrator.ts +241 -0
  95. package/gql/orchestration/index.ts +1 -0
  96. package/gql/scanner/ServiceScanner.ts +347 -0
  97. package/gql/schema/index.ts +458 -0
  98. package/gql/strategies/TypeGenerationStrategy.ts +329 -0
  99. package/gql/types.ts +1 -0
  100. package/gql/utils/TypeSignature.ts +220 -0
  101. package/gql/utils/index.ts +1 -0
  102. package/gql/visitors/ArchetypePreprocessorVisitor.ts +80 -0
  103. package/gql/visitors/DeduplicationVisitor.ts +82 -0
  104. package/gql/visitors/GraphVisitor.ts +78 -0
  105. package/gql/visitors/ResolverGeneratorVisitor.ts +122 -0
  106. package/gql/visitors/SchemaGeneratorVisitor.ts +851 -0
  107. package/gql/visitors/TypeCollectorVisitor.ts +79 -0
  108. package/gql/visitors/VisitorComposer.ts +96 -0
  109. package/gql/visitors/index.ts +7 -0
  110. package/package.json +59 -37
  111. package/plugins/index.ts +2 -2
  112. package/query/CTENode.ts +97 -0
  113. package/query/ComponentInclusionNode.ts +689 -0
  114. package/query/FilterBuilder.ts +127 -0
  115. package/query/FilterBuilderRegistry.ts +202 -0
  116. package/query/OrNode.ts +517 -0
  117. package/query/OrQuery.ts +42 -0
  118. package/query/Query.ts +1022 -0
  119. package/query/QueryContext.ts +170 -0
  120. package/query/QueryDAG.ts +122 -0
  121. package/query/QueryNode.ts +65 -0
  122. package/query/SourceNode.ts +53 -0
  123. package/query/builders/FullTextSearchBuilder.ts +236 -0
  124. package/query/index.ts +21 -0
  125. package/scheduler/index.ts +40 -8
  126. package/service/Service.ts +2 -1
  127. package/service/ServiceRegistry.ts +6 -5
  128. package/{core/storage → storage}/LocalStorageProvider.ts +2 -2
  129. package/storage/S3StorageProvider.ts +316 -0
  130. package/{core/storage → storage}/StorageProvider.ts +7 -3
  131. package/studio/bun.lock +482 -0
  132. package/studio/index.html +13 -0
  133. package/studio/package.json +39 -0
  134. package/studio/postcss.config.js +6 -0
  135. package/studio/src/components/DataTable.tsx +211 -0
  136. package/studio/src/components/Layout.tsx +13 -0
  137. package/studio/src/components/PageContainer.tsx +9 -0
  138. package/studio/src/components/PageHeader.tsx +13 -0
  139. package/studio/src/components/SearchBar.tsx +57 -0
  140. package/studio/src/components/Sidebar.tsx +294 -0
  141. package/studio/src/components/ui/button.tsx +56 -0
  142. package/studio/src/components/ui/checkbox.tsx +26 -0
  143. package/studio/src/components/ui/input.tsx +25 -0
  144. package/studio/src/hooks/useDataTable.ts +131 -0
  145. package/studio/src/index.css +36 -0
  146. package/studio/src/lib/api.ts +186 -0
  147. package/studio/src/lib/utils.ts +13 -0
  148. package/studio/src/main.tsx +17 -0
  149. package/studio/src/pages/ArcheType.tsx +239 -0
  150. package/studio/src/pages/Components.tsx +124 -0
  151. package/studio/src/pages/EntityInspector.tsx +302 -0
  152. package/studio/src/pages/QueryRunner.tsx +246 -0
  153. package/studio/src/pages/Table.tsx +94 -0
  154. package/studio/src/pages/Welcome.tsx +241 -0
  155. package/studio/src/routes.tsx +45 -0
  156. package/studio/src/store/archeTypeSettings.ts +30 -0
  157. package/studio/src/store/studio.ts +65 -0
  158. package/studio/src/utils/columnHelpers.tsx +114 -0
  159. package/studio/studio-instructions.md +81 -0
  160. package/studio/tailwind.config.js +77 -0
  161. package/studio/tsconfig.json +24 -0
  162. package/studio/utils.ts +54 -0
  163. package/studio/vite.config.js +19 -0
  164. package/swagger/generator.ts +1 -1
  165. package/tests/e2e/http.test.ts +126 -0
  166. package/tests/fixtures/archetypes/TestUserArchetype.ts +21 -0
  167. package/tests/fixtures/components/TestOrder.ts +23 -0
  168. package/tests/fixtures/components/TestProduct.ts +23 -0
  169. package/tests/fixtures/components/TestUser.ts +20 -0
  170. package/tests/fixtures/components/index.ts +6 -0
  171. package/tests/graphql/SchemaGeneration.test.ts +90 -0
  172. package/tests/graphql/builders/ResolverBuilder.test.ts +223 -0
  173. package/tests/graphql/builders/TypeDefBuilder.test.ts +153 -0
  174. package/tests/integration/archetype/ArcheType.persistence.test.ts +241 -0
  175. package/tests/integration/cache/CacheInvalidation.test.ts +259 -0
  176. package/tests/integration/entity/Entity.persistence.test.ts +333 -0
  177. package/tests/integration/query/Query.exec.test.ts +523 -0
  178. package/tests/pglite-setup.ts +61 -0
  179. package/tests/setup.ts +164 -0
  180. package/tests/stress/BenchmarkRunner.ts +203 -0
  181. package/tests/stress/DataSeeder.ts +190 -0
  182. package/tests/stress/StressTestReporter.ts +229 -0
  183. package/tests/stress/cursor-perf-test.ts +171 -0
  184. package/tests/stress/fixtures/StressTestComponents.ts +58 -0
  185. package/tests/stress/index.ts +7 -0
  186. package/tests/stress/scenarios/query-benchmarks.test.ts +285 -0
  187. package/tests/unit/BatchLoader.test.ts +82 -0
  188. package/tests/unit/archetype/ArcheType.test.ts +107 -0
  189. package/tests/unit/cache/CacheManager.test.ts +347 -0
  190. package/tests/unit/cache/MemoryCache.test.ts +260 -0
  191. package/tests/unit/cache/RedisCache.test.ts +411 -0
  192. package/tests/unit/entity/Entity.components.test.ts +244 -0
  193. package/tests/unit/entity/Entity.test.ts +345 -0
  194. package/tests/unit/gql/depthLimit.test.ts +203 -0
  195. package/tests/unit/gql/operationMiddleware.test.ts +293 -0
  196. package/tests/unit/health/Health.test.ts +129 -0
  197. package/tests/unit/middleware/AccessLog.test.ts +37 -0
  198. package/tests/unit/middleware/Middleware.test.ts +98 -0
  199. package/tests/unit/middleware/RequestId.test.ts +54 -0
  200. package/tests/unit/middleware/SecurityHeaders.test.ts +66 -0
  201. package/tests/unit/query/FilterBuilder.test.ts +111 -0
  202. package/tests/unit/query/Query.test.ts +308 -0
  203. package/tests/unit/scheduler/DistributedLock.test.ts +274 -0
  204. package/tests/unit/schema/schema-integration.test.ts +426 -0
  205. package/tests/unit/schema/schema.test.ts +580 -0
  206. package/tests/unit/storage/S3StorageProvider.test.ts +571 -0
  207. package/tests/unit/upload/RestUpload.test.ts +267 -0
  208. package/tests/unit/validateEnv.test.ts +82 -0
  209. package/tests/utils/entity-tracker.ts +57 -0
  210. package/tests/utils/index.ts +13 -0
  211. package/tests/utils/test-context.ts +149 -0
  212. package/tsconfig.json +5 -1
  213. package/types/archetype.types.ts +6 -0
  214. package/types/hooks.types.ts +1 -1
  215. package/types/query.types.ts +110 -0
  216. package/types/scheduler.types.ts +68 -7
  217. package/types/upload.types.ts +1 -0
  218. package/{core → upload}/FileValidator.ts +10 -1
  219. package/upload/RestUpload.ts +130 -0
  220. package/{core/components → upload}/UploadComponent.ts +11 -11
  221. package/{core → upload}/UploadManager.ts +3 -3
  222. package/upload/index.ts +23 -7
  223. package/utils/UploadHelper.ts +27 -6
  224. package/utils/cronParser.ts +16 -6
  225. package/.github/workflows/deploy-docs.yml +0 -57
  226. package/core/Components.ts +0 -202
  227. package/core/EntityCache.ts +0 -15
  228. package/core/Query.ts +0 -880
  229. package/docs/README.md +0 -149
  230. package/docs/_coverpage.md +0 -36
  231. package/docs/_sidebar.md +0 -23
  232. package/docs/api/core.md +0 -568
  233. package/docs/api/hooks.md +0 -554
  234. package/docs/api/index.md +0 -222
  235. package/docs/api/query.md +0 -678
  236. package/docs/api/service.md +0 -744
  237. package/docs/core-concepts/archetypes.md +0 -512
  238. package/docs/core-concepts/components.md +0 -498
  239. package/docs/core-concepts/entity.md +0 -314
  240. package/docs/core-concepts/hooks.md +0 -683
  241. package/docs/core-concepts/query.md +0 -588
  242. package/docs/core-concepts/services.md +0 -647
  243. package/docs/examples/code-examples.md +0 -425
  244. package/docs/getting-started.md +0 -337
  245. package/docs/index.html +0 -97
  246. package/tests/bench/insert.bench.ts +0 -60
  247. package/tests/bench/relations.bench.ts +0 -270
  248. package/tests/bench/sorting.bench.ts +0 -416
  249. package/tests/component-hooks-simple.test.ts +0 -117
  250. package/tests/component-hooks.test.ts +0 -1461
  251. package/tests/component.test.ts +0 -339
  252. package/tests/errorHandling.test.ts +0 -155
  253. package/tests/hooks.test.ts +0 -667
  254. package/tests/query-sorting.test.ts +0 -101
  255. package/tests/query.test.ts +0 -81
  256. package/tests/relations.test.ts +0 -170
  257. package/tests/scheduler.test.ts +0 -724
@@ -0,0 +1,212 @@
1
+ import db from "../database";
2
+ import type {
3
+ StudioTableQueryParams,
4
+ StudioTableResponse,
5
+ DeleteTableRowsRequest,
6
+ DeleteResponse,
7
+ TableColumn,
8
+ TableRowData,
9
+ } from "./types";
10
+
11
+ export async function handleStudioTableRequest(
12
+ tableName: string,
13
+ params: StudioTableQueryParams = {}
14
+ ): Promise<Response> {
15
+ const limit = Math.min(Math.max(params.limit ?? 50, 1), 1000);
16
+ const offset = Math.max(params.offset ?? 0, 0);
17
+ const searchTerm = params.search ?? "";
18
+
19
+ try {
20
+ const columnsResult = await db`
21
+ SELECT
22
+ column_name,
23
+ data_type,
24
+ is_nullable,
25
+ column_default
26
+ FROM information_schema.columns
27
+ WHERE table_name = ${tableName}
28
+ AND table_schema = 'public'
29
+ ORDER BY ordinal_position
30
+ `;
31
+
32
+ if (columnsResult.length === 0) {
33
+ return new Response(
34
+ JSON.stringify({ error: `Table '${tableName}' not found` }),
35
+ {
36
+ status: 404,
37
+ headers: { "Content-Type": "application/json" },
38
+ }
39
+ );
40
+ }
41
+
42
+ const primaryKeyResult = await db`
43
+ SELECT kcu.column_name
44
+ FROM information_schema.table_constraints tc
45
+ JOIN information_schema.key_column_usage kcu
46
+ ON tc.constraint_name = kcu.constraint_name
47
+ AND tc.table_schema = kcu.table_schema
48
+ WHERE tc.constraint_type = 'PRIMARY KEY'
49
+ AND tc.table_name = ${tableName}
50
+ AND tc.table_schema = 'public'
51
+ `;
52
+ const primaryKeyColumns = new Set(
53
+ primaryKeyResult.map((row: { column_name: string }) => row.column_name)
54
+ );
55
+
56
+ const columns: TableColumn[] = columnsResult.map((col: {
57
+ column_name: string;
58
+ data_type: string;
59
+ is_nullable: string;
60
+ }) => ({
61
+ name: col.column_name,
62
+ type: col.data_type,
63
+ nullable: col.is_nullable === "YES",
64
+ primary: primaryKeyColumns.has(col.column_name),
65
+ }));
66
+
67
+ const textColumns = columnsResult
68
+ .filter((col: { data_type: string }) =>
69
+ ["character varying", "text", "varchar", "char", "uuid"].includes(col.data_type)
70
+ )
71
+ .map((col: { column_name: string }) => col.column_name);
72
+
73
+ let rows: TableRowData[];
74
+ let totalResult: { count: number }[];
75
+
76
+ if (searchTerm && textColumns.length > 0) {
77
+ const searchPattern = `%${searchTerm}%`;
78
+ const searchConditions = textColumns
79
+ .map((col: string) => `"${col}"::text ILIKE $1`)
80
+ .join(" OR ");
81
+
82
+ rows = await db.unsafe(
83
+ `SELECT * FROM "${tableName}"
84
+ WHERE ${searchConditions}
85
+ ORDER BY created_at DESC NULLS LAST
86
+ LIMIT $2 OFFSET $3`,
87
+ [searchPattern, limit, offset]
88
+ );
89
+
90
+ totalResult = await db.unsafe(
91
+ `SELECT COUNT(*) as count FROM "${tableName}" WHERE ${searchConditions}`,
92
+ [searchPattern]
93
+ );
94
+ } else {
95
+ rows = await db.unsafe(
96
+ `SELECT * FROM "${tableName}"
97
+ ORDER BY created_at DESC NULLS LAST
98
+ LIMIT $1 OFFSET $2`,
99
+ [limit, offset]
100
+ );
101
+
102
+ totalResult = await db.unsafe(
103
+ `SELECT COUNT(*) as count FROM "${tableName}"`
104
+ );
105
+ }
106
+
107
+ const total = Number(totalResult[0]?.count ?? 0);
108
+
109
+ const responseData: StudioTableResponse = {
110
+ name: tableName,
111
+ columns,
112
+ rows,
113
+ total,
114
+ limit,
115
+ offset,
116
+ };
117
+
118
+ return new Response(JSON.stringify(responseData), {
119
+ headers: { "Content-Type": "application/json" },
120
+ });
121
+ } catch (error) {
122
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
123
+ return new Response(
124
+ JSON.stringify({ error: `Failed to fetch table data: ${errorMessage}` }),
125
+ {
126
+ status: 500,
127
+ headers: { "Content-Type": "application/json" },
128
+ }
129
+ );
130
+ }
131
+ }
132
+
133
+ export async function handleStudioTableDeleteRequest(
134
+ tableName: string,
135
+ requestBody: DeleteTableRowsRequest
136
+ ): Promise<Response> {
137
+ const { ids } = requestBody;
138
+
139
+ if (!ids || !Array.isArray(ids) || ids.length === 0) {
140
+ return new Response(
141
+ JSON.stringify({ error: "ids array is required and must not be empty" }),
142
+ {
143
+ status: 400,
144
+ headers: { "Content-Type": "application/json" },
145
+ }
146
+ );
147
+ }
148
+
149
+ try {
150
+ const idPlaceholders = ids.map((_, index) => `$${index + 1}`).join(", ");
151
+
152
+ await db.unsafe(
153
+ `DELETE FROM "${tableName}" WHERE id IN (${idPlaceholders})`,
154
+ ids
155
+ );
156
+
157
+ const deletedCount = ids.length;
158
+
159
+ const responseData: DeleteResponse = {
160
+ success: true,
161
+ deletedCount,
162
+ message: `Successfully deleted ${deletedCount} row(s) from ${tableName}`,
163
+ };
164
+
165
+ return new Response(JSON.stringify(responseData), {
166
+ headers: { "Content-Type": "application/json" },
167
+ });
168
+ } catch (error) {
169
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
170
+ return new Response(
171
+ JSON.stringify({ error: `Failed to delete rows: ${errorMessage}` }),
172
+ {
173
+ status: 500,
174
+ headers: { "Content-Type": "application/json" },
175
+ }
176
+ );
177
+ }
178
+ }
179
+
180
+ export async function handleGetTables(): Promise<Response> {
181
+ try {
182
+ // Fetch all tables except ECS tables
183
+ const ecsTables = ['components', 'entities', 'entity_components', 'spatial_ref_sys'];
184
+ const ecsTablePlaceholders = ecsTables.map((_, index) => `$${index + 1}`).join(", ");
185
+
186
+ const result = await db.unsafe(
187
+ `SELECT table_name
188
+ FROM information_schema.tables
189
+ WHERE table_schema = 'public'
190
+ AND table_type = 'BASE TABLE'
191
+ AND table_name NOT IN (${ecsTablePlaceholders})
192
+ AND table_name NOT LIKE 'components_%'
193
+ ORDER BY table_name`,
194
+ ecsTables
195
+ );
196
+
197
+ const tables = result.map((row: { table_name: string }) => row.table_name);
198
+
199
+ return new Response(JSON.stringify({ tables }), {
200
+ headers: { "Content-Type": "application/json" },
201
+ });
202
+ } catch (error) {
203
+ const errorMessage = error instanceof Error ? error.message : "Unknown error";
204
+ return new Response(
205
+ JSON.stringify({ error: `Failed to fetch tables: ${errorMessage}` }),
206
+ {
207
+ status: 500,
208
+ headers: { "Content-Type": "application/json" },
209
+ }
210
+ );
211
+ }
212
+ }
@@ -0,0 +1,155 @@
1
+ interface StudioTableQueryParams {
2
+ limit?: number;
3
+ offset?: number;
4
+ search?: string;
5
+ }
6
+
7
+ interface StudioArcheTypeQueryParams {
8
+ limit?: number;
9
+ offset?: number;
10
+ search?: string;
11
+ include_deleted?: boolean;
12
+ }
13
+
14
+ interface TableColumn {
15
+ name: string;
16
+ type: string;
17
+ nullable: boolean;
18
+ primary: boolean;
19
+ }
20
+
21
+ interface TableRowData {
22
+ [key: string]: unknown;
23
+ }
24
+
25
+ interface StudioTableResponse {
26
+ name: string;
27
+ columns: TableColumn[];
28
+ rows: TableRowData[];
29
+ total: number;
30
+ limit: number;
31
+ offset: number;
32
+ }
33
+
34
+ interface ArcheTypeField {
35
+ fieldName: string;
36
+ componentName: string;
37
+ fieldLabel: string;
38
+ nullable?: boolean;
39
+ }
40
+
41
+ interface ArcheTypeEntityRecord {
42
+ entityId: string;
43
+ components: Record<string, unknown>;
44
+ deleted_at?: string | null;
45
+ }
46
+
47
+ interface StudioArcheTypeResponse {
48
+ name: string;
49
+ fields: ArcheTypeField[];
50
+ indicatorComponent: string | null;
51
+ entities: ArcheTypeEntityRecord[];
52
+ total: number;
53
+ limit: number;
54
+ offset: number;
55
+ }
56
+
57
+ interface DeleteTableRowsRequest {
58
+ ids: string[];
59
+ }
60
+
61
+ interface DeleteArcheTypeEntitiesRequest {
62
+ entityIds: string[];
63
+ }
64
+
65
+ interface DeleteResponse {
66
+ success: boolean;
67
+ deletedCount: number;
68
+ message: string;
69
+ }
70
+
71
+ interface EntityComponent {
72
+ id: string;
73
+ name: string;
74
+ type_id: string;
75
+ data: unknown;
76
+ created_at: string;
77
+ updated_at: string;
78
+ deleted_at: string | null;
79
+ }
80
+
81
+ interface EntityInspectorResponse {
82
+ entity: {
83
+ id: string;
84
+ created_at: string;
85
+ updated_at: string;
86
+ deleted_at: string | null;
87
+ };
88
+ components: EntityComponent[];
89
+ }
90
+
91
+ interface ComponentTypeStats {
92
+ name: string;
93
+ count: number;
94
+ }
95
+
96
+ interface ArcheTypeStats {
97
+ name: string;
98
+ entityCount: number;
99
+ componentCount: number;
100
+ }
101
+
102
+ interface StudioStatsResponse {
103
+ entities: {
104
+ active: number;
105
+ deleted: number;
106
+ total: number;
107
+ };
108
+ componentTypes: ComponentTypeStats[];
109
+ archetypes: ArcheTypeStats[];
110
+ }
111
+
112
+ interface ComponentTypeInfo {
113
+ name: string;
114
+ entityCount: number;
115
+ partitionTable: string;
116
+ fields: string[];
117
+ }
118
+
119
+ interface StudioComponentsResponse {
120
+ components: ComponentTypeInfo[];
121
+ }
122
+
123
+ interface StudioQueryRequest {
124
+ sql: string;
125
+ }
126
+
127
+ interface StudioQueryResponse {
128
+ columns: string[];
129
+ rows: Record<string, unknown>[];
130
+ rowCount: number;
131
+ duration: number;
132
+ }
133
+
134
+ export type {
135
+ StudioTableQueryParams,
136
+ StudioArcheTypeQueryParams,
137
+ TableColumn,
138
+ TableRowData,
139
+ StudioTableResponse,
140
+ ArcheTypeField,
141
+ ArcheTypeEntityRecord,
142
+ StudioArcheTypeResponse,
143
+ DeleteTableRowsRequest,
144
+ DeleteArcheTypeEntitiesRequest,
145
+ DeleteResponse,
146
+ EntityComponent,
147
+ EntityInspectorResponse,
148
+ ComponentTypeStats,
149
+ ArcheTypeStats,
150
+ StudioStatsResponse,
151
+ ComponentTypeInfo,
152
+ StudioComponentsResponse,
153
+ StudioQueryRequest,
154
+ StudioQueryResponse,
155
+ };
@@ -1,4 +1,4 @@
1
- import { getAllArchetypeSchemas, getArchetypeSchema } from "../core/ArcheType";
1
+ import { getAllArchetypeSchemas, getArchetypeSchema, weaveAllArchetypes } from "../core/ArcheType";
2
2
  import { logger as MainLogger } from "../core/Logger";
3
3
 
4
4
  const logger = MainLogger.child({ scope: "ArchetypeOperations" });
@@ -25,9 +25,6 @@ export function generateArchetypeOperations(config: ArchetypeOperationConfig = {
25
25
  enableMutations = { create: true, update: true, delete: true }
26
26
  } = config;
27
27
 
28
- const schemas = getAllArchetypeSchemas();
29
- logger.trace(`getAllArchetypeSchemas returned ${schemas.length} schemas`);
30
-
31
28
  let typeDefs = "\n# Auto-generated Archetype Types\n";
32
29
  const queryFields: string[] = [];
33
30
  const mutationFields: string[] = [];
@@ -36,23 +33,39 @@ export function generateArchetypeOperations(config: ArchetypeOperationConfig = {
36
33
  // Track defined types to prevent duplicates
37
34
  const definedTypes = new Set<string>();
38
35
 
39
- schemas.forEach(({ zodSchema, graphqlSchema }) => {
40
- // Extract archetype name from the schema
41
- const archetypeName = extractArchetypeName(graphqlSchema);
42
- if (!archetypeName) {
43
- logger.warn(`Could not extract archetype name from schema: ${graphqlSchema.substring(0, 100)}`);
44
- return;
45
- }
46
-
47
- logger.trace(`Generating operations for archetype: ${archetypeName}`);
48
-
49
- // Add the archetype type definition (without Query/Mutation)
50
- // Extract and deduplicate type definitions
51
- const typeDefinitions = extractTypeDefinitions(graphqlSchema);
36
+ // Get the full weaved schema that includes all archetypes and their relations
37
+ const fullSchema = weaveAllArchetypes();
38
+ if (fullSchema) {
39
+ logger.trace(`Using full weaved schema for type definitions`);
40
+ // Extract and deduplicate type definitions from the full schema
41
+ const typeDefinitions = extractTypeDefinitions(fullSchema);
52
42
  const deduplicatedTypes = deduplicateTypeDefinitions(typeDefinitions, definedTypes);
53
- logger.trace(`Adding ${deduplicatedTypes.length} characters of type definitions for ${archetypeName}`);
43
+ logger.trace(`Adding ${deduplicatedTypes.length} characters of type definitions`);
54
44
  typeDefs += deduplicatedTypes;
55
- });
45
+ } else {
46
+ logger.warn(`No full schema available, falling back to individual schemas`);
47
+ // Fallback to individual schemas if weaving fails
48
+ const schemas = getAllArchetypeSchemas();
49
+ logger.trace(`getAllArchetypeSchemas returned ${schemas.length} schemas`);
50
+
51
+ schemas.forEach(({ zodSchema, graphqlSchema }) => {
52
+ // Extract archetype name from the schema
53
+ const archetypeName = extractArchetypeName(graphqlSchema);
54
+ if (!archetypeName) {
55
+ logger.warn(`Could not extract archetype name from schema: ${graphqlSchema.substring(0, 100)}`);
56
+ return;
57
+ }
58
+
59
+ logger.trace(`Generating operations for archetype: ${archetypeName}`);
60
+
61
+ // Add the archetype type definition (without Query/Mutation)
62
+ // Extract and deduplicate type definitions
63
+ const typeDefinitions = extractTypeDefinitions(graphqlSchema);
64
+ const deduplicatedTypes = deduplicateTypeDefinitions(typeDefinitions, definedTypes);
65
+ logger.trace(`Adding ${deduplicatedTypes.length} characters of type definitions for ${archetypeName}`);
66
+ typeDefs += deduplicatedTypes;
67
+ });
68
+ }
56
69
 
57
70
  typeDefs += "\n# END AUTO-GENERATED TYPES\n";
58
71
  logger.trace(`Final typeDefs length: ${typeDefs.length}`);
@@ -61,73 +74,6 @@ export function generateArchetypeOperations(config: ArchetypeOperationConfig = {
61
74
  return { typeDefs, queryFields, mutationFields, resolvers };
62
75
  }
63
76
 
64
- /**
65
- * WIP
66
- * Generate full archetype operations including types, queries, and mutations
67
- */
68
- //TODO: Implement this
69
- export function generateArchetypeOperationsWithCRUD(config: ArchetypeOperationConfig = {}) {
70
- const {
71
- enableQueries = { get: true, list: true },
72
- enableMutations = { create: true, update: true, delete: true }
73
- } = config;
74
-
75
- const schemas = getAllArchetypeSchemas();
76
- let typeDefs = "\n# Auto-generated Archetype Types\n";
77
- const queryFields: string[] = [];
78
- const mutationFields: string[] = [];
79
- const resolvers: any = { Query: {}, Mutation: {} };
80
-
81
- schemas.forEach(({ zodSchema, graphqlSchema }) => {
82
- // Extract archetype name from the schema
83
- const archetypeName = extractArchetypeName(graphqlSchema);
84
- if (!archetypeName) return;
85
-
86
- logger.trace(`Generating operations for archetype: ${archetypeName}`);
87
-
88
- // Add the archetype type definition (without Query/Mutation)
89
- typeDefs += extractTypeDefinitions(graphqlSchema);
90
-
91
- // Generate filter input type
92
- typeDefs += generateFilterInput(archetypeName, zodSchema);
93
-
94
- // Generate create input type
95
- typeDefs += generateCreateInput(archetypeName, zodSchema);
96
-
97
- // Generate update input type
98
- typeDefs += generateUpdateInput(archetypeName, zodSchema);
99
-
100
- // Generate Query operations
101
- if (enableQueries?.get) {
102
- queryFields.push(`get${archetypeName}(id: ID!): ${archetypeName}`);
103
- resolvers.Query[`get${archetypeName}`] = createGetResolver(archetypeName);
104
- }
105
-
106
- if (enableQueries?.list) {
107
- queryFields.push(`list${archetypeName}s(filter: ${archetypeName}Filter, limit: Int, offset: Int): [${archetypeName}!]!`);
108
- resolvers.Query[`list${archetypeName}s`] = createListResolver(archetypeName);
109
- }
110
-
111
- // Generate Mutation operations
112
- if (enableMutations?.create) {
113
- mutationFields.push(`create${archetypeName}(input: Create${archetypeName}Input!): ${archetypeName}!`);
114
- resolvers.Mutation[`create${archetypeName}`] = createCreateResolver(archetypeName);
115
- }
116
-
117
- if (enableMutations?.update) {
118
- mutationFields.push(`update${archetypeName}(id: ID!, input: Update${archetypeName}Input!): ${archetypeName}!`);
119
- resolvers.Mutation[`update${archetypeName}`] = createUpdateResolver(archetypeName);
120
- }
121
-
122
- if (enableMutations?.delete) {
123
- mutationFields.push(`delete${archetypeName}(id: ID!): Boolean!`);
124
- resolvers.Mutation[`delete${archetypeName}`] = createDeleteResolver(archetypeName);
125
- }
126
- });
127
-
128
- return { typeDefs, queryFields, mutationFields, resolvers };
129
- }
130
-
131
77
  function extractArchetypeName(graphqlSchema: string): string | null {
132
78
  const match = graphqlSchema.match(/type (\w+) \{/);
133
79
  return match ? match[1] ?? null : null;