@svgrid/enterprise 1.2.0 → 2.0.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 (159) hide show
  1. package/dist/cdn/svgrid-enterprise.svelte-external.js +26039 -805
  2. package/dist/designer/assets/index-Dp44bTid.js +939 -0
  3. package/dist/designer/assets/index-RJp6x8tw.css +1 -0
  4. package/dist/designer/assets/jszip.min-CjMo-QGg.js +2 -0
  5. package/dist/designer/index.html +13 -0
  6. package/dist/node/studio.js +22554 -0
  7. package/package.json +10 -3
  8. package/src/SvAuthGate.svelte +115 -0
  9. package/src/SvBoard.dom.test.ts +67 -0
  10. package/src/SvBoard.svelte +192 -0
  11. package/src/SvExportMenu.svelte +553 -0
  12. package/src/SvFileInput.svelte +113 -0
  13. package/src/SvGridEditPanel.dom.test.ts +146 -0
  14. package/src/SvGridEditPanel.svelte +793 -0
  15. package/src/SvGridMasterDetail.svelte +95 -0
  16. package/src/SvImportDialog.svelte +1020 -0
  17. package/src/SvLookupInput.svelte +180 -0
  18. package/src/SvRecordDetail.dom.test.ts +137 -0
  19. package/src/SvRecordDetail.svelte +288 -0
  20. package/src/SvSchedule.dom.test.ts +57 -0
  21. package/src/SvSchedule.svelte +156 -0
  22. package/src/SvSchemaChart.svelte +233 -0
  23. package/src/SvSchemaDashboard.svelte +130 -0
  24. package/src/ai-export-pdf.test.ts +74 -0
  25. package/src/ai-export-xlsx.test.ts +87 -0
  26. package/src/ai-export.test.ts +110 -0
  27. package/src/ai.ts +1188 -782
  28. package/src/edit-panel.test.ts +213 -0
  29. package/src/edit-panel.ts +228 -0
  30. package/src/export-conditional.test.ts +60 -0
  31. package/src/export-conditional.ts +94 -0
  32. package/src/export-ooxml.test.ts +152 -0
  33. package/src/export-ooxml.ts +485 -0
  34. package/src/export-pdf.test.ts +138 -0
  35. package/src/export-pdf.ts +245 -0
  36. package/src/export-print.test.ts +66 -0
  37. package/src/export-print.ts +132 -0
  38. package/src/export-serialize.test.ts +56 -0
  39. package/src/export-serialize.ts +24 -0
  40. package/src/export-xls.ts +196 -0
  41. package/src/export-xlsx-roundtrip.test.ts +120 -0
  42. package/src/export-xlsx.test.ts +150 -0
  43. package/src/export.test.ts +349 -0
  44. package/src/export.ts +1452 -549
  45. package/src/import-automap.test.ts +131 -0
  46. package/src/import-hardening.test.ts +158 -0
  47. package/src/import.ts +1042 -648
  48. package/src/index.ts +282 -0
  49. package/src/install.ts +134 -114
  50. package/src/license-core.test.ts +23 -0
  51. package/src/license-core.ts +35 -0
  52. package/src/license.ts +103 -90
  53. package/src/master-detail.test.ts +61 -0
  54. package/src/master-detail.ts +42 -0
  55. package/src/print.ts +107 -127
  56. package/src/schema-designer.test.ts +121 -0
  57. package/src/schema-designer.ts +142 -0
  58. package/src/schema.test.ts +268 -0
  59. package/src/schema.ts +499 -0
  60. package/src/smart-shim.ts +107 -105
  61. package/src/sources/aggregate.test.ts +79 -0
  62. package/src/sources/aggregate.ts +102 -0
  63. package/src/sources/auth-supabase.test.ts +80 -0
  64. package/src/sources/auth-supabase.ts +87 -0
  65. package/src/sources/dashboard.kpi.test.ts +50 -0
  66. package/src/sources/dashboard.test.ts +61 -0
  67. package/src/sources/dashboard.ts +136 -0
  68. package/src/sources/field-inference.test.ts +60 -0
  69. package/src/sources/field-inference.ts +63 -0
  70. package/src/sources/filters.test.ts +58 -0
  71. package/src/sources/filters.ts +64 -0
  72. package/src/sources/index.ts +67 -0
  73. package/src/sources/introspect-supabase.test.ts +100 -0
  74. package/src/sources/introspect-supabase.ts +119 -0
  75. package/src/sources/realtime-supabase.test.ts +93 -0
  76. package/src/sources/realtime-supabase.ts +99 -0
  77. package/src/sources/relation-lookup.test.ts +99 -0
  78. package/src/sources/relation-lookup.ts +128 -0
  79. package/src/sources/rest-adapters.test.ts +95 -0
  80. package/src/sources/rest-adapters.ts +120 -0
  81. package/src/sources/rest.test.ts +104 -0
  82. package/src/sources/rest.ts +129 -0
  83. package/src/sources/schema-from-columns.test.ts +106 -0
  84. package/src/sources/schema-from-columns.ts +88 -0
  85. package/src/sources/supabase.test.ts +110 -0
  86. package/src/sources/supabase.ts +99 -0
  87. package/src/sources/with-entity-rules.test.ts +104 -0
  88. package/src/sources/with-entity-rules.ts +78 -0
  89. package/src/sources/with-relation-labels.test.ts +75 -0
  90. package/src/sources/with-relation-labels.ts +73 -0
  91. package/src/studio/bug-report.test.ts +101 -0
  92. package/src/studio/bug-report.ts +165 -0
  93. package/src/studio/cli.test.ts +187 -0
  94. package/src/studio/cli.ts +112 -0
  95. package/src/studio/csv.test.ts +90 -0
  96. package/src/studio/csv.ts +165 -0
  97. package/src/studio/db-connect-string.test.ts +94 -0
  98. package/src/studio/db-connect-string.ts +128 -0
  99. package/src/studio/emit-project.test.ts +923 -0
  100. package/src/studio/emit-project.ts +1273 -0
  101. package/src/studio/emit-schema.test.ts +94 -0
  102. package/src/studio/emit-schema.ts +920 -0
  103. package/src/studio/index.ts +195 -0
  104. package/src/studio/introspect-db.test.ts +186 -0
  105. package/src/studio/introspect-db.ts +312 -0
  106. package/src/studio/introspect-prisma.test.ts +99 -0
  107. package/src/studio/introspect-prisma.ts +175 -0
  108. package/src/studio/introspect.test.ts +172 -0
  109. package/src/studio/introspect.ts +310 -0
  110. package/src/studio/pipeline.test.ts +42 -0
  111. package/src/studio/project-robust.test.ts +157 -0
  112. package/src/studio/project.test.ts +473 -0
  113. package/src/studio/project.ts +916 -0
  114. package/src/studio/sample-data.test.ts +58 -0
  115. package/src/studio/sample-data.ts +200 -0
  116. package/src/studio/samples/ats.ts +202 -0
  117. package/src/studio/samples/clinic.ts +177 -0
  118. package/src/studio/samples/crm.ts +250 -0
  119. package/src/studio/samples/ecommerce.ts +187 -0
  120. package/src/studio/samples/events.ts +199 -0
  121. package/src/studio/samples/fleet.ts +184 -0
  122. package/src/studio/samples/gym.ts +213 -0
  123. package/src/studio/samples/hr.ts +193 -0
  124. package/src/studio/samples/index.ts +55 -0
  125. package/src/studio/samples/insurance.ts +195 -0
  126. package/src/studio/samples/inventory.ts +182 -0
  127. package/src/studio/samples/invoicing.ts +162 -0
  128. package/src/studio/samples/library.ts +180 -0
  129. package/src/studio/samples/live-data.test.ts +98 -0
  130. package/src/studio/samples/live-data.ts +308 -0
  131. package/src/studio/samples/projects.ts +190 -0
  132. package/src/studio/samples/realestate.ts +196 -0
  133. package/src/studio/samples/restaurant.ts +187 -0
  134. package/src/studio/samples/samples.test.ts +208 -0
  135. package/src/studio/samples/school.ts +197 -0
  136. package/src/studio/samples/seed-floor.test.ts +25 -0
  137. package/src/studio/samples/shared.ts +305 -0
  138. package/src/studio/samples/subscriptions.ts +183 -0
  139. package/src/studio/samples/support.ts +182 -0
  140. package/src/studio/scaffold-app.test.ts +91 -0
  141. package/src/studio/scaffold-app.ts +161 -0
  142. package/src/studio/scaffold.test.ts +178 -0
  143. package/src/studio/scaffold.ts +374 -0
  144. package/src/studio/themes.ts +172 -0
  145. package/src/studio/verify.test.ts +47 -0
  146. package/src/studio/verify.ts +79 -0
  147. package/src/sveltekit/in-memory.test.ts +104 -0
  148. package/src/sveltekit/in-memory.ts +129 -0
  149. package/src/sveltekit/index.ts +23 -0
  150. package/src/sveltekit/query-plan.test.ts +109 -0
  151. package/src/sveltekit/query-plan.ts +125 -0
  152. package/src/sveltekit/sql-source.test.ts +185 -0
  153. package/src/sveltekit/sql-source.ts +166 -0
  154. package/src/sveltekit/sql.test.ts +80 -0
  155. package/src/sveltekit/sql.ts +131 -0
  156. package/src/sveltekit/transport.test.ts +175 -0
  157. package/src/sveltekit/transport.ts +254 -0
  158. package/src/sveltekit/types.ts +11 -0
  159. package/src/upgrade-prompt.ts +149 -148
