@crombolo/data 0.0.0-stage → 0.10.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.
- package/LICENSE +21 -0
- package/NOTICE +69 -0
- package/package.json +31 -4
- package/src/bundle-tables/builder.ts +264 -0
- package/src/bundle-tables/capability.ts +377 -0
- package/src/bundle-tables/chain.ts +105 -0
- package/src/bundle-tables/ddl.ts +124 -0
- package/src/bundle-tables/guard.ts +116 -0
- package/src/bundle-tables/index.ts +7 -0
- package/src/bundle-tables/names.ts +58 -0
- package/src/bundle-tables/schema.ts +485 -0
- package/src/change-report.ts +166 -0
- package/src/cluster.ts +108 -0
- package/src/database.ts +121 -0
- package/src/dialect.ts +136 -0
- package/src/index.ts +63 -0
- package/src/locks.ts +103 -0
- package/src/maintenance.ts +51 -0
- package/src/migrations.ts +547 -0
- package/src/node-ref.ts +107 -0
- package/src/pending.ts +25 -0
- package/src/repositories/bundles.ts +223 -0
- package/src/repositories/content-types.ts +831 -0
- package/src/repositories/data-types.ts +222 -0
- package/src/repositories/dictionary.ts +259 -0
- package/src/repositories/documents.ts +2389 -0
- package/src/repositories/domains.ts +108 -0
- package/src/repositories/folders.ts +120 -0
- package/src/repositories/form-entries.ts +314 -0
- package/src/repositories/form-workflows.ts +213 -0
- package/src/repositories/languages.ts +108 -0
- package/src/repositories/log-searches.ts +33 -0
- package/src/repositories/members.ts +427 -0
- package/src/repositories/nodes.ts +361 -0
- package/src/repositories/notifications.ts +54 -0
- package/src/repositories/public-access.ts +187 -0
- package/src/repositories/redirects.ts +274 -0
- package/src/repositories/references.ts +162 -0
- package/src/repositories/tags.ts +93 -0
- package/src/repositories/templates.ts +114 -0
- package/src/repositories/transfer-runs.ts +208 -0
- package/src/repositories/user-data.ts +90 -0
- package/src/repositories/users.ts +898 -0
- package/src/schema/assistant.ts +74 -0
- package/src/schema/built-in-content-types.ts +106 -0
- package/src/schema/built-in-media-types.ts +335 -0
- package/src/schema/built-in-member-types.ts +61 -0
- package/src/schema/bundle-components.ts +49 -0
- package/src/schema/bundle-package.ts +27 -0
- package/src/schema/bundles-rename.ts +32 -0
- package/src/schema/change-report.ts +46 -0
- package/src/schema/client-id-prefix.ts +43 -0
- package/src/schema/content-editing.ts +50 -0
- package/src/schema/content-seed.ts +586 -0
- package/src/schema/content.ts +263 -0
- package/src/schema/created-packages.ts +56 -0
- package/src/schema/elements.ts +62 -0
- package/src/schema/form-permission-prefix.ts +50 -0
- package/src/schema/form-permissions.ts +26 -0
- package/src/schema/form-workflows.ts +54 -0
- package/src/schema/forms.ts +63 -0
- package/src/schema/group-permissions.ts +20 -0
- package/src/schema/identity.ts +176 -0
- package/src/schema/log-viewer.ts +68 -0
- package/src/schema/member-property-type.ts +30 -0
- package/src/schema/members.ts +97 -0
- package/src/schema/plan.ts +77 -0
- package/src/schema/public-access.ts +56 -0
- package/src/schema/recycle-bin.ts +21 -0
- package/src/schema/redirects.ts +57 -0
- package/src/schema/rich-text-ui.ts +34 -0
- package/src/schema/seed.ts +298 -0
- package/src/schema/server-role.ts +21 -0
- package/src/schema/since-version.ts +26 -0
- package/src/schema/transfer-run-package.ts +27 -0
- package/src/schema/transfer-runs.ts +71 -0
- package/src/schema/upgrade-report.ts +43 -0
- package/src/schema/users-localisation.ts +85 -0
- package/src/schema/values.ts +108 -0
- package/src/schema-ops.ts +35 -0
- package/src/schema-state.ts +196 -0
- package/README.md +0 -3
package/src/pending.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An element is pending on a node when the deployment that created it is newer
|
|
3
|
+
* than the node, or its file says `since` a version the node has not reached.
|
|
4
|
+
* The one place the rule lives. docs/schema-as-code.md, "since".
|
|
5
|
+
*/
|
|
6
|
+
import { compareStates, compareVersions, type NodeSchemaState } from './schema-state.ts'
|
|
7
|
+
|
|
8
|
+
export interface SinceMarkers {
|
|
9
|
+
/** The `(version, revision)` of the state that created the row, when known. */
|
|
10
|
+
since: NodeSchemaState | null
|
|
11
|
+
/** The file's explicit `since`, when written. */
|
|
12
|
+
sinceVersion: string | null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The state the element goes live in, or null when it is live on this node. */
|
|
16
|
+
export function pendingUntil(markers: SinceMarkers, node: NodeSchemaState): NodeSchemaState | null {
|
|
17
|
+
if (markers.sinceVersion && compareVersions(markers.sinceVersion, node.version) > 0)
|
|
18
|
+
return { version: markers.sinceVersion, revision: '0' }
|
|
19
|
+
if (markers.since && compareStates(markers.since, node) > 0) return markers.since
|
|
20
|
+
return null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function isPending(markers: SinceMarkers, node: NodeSchemaState): boolean {
|
|
24
|
+
return pendingUntil(markers, node) !== null
|
|
25
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bundle definitions: what a bundle would contain, not a built bundle.
|
|
3
|
+
* `docs/bundles.md`.
|
|
4
|
+
*
|
|
5
|
+
* The selection lists travel as JSON text in single columns. A malformed list
|
|
6
|
+
* reads back as empty rather than throwing: a definition whose row was edited
|
|
7
|
+
* by hand should still list and still be deletable.
|
|
8
|
+
*/
|
|
9
|
+
import { randomUUID } from 'node:crypto'
|
|
10
|
+
import type { Db } from '../database.ts'
|
|
11
|
+
import { DbDate, fromDbBool } from '../dialect.ts'
|
|
12
|
+
|
|
13
|
+
export interface Bundle {
|
|
14
|
+
id: string
|
|
15
|
+
name: string
|
|
16
|
+
contentNodeId: string | null
|
|
17
|
+
contentLoadChildNodes: boolean
|
|
18
|
+
mediaIds: string[]
|
|
19
|
+
mediaLoadChildNodes: boolean
|
|
20
|
+
elementIds: string[] | null
|
|
21
|
+
contentTypes: string[]
|
|
22
|
+
mediaTypes: string[]
|
|
23
|
+
dataTypes: string[]
|
|
24
|
+
components: string[]
|
|
25
|
+
stylesheets: string[]
|
|
26
|
+
scripts: string[]
|
|
27
|
+
languages: string[]
|
|
28
|
+
dictionaryItems: string[]
|
|
29
|
+
/**
|
|
30
|
+
* The npm package the bundle is built as. Not in Umbraco's definition, so the
|
|
31
|
+
* contract never writes these; null until someone sets them.
|
|
32
|
+
*/
|
|
33
|
+
packageName: string | null
|
|
34
|
+
packageVersion: string | null
|
|
35
|
+
createDate: Date
|
|
36
|
+
updateDate: Date
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** A definition to store; `id` is assigned when it is new, the dates always. */
|
|
40
|
+
export type BundleInput = Omit<
|
|
41
|
+
Bundle,
|
|
42
|
+
'id' | 'createDate' | 'updateDate' | 'packageName' | 'packageVersion'
|
|
43
|
+
>
|
|
44
|
+
|
|
45
|
+
interface Row {
|
|
46
|
+
id: string
|
|
47
|
+
name: string
|
|
48
|
+
content_node_id: string | null
|
|
49
|
+
content_load_child_nodes: unknown
|
|
50
|
+
media_load_child_nodes: unknown
|
|
51
|
+
media_ids: string
|
|
52
|
+
element_ids: string | null
|
|
53
|
+
content_types: string
|
|
54
|
+
media_types: string
|
|
55
|
+
data_types: string
|
|
56
|
+
components: string
|
|
57
|
+
stylesheets: string
|
|
58
|
+
scripts: string
|
|
59
|
+
languages: string
|
|
60
|
+
dictionary_items: string
|
|
61
|
+
package_name: string | null
|
|
62
|
+
package_version: string | null
|
|
63
|
+
create_date: unknown
|
|
64
|
+
update_date: unknown
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const SELECT = `SELECT id, name, content_node_id, content_load_child_nodes,
|
|
68
|
+
media_load_child_nodes, media_ids, element_ids, content_types,
|
|
69
|
+
media_types, data_types, components, stylesheets,
|
|
70
|
+
scripts, languages, dictionary_items, package_name, package_version,
|
|
71
|
+
create_date, update_date
|
|
72
|
+
FROM bundle`
|
|
73
|
+
|
|
74
|
+
const list = (value: string | null): string[] => {
|
|
75
|
+
if (!value) return []
|
|
76
|
+
try {
|
|
77
|
+
const parsed = JSON.parse(value) as unknown
|
|
78
|
+
return Array.isArray(parsed)
|
|
79
|
+
? parsed.filter((item): item is string => typeof item === 'string')
|
|
80
|
+
: []
|
|
81
|
+
} catch {
|
|
82
|
+
return []
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const hydrate = (row: Row): Bundle => ({
|
|
87
|
+
id: row.id,
|
|
88
|
+
name: row.name,
|
|
89
|
+
contentNodeId: row.content_node_id,
|
|
90
|
+
contentLoadChildNodes: fromDbBool(row.content_load_child_nodes),
|
|
91
|
+
mediaIds: list(row.media_ids),
|
|
92
|
+
mediaLoadChildNodes: fromDbBool(row.media_load_child_nodes),
|
|
93
|
+
elementIds: row.element_ids === null ? null : list(row.element_ids),
|
|
94
|
+
contentTypes: list(row.content_types),
|
|
95
|
+
mediaTypes: list(row.media_types),
|
|
96
|
+
dataTypes: list(row.data_types),
|
|
97
|
+
components: list(row.components),
|
|
98
|
+
stylesheets: list(row.stylesheets),
|
|
99
|
+
scripts: list(row.scripts),
|
|
100
|
+
languages: list(row.languages),
|
|
101
|
+
dictionaryItems: list(row.dictionary_items),
|
|
102
|
+
packageName: row.package_name ?? null,
|
|
103
|
+
packageVersion: row.package_version ?? null,
|
|
104
|
+
createDate: DbDate.fromDb(row.create_date) ?? new Date(0),
|
|
105
|
+
updateDate: DbDate.fromDb(row.update_date) ?? new Date(0),
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
export class BundleRepository {
|
|
109
|
+
#db: Db
|
|
110
|
+
constructor(db: Db) {
|
|
111
|
+
this.#db = db
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** By name, which is the order the section lists them in. */
|
|
115
|
+
async list(
|
|
116
|
+
options: { skip?: number; take?: number } = {},
|
|
117
|
+
): Promise<{ total: number; items: Bundle[] }> {
|
|
118
|
+
const counted = await this.#db.query<{ total: number }>('SELECT COUNT(*) AS total FROM bundle')
|
|
119
|
+
const rows = await this.#db.query<Row>(`${SELECT} ORDER BY name LIMIT ? OFFSET ?`, [
|
|
120
|
+
options.take ?? 100,
|
|
121
|
+
options.skip ?? 0,
|
|
122
|
+
])
|
|
123
|
+
return { total: Number(counted[0]?.total ?? 0), items: rows.map(hydrate) }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async byId(id: string): Promise<Bundle | undefined> {
|
|
127
|
+
const rows = await this.#db.query<Row>(`${SELECT} WHERE id = ?`, [id])
|
|
128
|
+
const row = rows[0]
|
|
129
|
+
return row ? hydrate(row) : undefined
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async byName(name: string): Promise<Bundle | undefined> {
|
|
133
|
+
const rows = await this.#db.query<Row>(`${SELECT} WHERE LOWER(name) = ?`, [
|
|
134
|
+
name.trim().toLowerCase(),
|
|
135
|
+
])
|
|
136
|
+
const row = rows[0]
|
|
137
|
+
return row ? hydrate(row) : undefined
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async create(input: BundleInput, id: string = randomUUID()): Promise<Bundle> {
|
|
141
|
+
const now = new Date()
|
|
142
|
+
await this.#db.exec(
|
|
143
|
+
`INSERT INTO bundle
|
|
144
|
+
(id, name, content_node_id, content_load_child_nodes, media_load_child_nodes,
|
|
145
|
+
media_ids, element_ids, content_types, media_types, data_types, components,
|
|
146
|
+
stylesheets, scripts, languages, dictionary_items,
|
|
147
|
+
create_date, update_date)
|
|
148
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
149
|
+
[
|
|
150
|
+
id,
|
|
151
|
+
input.name,
|
|
152
|
+
input.contentNodeId,
|
|
153
|
+
this.#db.dialect.boolValue(input.contentLoadChildNodes),
|
|
154
|
+
this.#db.dialect.boolValue(input.mediaLoadChildNodes),
|
|
155
|
+
JSON.stringify(input.mediaIds),
|
|
156
|
+
input.elementIds === null ? null : JSON.stringify(input.elementIds),
|
|
157
|
+
JSON.stringify(input.contentTypes),
|
|
158
|
+
JSON.stringify(input.mediaTypes),
|
|
159
|
+
JSON.stringify(input.dataTypes),
|
|
160
|
+
JSON.stringify(input.components),
|
|
161
|
+
JSON.stringify(input.stylesheets),
|
|
162
|
+
JSON.stringify(input.scripts),
|
|
163
|
+
JSON.stringify(input.languages),
|
|
164
|
+
JSON.stringify(input.dictionaryItems),
|
|
165
|
+
DbDate.toDb(now),
|
|
166
|
+
DbDate.toDb(now),
|
|
167
|
+
],
|
|
168
|
+
)
|
|
169
|
+
return {
|
|
170
|
+
...input,
|
|
171
|
+
id,
|
|
172
|
+
packageName: null,
|
|
173
|
+
packageVersion: null,
|
|
174
|
+
createDate: now,
|
|
175
|
+
updateDate: now,
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async update(id: string, input: BundleInput): Promise<void> {
|
|
180
|
+
await this.#db.exec(
|
|
181
|
+
`UPDATE bundle
|
|
182
|
+
SET name = ?, content_node_id = ?, content_load_child_nodes = ?,
|
|
183
|
+
media_load_child_nodes = ?, media_ids = ?, element_ids = ?,
|
|
184
|
+
content_types = ?, media_types = ?, data_types = ?, components = ?,
|
|
185
|
+
stylesheets = ?, scripts = ?, languages = ?,
|
|
186
|
+
dictionary_items = ?, update_date = ?
|
|
187
|
+
WHERE id = ?`,
|
|
188
|
+
[
|
|
189
|
+
input.name,
|
|
190
|
+
input.contentNodeId,
|
|
191
|
+
this.#db.dialect.boolValue(input.contentLoadChildNodes),
|
|
192
|
+
this.#db.dialect.boolValue(input.mediaLoadChildNodes),
|
|
193
|
+
JSON.stringify(input.mediaIds),
|
|
194
|
+
input.elementIds === null ? null : JSON.stringify(input.elementIds),
|
|
195
|
+
JSON.stringify(input.contentTypes),
|
|
196
|
+
JSON.stringify(input.mediaTypes),
|
|
197
|
+
JSON.stringify(input.dataTypes),
|
|
198
|
+
JSON.stringify(input.components),
|
|
199
|
+
JSON.stringify(input.stylesheets),
|
|
200
|
+
JSON.stringify(input.scripts),
|
|
201
|
+
JSON.stringify(input.languages),
|
|
202
|
+
JSON.stringify(input.dictionaryItems),
|
|
203
|
+
DbDate.toDb(new Date()),
|
|
204
|
+
id,
|
|
205
|
+
],
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** The npm package a definition is built as; null clears a value back to its default. */
|
|
210
|
+
async setPackage(
|
|
211
|
+
id: string,
|
|
212
|
+
pkg: { name: string | null; version: string | null },
|
|
213
|
+
): Promise<void> {
|
|
214
|
+
await this.#db.exec(
|
|
215
|
+
'UPDATE bundle SET package_name = ?, package_version = ?, update_date = ? WHERE id = ?',
|
|
216
|
+
[pkg.name, pkg.version, DbDate.toDb(new Date()), id],
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
async delete(id: string): Promise<void> {
|
|
221
|
+
await this.#db.exec('DELETE FROM bundle WHERE id = ?', [id])
|
|
222
|
+
}
|
|
223
|
+
}
|