@beechcms/api 0.6.0-preview.1 → 0.6.0-preview.2
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/assets/dashboard/BeechLogo.svg +18 -18
- package/assets/dashboard/BeechLogoLIght.svg +48 -48
- package/assets/dashboard/assets/chart-BrJFdsGZ.js +39 -0
- package/assets/dashboard/assets/index-CIaoMxuB.css +1 -0
- package/assets/dashboard/assets/index-wTKgygsg.js +636 -0
- package/assets/dashboard/assets/pie-chart-recharts-BEaE1FOE.js +1 -0
- package/assets/dashboard/assets/timeseries-chart-recharts-DmWM6imF.js +1 -0
- package/assets/dashboard/beechLogoDark.svg +48 -48
- package/assets/dashboard/index.html +18 -18
- package/assets/dashboard/noResult.svg +42 -42
- package/assets/dashboard/sol.svg +3 -3
- package/assets/dashboard/undraw_enter_nwx3.svg +36 -36
- package/migrations/0000_v040_base.sql +265 -265
- package/migrations/0029_automations.sql +14 -14
- package/migrations/0030_test_seeds.sql +125 -125
- package/package.json +2 -2
- package/src/auth/__fixtures__/in-memory-hash-provider.ts +17 -17
- package/src/auth/__fixtures__/static-token-service.ts +22 -22
- package/src/auth/bcrypt-hash-provider.ts +24 -24
- package/src/auth/constants.ts +14 -14
- package/src/auth/generate-refresh-token.test.ts +23 -23
- package/src/auth/hash-provider.test.ts +55 -55
- package/src/auth/jose-token-service.ts +62 -62
- package/src/auth/jwt-claims-passthrough.test.ts +87 -87
- package/src/auth/login.test.ts +100 -100
- package/src/auth/login.ts +78 -78
- package/src/auth/refresh.ts +11 -11
- package/src/auth/token-service.test.ts +90 -90
- package/src/factory.ts +370 -368
- package/src/features/automations/__tests__/action-executors.test.ts +255 -255
- package/src/features/automations/__tests__/automation-runner.test.ts +196 -196
- package/src/features/automations/__tests__/automation-runner.utils.test.ts +60 -60
- package/src/features/automations/__tests__/automations.handler.test.ts +264 -264
- package/src/features/automations/__tests__/automations.repository.test.ts +163 -163
- package/src/features/automations/__tests__/automations.schema.test.ts +224 -224
- package/src/features/automations/__tests__/context-resolver.test.ts +126 -126
- package/src/features/automations/__tests__/cron-runner.test.ts +267 -267
- package/src/features/automations/__tests__/cron-runner.utils.test.ts +144 -144
- package/src/features/automations/__tests__/set-variable.executor.test.ts +383 -383
- package/src/features/automations/__tests__/template-grammar.test.ts +308 -308
- package/src/features/automations/__tests__/webhook.executor.test.ts +142 -142
- package/src/features/automations/__tests__/when-evaluator.test.ts +274 -274
- package/src/features/automations/__tests__/when-pushdown.test.ts +281 -281
- package/src/features/automations/action-executors/create-entry.executor.ts +27 -27
- package/src/features/automations/action-executors/edit-field.executor.ts +26 -26
- package/src/features/automations/action-executors/index.ts +37 -37
- package/src/features/automations/action-executors/send-mail.executor.ts +53 -53
- package/src/features/automations/action-executors/set-variable.executor.ts +159 -159
- package/src/features/automations/action-executors/webhook.executor.ts +67 -67
- package/src/features/automations/automation-runner.ts +85 -85
- package/src/features/automations/automation-runner.utils.ts +47 -47
- package/src/features/automations/automations.handler.ts +197 -197
- package/src/features/automations/automations.schema.ts +177 -177
- package/src/features/automations/context-resolver.ts +152 -152
- package/src/features/automations/cron-runner.ts +140 -140
- package/src/features/automations/cron-runner.utils.ts +44 -44
- package/src/features/automations/filter-translation.ts +46 -46
- package/src/features/automations/index.ts +16 -16
- package/src/features/automations/template-grammar.ts +245 -245
- package/src/features/automations/var-access-resolver.ts +140 -140
- package/src/features/automations/when-evaluator.ts +87 -87
- package/src/features/automations/when-pushdown.ts +57 -57
- package/src/features/backrefs/__tests__/backrefs.handler.test.ts +359 -359
- package/src/features/backrefs/backrefs.handler.ts +168 -168
- package/src/features/backrefs/d1-backref.repository.ts +84 -84
- package/src/features/backrefs/index.ts +5 -5
- package/src/features/content/constants.ts +16 -16
- package/src/features/content/handlers/bulk.handler.ts +185 -185
- package/src/features/content/handlers/create.ts +129 -129
- package/src/features/content/handlers/delete.ts +62 -62
- package/src/features/content/handlers/facets.ts +49 -49
- package/src/features/content/handlers/get.ts +120 -120
- package/src/features/content/handlers/helpers.test.ts +180 -180
- package/src/features/content/handlers/helpers.ts +93 -93
- package/src/features/content/handlers/list.ts +174 -174
- package/src/features/content/handlers/update.ts +174 -174
- package/src/features/content/index.ts +26 -26
- package/src/features/dashboard-layout/__tests__/dashboard-layout.handler.test.ts +388 -0
- package/src/features/dashboard-layout/dashboard-layout.handler.ts +206 -0
- package/src/features/dashboard-layout/index.ts +5 -0
- package/src/features/draft/draft.handler.ts +195 -195
- package/src/features/draft/draft.middleware.ts +66 -66
- package/src/features/draft/index.ts +5 -5
- package/src/features/email/email.provider.ts +42 -42
- package/src/features/email/email.service.ts +98 -98
- package/src/features/email/email.types.ts +119 -119
- package/src/features/email/index.ts +33 -33
- package/src/features/email/providers/resend.ts +67 -67
- package/src/features/email/providers/smtp.ts +55 -55
- package/src/features/email/templates/automation-mail.ts +19 -19
- package/src/features/email/templates/password-changed.ts +63 -63
- package/src/features/email/templates/password-reset.ts +68 -68
- package/src/features/email/templates/shell.ts +96 -96
- package/src/features/notifications/index.ts +5 -5
- package/src/features/notifications/notifications.handler.ts +105 -105
- package/src/features/password-reset/index.ts +19 -19
- package/src/features/password-reset/request.ts +92 -92
- package/src/features/password-reset/reset.ts +102 -102
- package/src/features/rotate-field/index.ts +5 -5
- package/src/features/rotate-field/rotate-field.handler.ts +132 -132
- package/src/features/rotate-field/rotate-field.schema.ts +17 -17
- package/src/features/schema/schema.handler.ts +131 -131
- package/src/features/seeds/index.ts +5 -5
- package/src/features/seeds/seeds.handler.test.ts +1199 -632
- package/src/features/seeds/seeds.handler.ts +558 -693
- package/src/features/settings/__tests__/settings.handler.test.ts +555 -555
- package/src/features/settings/settings.handler.ts +392 -392
- package/src/features/setup/index.ts +288 -204
- package/src/features/stats/index.ts +5 -5
- package/src/features/stats/stats.handler.ts +420 -420
- package/src/features/webhooks/index.ts +63 -63
- package/src/index.ts +65 -65
- package/src/media-utils.ts +82 -82
- package/src/middleware/auth-providers.middleware.test.ts +85 -0
- package/src/middleware/auth-providers.middleware.ts +45 -45
- package/src/middleware/observability.middleware.test.ts +93 -0
- package/src/middleware/observability.middleware.ts +70 -70
- package/src/middleware/rate-limit.middleware.ts +45 -45
- package/src/middleware/repository.middleware.ts +117 -114
- package/src/middleware/seed-registry.middleware.test.ts +97 -97
- package/src/middleware/seed-registry.middleware.ts +21 -21
- package/src/middleware/storage.middleware.ts +25 -25
- package/src/middleware.ts +45 -45
- package/src/public/access-policy.ts +27 -27
- package/src/public/api-key-middleware.ts +57 -57
- package/src/public/cache-utils.ts +38 -38
- package/src/public/entry-projection.ts +46 -46
- package/src/public/idempotency.ts +23 -23
- package/src/public/index.ts +16 -16
- package/src/public/problem-details.ts +124 -124
- package/src/public/public-add.ts +114 -114
- package/src/public/public-edit.ts +163 -163
- package/src/public/public-errors.ts +19 -19
- package/src/public/public-read.ts +63 -63
- package/src/public/public-routes.ts +88 -88
- package/src/public/query-builder.test.ts +224 -224
- package/src/public/query-builder.ts +156 -156
- package/src/public/rate-limit-middleware.ts +34 -34
- package/src/public/read-list.ts +54 -54
- package/src/public/read-single.ts +48 -48
- package/src/public/response-builder.ts +30 -30
- package/src/public/sanitize.ts +69 -69
- package/src/public/slug-utils.ts +18 -18
- package/src/rate-limit/cloudflare-rate-limiter.test.ts +30 -30
- package/src/rate-limit/cloudflare-rate-limiter.ts +15 -15
- package/src/rate-limit/in-memory-rate-limiter.test.ts +37 -37
- package/src/rate-limit/in-memory-rate-limiter.ts +17 -17
- package/src/rate-limit/no-op-rate-limiter.test.ts +22 -22
- package/src/rate-limit/no-op-rate-limiter.ts +11 -11
- package/src/search-utils.test.ts +211 -211
- package/src/search-utils.ts +213 -213
- package/src/search.ts +65 -65
- package/src/shared/apply-policies.test.ts +81 -81
- package/src/shared/apply-policies.ts +67 -67
- package/src/shared/automations.repository.d1.ts +150 -150
- package/src/shared/background-notification-service.test.ts +62 -62
- package/src/shared/background-notification-service.ts +52 -52
- package/src/shared/base.repository.d1.ts +32 -32
- package/src/shared/content-utils.test.ts +165 -165
- package/src/shared/content-utils.ts +86 -86
- package/src/shared/content.repository.d1.test.ts +507 -458
- package/src/shared/content.repository.d1.ts +851 -851
- package/src/shared/d1-activity-log.repository.test.ts +140 -140
- package/src/shared/d1-activity-log.repository.ts +105 -105
- package/src/shared/d1-activity-logger.test.ts +86 -86
- package/src/shared/d1-activity-logger.ts +67 -67
- package/src/shared/d1-analytics.repository.test.ts +78 -78
- package/src/shared/d1-analytics.repository.ts +85 -85
- package/src/shared/d1-content-scan.repository.test.ts +80 -80
- package/src/shared/d1-content-scan.repository.ts +37 -37
- package/src/shared/d1-notification.repository.test.ts +128 -128
- package/src/shared/d1-notification.repository.ts +118 -118
- package/src/shared/d1-password-reset-token.repository.test.ts +81 -81
- package/src/shared/d1-password-reset-token.repository.ts +56 -56
- package/src/shared/d1-search.repository.test.ts +87 -87
- package/src/shared/d1-search.repository.ts +88 -88
- package/src/shared/d1-session.repository.test.ts +125 -125
- package/src/shared/d1-session.repository.ts +102 -102
- package/src/shared/d1-setup-checklist.repository.ts +36 -36
- package/src/shared/d1-user.repository.test.ts +151 -151
- package/src/shared/d1-user.repository.ts +119 -119
- package/src/shared/d1-widget.repository.test.ts +267 -221
- package/src/shared/d1-widget.repository.ts +385 -341
- package/src/shared/dashboard-layout.repository.d1.test.ts +135 -0
- package/src/shared/dashboard-layout.repository.d1.ts +58 -0
- package/src/shared/demo-data-sql.ts +216 -54
- package/src/shared/demo-data.repository.d1.ts +20 -20
- package/src/shared/execution-context-scheduler.ts +13 -13
- package/src/shared/fixed-clock.ts +25 -25
- package/src/shared/fts-sync.ts +8 -8
- package/src/shared/idempotency.repository.d1.test.ts +83 -83
- package/src/shared/idempotency.repository.d1.ts +60 -60
- package/src/shared/in-memory-activity-logger.ts +19 -19
- package/src/shared/in-memory-notification-service.ts +19 -19
- package/src/shared/in-memory-seed.repository.ts +58 -51
- package/src/shared/media.repository.d1.test.ts +107 -107
- package/src/shared/media.repository.d1.ts +68 -68
- package/src/shared/qstash-notification-service.test.ts +67 -67
- package/src/shared/qstash-notification-service.ts +55 -55
- package/src/shared/query-utils.ts +141 -141
- package/src/shared/request-utils.ts +26 -26
- package/src/shared/schema-mutator.d1.test.ts +142 -0
- package/src/shared/schema-mutator.d1.ts +64 -64
- package/src/shared/seed-layout.repository.d1.test.ts +114 -114
- package/src/shared/seed-layout.repository.d1.ts +62 -62
- package/src/shared/seed-registry-cache.test.ts +68 -68
- package/src/shared/seed-registry-cache.ts +49 -49
- package/src/shared/seed.repository.d1.test.ts +143 -143
- package/src/shared/seed.repository.d1.ts +98 -98
- package/src/shared/sequential-id-generator.ts +33 -33
- package/src/shared/site-settings.repository.d1.ts +53 -53
- package/src/shared/storage/factory.ts +41 -41
- package/src/shared/storage/s3-bucket.ts +195 -195
- package/src/shared/storage-utils.ts +40 -40
- package/src/shared/system-stats.repository.d1.test.ts +58 -58
- package/src/shared/system-stats.repository.d1.ts +48 -48
- package/src/types.ts +90 -87
- package/src/upload.ts +198 -198
- package/src/widget.test.ts +85 -0
- package/src/widget.ts +251 -212
- package/assets/dashboard/assets/index-BSjk0Sx9.js +0 -634
- package/assets/dashboard/assets/index-kRCYVN2B.css +0 -1
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
-
// Copyright (c) 2024–2026 Flavio De Musso. All rights reserved.
|
|
3
|
-
// See LICENSE in the repository root for license terms.
|
|
4
|
-
|
|
5
|
-
/// <reference types="@cloudflare/workers-types" />
|
|
6
|
-
import { deserializeFromDb, serializeForDb } from '@beechcms/core'
|
|
7
|
-
import type { Seed } from '@beechcms/core'
|
|
8
|
-
import type { ContentEntry } from './query-utils'
|
|
9
|
-
|
|
10
|
-
/** Deserializza ogni branch colonna di un DB row in formato API alias. */
|
|
11
|
-
export function rowToApiData(seed: Seed, row: Record<string, unknown>): Record<string, unknown> {
|
|
12
|
-
const data: Record<string, unknown> = {}
|
|
13
|
-
for (const branch of seed.branches) {
|
|
14
|
-
data[branch.alias] = deserializeFromDb(branch, row[branch.alias] ?? null)
|
|
15
|
-
}
|
|
16
|
-
return data
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Converte un row della tabella content_{slug} in ContentEntry per le risposte API. */
|
|
20
|
-
export function rowToEntry(
|
|
21
|
-
seed: Seed,
|
|
22
|
-
row: Record<string, unknown>,
|
|
23
|
-
hasPendingDraft = false
|
|
24
|
-
): ContentEntry {
|
|
25
|
-
return {
|
|
26
|
-
id: row.id as string,
|
|
27
|
-
schema_slug: seed.slug,
|
|
28
|
-
slug: (row.slug as string | null) ?? null,
|
|
29
|
-
status: (row.status as string) ?? 'draft',
|
|
30
|
-
data: rowToApiData(seed, row),
|
|
31
|
-
hasPendingDraft,
|
|
32
|
-
created_at: (row.created_at as number | null) ?? null,
|
|
33
|
-
updated_at: (row.updated_at as number | null) ?? null,
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface InsertBindings {
|
|
38
|
-
cols: string[]
|
|
39
|
-
placeholders: string[]
|
|
40
|
-
bindings: (string | number | null)[]
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** Costruisce colonne, placeholders e bindings per INSERT INTO content_{slug}. */
|
|
44
|
-
export function buildInsertBindings(seed: Seed, payload: Record<string, unknown>): InsertBindings {
|
|
45
|
-
const cols: string[] = []
|
|
46
|
-
const placeholders: string[] = []
|
|
47
|
-
const bindings: (string | number | null)[] = []
|
|
48
|
-
for (const branch of seed.branches) {
|
|
49
|
-
if (Object.hasOwn(payload, branch.alias)) {
|
|
50
|
-
cols.push(branch.alias)
|
|
51
|
-
placeholders.push('?')
|
|
52
|
-
bindings.push(serializeForDb(branch, payload[branch.alias]))
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return { cols, placeholders, bindings }
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface UpdateBindings {
|
|
59
|
-
setClause: string
|
|
60
|
-
bindings: (string | number | null)[]
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Costruisce SET clause e bindings per UPDATE content_{slug}. */
|
|
64
|
-
export function buildUpdateBindings(seed: Seed, payload: Record<string, unknown>): UpdateBindings {
|
|
65
|
-
const setParts: string[] = []
|
|
66
|
-
const bindings: (string | number | null)[] = []
|
|
67
|
-
for (const branch of seed.branches) {
|
|
68
|
-
if (Object.hasOwn(payload, branch.alias)) {
|
|
69
|
-
setParts.push(`${branch.alias} = ?`)
|
|
70
|
-
bindings.push(serializeForDb(branch, payload[branch.alias]))
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
return { setClause: setParts.join(', '), bindings }
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** Controlla se esiste un draft pendente in content_{slug}_drafts. */
|
|
77
|
-
export async function hasDraft(db: D1Database, seed: Seed, entryId: string): Promise<boolean> {
|
|
78
|
-
if (!seed.allowDrafts) return false
|
|
79
|
-
const row = await db
|
|
80
|
-
.prepare(`SELECT 1 FROM content_${seed.slug}_drafts WHERE entry_id = ? LIMIT 1`)
|
|
81
|
-
.bind(entryId)
|
|
82
|
-
.first()
|
|
83
|
-
return row !== null
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
1
|
+
// SPDX-License-Identifier: BUSL-1.1
|
|
2
|
+
// Copyright (c) 2024–2026 Flavio De Musso. All rights reserved.
|
|
3
|
+
// See LICENSE in the repository root for license terms.
|
|
4
|
+
|
|
5
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
6
|
+
import { deserializeFromDb, serializeForDb } from '@beechcms/core'
|
|
7
|
+
import type { Seed } from '@beechcms/core'
|
|
8
|
+
import type { ContentEntry } from './query-utils'
|
|
9
|
+
|
|
10
|
+
/** Deserializza ogni branch colonna di un DB row in formato API alias. */
|
|
11
|
+
export function rowToApiData(seed: Seed, row: Record<string, unknown>): Record<string, unknown> {
|
|
12
|
+
const data: Record<string, unknown> = {}
|
|
13
|
+
for (const branch of seed.branches) {
|
|
14
|
+
data[branch.alias] = deserializeFromDb(branch, row[branch.alias] ?? null)
|
|
15
|
+
}
|
|
16
|
+
return data
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Converte un row della tabella content_{slug} in ContentEntry per le risposte API. */
|
|
20
|
+
export function rowToEntry(
|
|
21
|
+
seed: Seed,
|
|
22
|
+
row: Record<string, unknown>,
|
|
23
|
+
hasPendingDraft = false
|
|
24
|
+
): ContentEntry {
|
|
25
|
+
return {
|
|
26
|
+
id: row.id as string,
|
|
27
|
+
schema_slug: seed.slug,
|
|
28
|
+
slug: (row.slug as string | null) ?? null,
|
|
29
|
+
status: (row.status as string) ?? 'draft',
|
|
30
|
+
data: rowToApiData(seed, row),
|
|
31
|
+
hasPendingDraft,
|
|
32
|
+
created_at: (row.created_at as number | null) ?? null,
|
|
33
|
+
updated_at: (row.updated_at as number | null) ?? null,
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface InsertBindings {
|
|
38
|
+
cols: string[]
|
|
39
|
+
placeholders: string[]
|
|
40
|
+
bindings: (string | number | null)[]
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Costruisce colonne, placeholders e bindings per INSERT INTO content_{slug}. */
|
|
44
|
+
export function buildInsertBindings(seed: Seed, payload: Record<string, unknown>): InsertBindings {
|
|
45
|
+
const cols: string[] = []
|
|
46
|
+
const placeholders: string[] = []
|
|
47
|
+
const bindings: (string | number | null)[] = []
|
|
48
|
+
for (const branch of seed.branches) {
|
|
49
|
+
if (Object.hasOwn(payload, branch.alias)) {
|
|
50
|
+
cols.push(branch.alias)
|
|
51
|
+
placeholders.push('?')
|
|
52
|
+
bindings.push(serializeForDb(branch, payload[branch.alias]))
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { cols, placeholders, bindings }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface UpdateBindings {
|
|
59
|
+
setClause: string
|
|
60
|
+
bindings: (string | number | null)[]
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Costruisce SET clause e bindings per UPDATE content_{slug}. */
|
|
64
|
+
export function buildUpdateBindings(seed: Seed, payload: Record<string, unknown>): UpdateBindings {
|
|
65
|
+
const setParts: string[] = []
|
|
66
|
+
const bindings: (string | number | null)[] = []
|
|
67
|
+
for (const branch of seed.branches) {
|
|
68
|
+
if (Object.hasOwn(payload, branch.alias)) {
|
|
69
|
+
setParts.push(`${branch.alias} = ?`)
|
|
70
|
+
bindings.push(serializeForDb(branch, payload[branch.alias]))
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { setClause: setParts.join(', '), bindings }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Controlla se esiste un draft pendente in content_{slug}_drafts. */
|
|
77
|
+
export async function hasDraft(db: D1Database, seed: Seed, entryId: string): Promise<boolean> {
|
|
78
|
+
if (!seed.allowDrafts) return false
|
|
79
|
+
const row = await db
|
|
80
|
+
.prepare(`SELECT 1 FROM content_${seed.slug}_drafts WHERE entry_id = ? LIMIT 1`)
|
|
81
|
+
.bind(entryId)
|
|
82
|
+
.first()
|
|
83
|
+
return row !== null
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|