@stacksjs/defaults 0.75.243 → 0.75.244
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.
- package/ai/skills/stacks-native/CATALOG.md +2 -2
- package/app/Actions/Dashboard/DashboardHomeAction.ts +7 -1
- package/app/Models/QueryLog.ts +10 -0
- package/functions/dashboard.ts +10 -1
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
- package/resources/components/Dashboard/Home/DashboardHome.stx +20 -2
- package/resources/functions/dashboard/toggles.ts +47 -11
|
@@ -65,7 +65,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
|
|
|
65
65
|
| `@stacksjs/newsletter` | [`stacks-newsletter`](../stacks-newsletter/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/newsletter/src/index.ts) | 7 |
|
|
66
66
|
| `@stacksjs/notifications` | [`stacks-notifications`](../stacks-notifications/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/index.ts) | 16 |
|
|
67
67
|
| `@stacksjs/objects` | [`stacks-objects`](../stacks-objects/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/objects/src/index.ts) | 4 |
|
|
68
|
-
| `@stacksjs/orm` | [`stacks-orm`](../stacks-orm/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/index.ts) |
|
|
68
|
+
| `@stacksjs/orm` | [`stacks-orm`](../stacks-orm/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/index.ts) | 64 |
|
|
69
69
|
| `@stacksjs/pagination` | [`stacks-pagination`](../stacks-pagination/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/pagination/src/index.ts) | 0 |
|
|
70
70
|
| `@stacksjs/path` | [`stacks-path`](../stacks-path/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/path/src/index.ts) | 11 |
|
|
71
71
|
| `@stacksjs/payments` | [`stacks-payments`](../stacks-payments/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/payments/src/index.ts) | 28 |
|
|
@@ -633,7 +633,7 @@ Declared runtime exports: `Activity`, `AnalyticsEvent`, `Auction`, `AuctionItem`
|
|
|
633
633
|
|
|
634
634
|
Local source modules: [src/auto-crud.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/auto-crud.ts), [src/batch-loader.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/batch-loader.ts), [src/db.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/db.ts), [src/define-model.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/define-model.ts), [src/extend-model.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/extend-model.ts), [src/gdpr/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/gdpr/index.ts), [src/generate-database-schema.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/generate-database-schema.ts), [src/locked-row.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/locked-row.ts), [src/messaging.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/messaging.ts), [src/model-types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/model-types.ts), [src/ownership.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/ownership.ts), [src/paginator-request.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/paginator-request.ts), [src/row-token.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/row-token.ts), [src/subquery.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/subquery.ts), [src/traits/audit.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/traits/audit.ts), [src/traits/billable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/traits/billable.ts), [src/traits/categorizable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/traits/categorizable.ts), [src/traits/commentable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/traits/commentable.ts), [src/traits/likeable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/traits/likeable.ts), [src/traits/taggable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/traits/taggable.ts), [src/transaction.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/transaction.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/types.ts), [src/utils/encrypted.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/utils/encrypted.ts), [src/utils/prunable.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/utils/prunable.ts).
|
|
635
635
|
|
|
636
|
-
Evidence directory: [
|
|
636
|
+
Evidence directory: [64 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
|
|
637
637
|
|
|
638
638
|
### @stacksjs/pagination
|
|
639
639
|
|
|
@@ -193,6 +193,12 @@ export default new Action({
|
|
|
193
193
|
})
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
|
|
196
|
+
// Which feature-backed sections exist, so the home page does not offer a
|
|
197
|
+
// card for a section the sidebar has hidden and whose pages cannot load.
|
|
198
|
+
// `feature()` is server-side only, and this component runs on the client.
|
|
199
|
+
// See stacksjs/stacks#2928.
|
|
200
|
+
const sections = { commerce, content: feature('cms'), marketing: feature('marketing') }
|
|
201
|
+
|
|
202
|
+
return { stats, httpMetrics, services, activities, issues, sections }
|
|
197
203
|
},
|
|
198
204
|
})
|
package/app/Models/QueryLog.ts
CHANGED
|
@@ -142,38 +142,48 @@ export default defineModel({
|
|
|
142
142
|
rule: schema.string().max(255),
|
|
143
143
|
},
|
|
144
144
|
},
|
|
145
|
+
// `text`, all of these: an EXPLAIN plan, the tables a query touched and the
|
|
146
|
+
// suggestions made about it run past the varchar(255) Postgres enforces, and
|
|
147
|
+
// a log row that does not fit is dropped ("value too long for type character
|
|
148
|
+
// varying(255)") - losing exactly the slow queries this table exists for.
|
|
145
149
|
tags: {
|
|
146
150
|
fillable: true,
|
|
151
|
+
type: 'text',
|
|
147
152
|
validation: {
|
|
148
153
|
rule: schema.string(),
|
|
149
154
|
},
|
|
150
155
|
},
|
|
151
156
|
affected_tables: {
|
|
152
157
|
fillable: true,
|
|
158
|
+
type: 'text',
|
|
153
159
|
validation: {
|
|
154
160
|
rule: schema.string(),
|
|
155
161
|
},
|
|
156
162
|
},
|
|
157
163
|
indexes_used: {
|
|
158
164
|
fillable: true,
|
|
165
|
+
type: 'text',
|
|
159
166
|
validation: {
|
|
160
167
|
rule: schema.string(),
|
|
161
168
|
},
|
|
162
169
|
},
|
|
163
170
|
missing_indexes: {
|
|
164
171
|
fillable: true,
|
|
172
|
+
type: 'text',
|
|
165
173
|
validation: {
|
|
166
174
|
rule: schema.string(),
|
|
167
175
|
},
|
|
168
176
|
},
|
|
169
177
|
explain_plan: {
|
|
170
178
|
fillable: true,
|
|
179
|
+
type: 'text',
|
|
171
180
|
validation: {
|
|
172
181
|
rule: schema.string(),
|
|
173
182
|
},
|
|
174
183
|
},
|
|
175
184
|
optimization_suggestions: {
|
|
176
185
|
fillable: true,
|
|
186
|
+
type: 'text',
|
|
177
187
|
validation: {
|
|
178
188
|
rule: schema.string(),
|
|
179
189
|
},
|
package/functions/dashboard.ts
CHANGED
|
@@ -39,6 +39,11 @@ export interface DashboardIssue {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
interface DashboardHomeResponse {
|
|
42
|
+
/**
|
|
43
|
+
* Which feature-backed sections the server has available, so the home page
|
|
44
|
+
* only offers cards for sections that exist. See stacksjs/stacks#2928.
|
|
45
|
+
*/
|
|
46
|
+
sections?: Record<string, boolean>
|
|
42
47
|
stats?: Array<{ label: string, value: string }>
|
|
43
48
|
httpMetrics?: DashboardHttpMetric[]
|
|
44
49
|
services?: SystemHealthItem[]
|
|
@@ -98,6 +103,7 @@ export async function fetchDashboardHome(): Promise<DashboardHomeResponse> {
|
|
|
98
103
|
}
|
|
99
104
|
|
|
100
105
|
export function useDashboard() {
|
|
106
|
+
const sections = ref<Record<string, boolean>>({})
|
|
101
107
|
const stats = ref<DashboardStats[]>([])
|
|
102
108
|
const httpMetrics = ref<DashboardHttpMetric[]>([])
|
|
103
109
|
const recentActivity = ref<ActivityItem[]>([])
|
|
@@ -109,6 +115,7 @@ export function useDashboard() {
|
|
|
109
115
|
async function fetchDashboardStats(timeRange = '7d') {
|
|
110
116
|
void timeRange
|
|
111
117
|
const data = await fetchDashboardHome()
|
|
118
|
+
sections.value = data.sections && typeof data.sections === 'object' ? data.sections : {}
|
|
112
119
|
stats.value = normalizeStats(data.stats)
|
|
113
120
|
issues.value = Array.isArray(data.issues) ? data.issues : []
|
|
114
121
|
}
|
|
@@ -132,7 +139,8 @@ export function useDashboard() {
|
|
|
132
139
|
|
|
133
140
|
try {
|
|
134
141
|
const data = await fetchDashboardHome()
|
|
135
|
-
|
|
142
|
+
sections.value = data.sections && typeof data.sections === 'object' ? data.sections : {}
|
|
143
|
+
stats.value = normalizeStats(data.stats)
|
|
136
144
|
httpMetrics.value = Array.isArray(data.httpMetrics) ? data.httpMetrics : []
|
|
137
145
|
recentActivity.value = normalizeActivities(data.activities)
|
|
138
146
|
systemHealth.value = Array.isArray(data.services) ? data.services : []
|
|
@@ -157,6 +165,7 @@ export function useDashboard() {
|
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
return {
|
|
168
|
+
sections,
|
|
160
169
|
stats,
|
|
161
170
|
httpMetrics,
|
|
162
171
|
recentActivity,
|
package/ide/vscode/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"publisher": "Stacks",
|
|
3
3
|
"name": "vscode-stacks",
|
|
4
4
|
"displayName": "Stacks",
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.244",
|
|
6
6
|
"description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.244",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@iconify-json/f7": "^1.2.2",
|
|
46
46
|
"@iconify-json/hugeicons": "^1.2.35",
|
|
47
|
-
"@stacksjs/mobile": "0.75.
|
|
47
|
+
"@stacksjs/mobile": "0.75.244",
|
|
48
48
|
"@stacksjs/sanitizer": "^0.2.534",
|
|
49
49
|
"@xterm/addon-fit": "^0.11.0",
|
|
50
50
|
"@xterm/xterm": "^6.0.0",
|
|
@@ -4,13 +4,20 @@ import { useDashboard } from '../../../../functions/dashboard'
|
|
|
4
4
|
const dashboard = useDashboard()
|
|
5
5
|
const loadingCards = [1, 2, 3, 4]
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* `section` names the feature-backed dashboard section a card belongs to.
|
|
9
|
+
* A card with one is only offered when the server says that section exists -
|
|
10
|
+
* otherwise the home page links to pages the sidebar has hidden and that
|
|
11
|
+
* cannot load. See stacksjs/stacks#2928.
|
|
12
|
+
*/
|
|
13
|
+
const allQuickLinks = [
|
|
8
14
|
{
|
|
9
15
|
title: 'Blog',
|
|
10
16
|
description: 'Manage persisted posts',
|
|
11
17
|
href: '/content/dashboard',
|
|
12
18
|
icon: 'i-hugeicons-book-open-01',
|
|
13
19
|
tone: 'blue',
|
|
20
|
+
section: 'content',
|
|
14
21
|
},
|
|
15
22
|
{
|
|
16
23
|
title: 'Commerce',
|
|
@@ -18,6 +25,7 @@ const quickLinks = [
|
|
|
18
25
|
href: '/commerce/dashboard',
|
|
19
26
|
icon: 'i-hugeicons-store-01',
|
|
20
27
|
tone: 'green',
|
|
28
|
+
section: 'commerce',
|
|
21
29
|
},
|
|
22
30
|
{
|
|
23
31
|
title: 'Cloud',
|
|
@@ -35,6 +43,16 @@ const quickLinks = [
|
|
|
35
43
|
},
|
|
36
44
|
]
|
|
37
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Cards without a `section` are always offered. A card with one waits for the
|
|
48
|
+
* server to say that section exists, so the home page never links to a
|
|
49
|
+
* section the sidebar has hidden and whose pages cannot load.
|
|
50
|
+
*/
|
|
51
|
+
function quickLinks() {
|
|
52
|
+
const available = dashboard.sections.value
|
|
53
|
+
return allQuickLinks.filter(link => !link.section || available[link.section] !== false)
|
|
54
|
+
}
|
|
55
|
+
|
|
38
56
|
const resourceLinks = [
|
|
39
57
|
{
|
|
40
58
|
title: 'Documentation',
|
|
@@ -153,7 +171,7 @@ onMount(() => {
|
|
|
153
171
|
</div>
|
|
154
172
|
</section>
|
|
155
173
|
|
|
156
|
-
<QuickLinks class="mb-8" :links="quickLinks" />
|
|
174
|
+
<QuickLinks class="mb-8" :links="quickLinks()" />
|
|
157
175
|
|
|
158
176
|
<div class="grid gap-6 grid-cols-1 lg:grid-cols-2 mt-8">
|
|
159
177
|
<ServiceHealth :services="services()" :loading="dashboard.isLoading.value" />
|
|
@@ -45,12 +45,46 @@ export interface ResolvedDashboardToggles {
|
|
|
45
45
|
data: DashboardDataRowToggles
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Dashboard sections that mirror an installable feature.
|
|
50
|
+
*
|
|
51
|
+
* A section whose feature is off used to stay in the sidebar anyway, and every
|
|
52
|
+
* page under it failed: the models those pages query are never loaded, so the
|
|
53
|
+
* first call came back `Manufacturer.orderByDesc is not a function` and the
|
|
54
|
+
* endpoint 503'd. Switching commerce off took two edits in two files -
|
|
55
|
+
* `config/commerce.ts` and `config/dashboard.ts` - and missing the second left
|
|
56
|
+
* a Commerce section that could not load. See stacksjs/stacks#2928.
|
|
57
|
+
*
|
|
58
|
+
* `library`, `analytics`, `management` and `utilities` are deliberately absent:
|
|
59
|
+
* they have no feature of their own, so they stay on.
|
|
60
|
+
*/
|
|
61
|
+
const FEATURE_BACKED_SECTIONS = {
|
|
62
|
+
commerce: 'commerce',
|
|
63
|
+
content: 'cms',
|
|
64
|
+
marketing: 'marketing',
|
|
65
|
+
} as const
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Reads whether a feature is on. Supplied by the caller rather than imported,
|
|
69
|
+
* because this module is loaded on the dashboard's synchronous path and stays
|
|
70
|
+
* free of `@stacksjs/*` imports - its sibling `sidebar.ts` says why.
|
|
71
|
+
*
|
|
72
|
+
* Omitted, every section defaults on exactly as it did before.
|
|
73
|
+
*/
|
|
74
|
+
export type FeatureResolver = (name: string) => boolean
|
|
75
|
+
|
|
76
|
+
function sectionFallback(section: keyof typeof FEATURE_BACKED_SECTIONS, isFeatureEnabled?: FeatureResolver): boolean {
|
|
77
|
+
if (!isFeatureEnabled)
|
|
78
|
+
return true
|
|
79
|
+
return isFeatureEnabled(FEATURE_BACKED_SECTIONS[section])
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function defaultDashboardToggles(isFeatureEnabled?: FeatureResolver): ResolvedDashboardToggles {
|
|
49
83
|
return {
|
|
50
84
|
library: true,
|
|
51
|
-
content:
|
|
52
|
-
commerce:
|
|
53
|
-
marketing:
|
|
85
|
+
content: sectionFallback('content', isFeatureEnabled),
|
|
86
|
+
commerce: sectionFallback('commerce', isFeatureEnabled),
|
|
87
|
+
marketing: sectionFallback('marketing', isFeatureEnabled),
|
|
54
88
|
analytics: true,
|
|
55
89
|
management: true,
|
|
56
90
|
utilities: true,
|
|
@@ -66,7 +100,7 @@ export function defaultDashboardToggles(): ResolvedDashboardToggles {
|
|
|
66
100
|
}
|
|
67
101
|
}
|
|
68
102
|
|
|
69
|
-
export function resolveDashboardToggles(value: unknown): ResolvedDashboardToggles {
|
|
103
|
+
export function resolveDashboardToggles(value: unknown, isFeatureEnabled?: FeatureResolver): ResolvedDashboardToggles {
|
|
70
104
|
const config = objectValue(value, 'dashboard config')
|
|
71
105
|
const sections = config.sections === undefined
|
|
72
106
|
? {}
|
|
@@ -77,9 +111,11 @@ export function resolveDashboardToggles(value: unknown): ResolvedDashboardToggle
|
|
|
77
111
|
|
|
78
112
|
return {
|
|
79
113
|
library: sectionEnabled(sections.library, 'library', true),
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
114
|
+
// An explicit `enabled` in config/dashboard.ts still wins, both ways: an
|
|
115
|
+
// app can show a section whose feature is off, or hide one that is on.
|
|
116
|
+
content: sectionEnabled(sections.content, 'content', sectionFallback('content', isFeatureEnabled)),
|
|
117
|
+
commerce: sectionEnabled(sections.commerce, 'commerce', sectionFallback('commerce', isFeatureEnabled)),
|
|
118
|
+
marketing: sectionEnabled(sections.marketing, 'marketing', sectionFallback('marketing', isFeatureEnabled)),
|
|
83
119
|
analytics: sectionEnabled(sections.analytics, 'analytics', true),
|
|
84
120
|
management: sectionEnabled(sections.management, 'management', true),
|
|
85
121
|
utilities: sectionEnabled(sections.utilities, 'utilities', true),
|
|
@@ -157,16 +193,16 @@ export interface LoadedDashboardConfig {
|
|
|
157
193
|
* One import rather than two: the config module is cache-busted on mtime, so a
|
|
158
194
|
* second load of the same file would be a second evaluation of user code.
|
|
159
195
|
*/
|
|
160
|
-
export async function loadDashboardConfig(configPath: string): Promise<LoadedDashboardConfig> {
|
|
196
|
+
export async function loadDashboardConfig(configPath: string, isFeatureEnabled?: FeatureResolver): Promise<LoadedDashboardConfig> {
|
|
161
197
|
if (!existsSync(configPath))
|
|
162
|
-
return { toggles: defaultDashboardToggles(), nav: [] }
|
|
198
|
+
return { toggles: defaultDashboardToggles(isFeatureEnabled), nav: [] }
|
|
163
199
|
|
|
164
200
|
try {
|
|
165
201
|
const moduleUrl = pathToFileURL(configPath)
|
|
166
202
|
moduleUrl.searchParams.set('dashboard-config-mtime', String(statSync(configPath).mtimeMs))
|
|
167
203
|
const configModule = await import(moduleUrl.href) as { default?: unknown }
|
|
168
204
|
return {
|
|
169
|
-
toggles: resolveDashboardToggles(configModule.default),
|
|
205
|
+
toggles: resolveDashboardToggles(configModule.default, isFeatureEnabled),
|
|
170
206
|
nav: resolveDashboardNav(configModule.default),
|
|
171
207
|
}
|
|
172
208
|
}
|