@@ -0,0 +1,110 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
2
+
3
+ // Capture downloads instead of touching the DOM (aiExport -> exportGrid).
4
+ const downloads: Array<{ text: string; filename: string }> = []
5
+ vi.mock('./export-serialize', async (importOriginal) => {
6
+ const actual = (await importOriginal()) as Record<string, unknown>
7
+ return {
8
+ ...actual,
9
+ downloadTextFile: (text: string, filename: string) => {
10
+ downloads.push({ text, filename })
11
+ },
12
+ }
13
+ })
14
+
15
+ import { aiExport, aiFindAnomalies, setAIProvider, mockAIProvider } from './ai'
16
+ import { setLicenseKey } from './license'
17
+
18
+ type Row = { region: string; amount: number; name: string }
19
+ const rows: Row[] = [
20
+ { region: 'EMEA', amount: 100, name: 'A' },
21
+ { region: 'NA', amount: 2000, name: 'B' },
22
+ { region: 'EMEA', amount: 50, name: 'C' },
23
+ ]
24
+
25
+ function makeApi() {
26
+ return {
27
+ getData: () => rows,
28
+ getDisplayedRows: () => rows,
29
+ getSelectedRows: () => [],
30
+ getColumns: () => [
31
+ { id: 'region', field: 'region', header: 'Region', visible: true },
32
+ { id: 'amount', field: 'amount', header: 'Amount', visible: true },
33
+ { id: 'name', field: 'name', header: 'Name', visible: true },
34
+ ],
35
+ getState: () => ({ grouping: [] }),
36
+ clearAllFilters: vi.fn(),
37
+ clearSort: vi.fn(),
38
+ setFilter: vi.fn(),
39
+ setSort: vi.fn(),
40
+ } as any
41
+ }
42
+
43
+ beforeEach(() => {
44
+ downloads.length = 0
45
+ setLicenseKey('SVENTERPRISE-DEV-TEST')
46
+ setAIProvider(mockAIProvider)
47
+ })
48
+ afterEach(() => setAIProvider(null))
49
+
50
+ describe('aiExport', () => {
51
+ it('parses format + groupBy + filters; applies to the grid only when asked', async () => {
52
+ const api = makeApi()
53
+ const plan = await aiExport(api, 'export deals over 500 grouped by region as a pdf', {
54
+ run: false,
55
+ apply: true,
56
+ })
57
+ expect(plan.format).toBe('pdf')
58
+ expect(plan.groupBy).toEqual(['region'])
59
+ expect(plan.filters).toContainEqual({ field: 'amount', operator: 'greaterThan', value: '500' })
60
+ // apply: true -> the grid is mutated
61
+ expect(api.clearAllFilters).toHaveBeenCalled()
62
+ expect(api.setFilter).toHaveBeenCalledWith('amount', { operator: 'greaterThan', value: '500' })
63
+ // run:false -> nothing downloaded
64
+ expect(downloads).toHaveLength(0)
65
+ })
66
+
67
+ it('defaults to xlsx and does NOT touch the grid (apply defaults off)', async () => {
68
+ const api = makeApi()
69
+ const plan = await aiExport(api, 'just export everything', { run: false })
70
+ expect(plan.format).toBe('xlsx')
71
+ expect(api.clearAllFilters).not.toHaveBeenCalled()
72
+ expect(api.setFilter).not.toHaveBeenCalled()
73
+ })
74
+
75
+ it('runs the export (downloads) when run is not false', async () => {
76
+ const api = makeApi()
77
+ await aiExport(api, 'export as csv', { filename: 'report' })
78
+ expect(downloads).toHaveLength(1)
79
+ expect(downloads[0]!.filename).toBe('report.csv')
80
+ })
81
+
82
+ it('exports the plan-filtered rows directly (not the grid displayed rows)', async () => {
83
+ // getDisplayedRows returns EVERYTHING (as if the grid hadn't re-filtered);
84
+ // the export must still contain only rows matching the plan's filter.
85
+ const api = makeApi()
86
+ await aiExport(api, 'export deals over 500 as csv', { filename: 'big' })
87
+ const { text } = downloads[0]!
88
+ expect(text).toContain('2000') // amount 2000 > 500 kept
89
+ expect(text).not.toContain('100') // amount 100 filtered out
90
+ expect(text).not.toContain('50') // amount 50 filtered out
91
+ })
92
+ })
93
+
94
+ describe('aiFindAnomalies', () => {
95
+ it('flags a numeric outlier over the scanned rows', async () => {
96
+ const api = makeApi()
97
+ const result = await aiFindAnomalies(api, {})
98
+ expect(result.anomalies.length).toBeGreaterThan(0)
99
+ const amountAnomaly = result.anomalies.find((a) => a.field === 'amount')
100
+ expect(amountAnomaly?.value).toBe(2000) // the max in the sample
101
+ expect(amountAnomaly?.severity).toBe('medium')
102
+ expect(result.summary).toBeTruthy()
103
+ })
104
+
105
+ it('returns empty for an empty selection', async () => {
106
+ const api = makeApi()
107
+ const result = await aiFindAnomalies(api, { target: { kind: 'selection', rowIndices: [] } })
108
+ expect(result.anomalies).toEqual([])
109
+ })
110
+ })