@nixxie-cms/core 1.0.0 → 1.0.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/README.md +2 -2
- package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.cjs.js +4 -4
- package/admin-ui/components/dist/nixxie-cms-core-admin-ui-components.esm.js +4 -4
- package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.cjs.js +2 -2
- package/admin-ui/context/dist/nixxie-cms-core-admin-ui-context.esm.js +2 -2
- package/context/dist/nixxie-cms-core-context.cjs.js +2 -2
- package/context/dist/nixxie-cms-core-context.esm.js +2 -2
- package/dist/{CreateItemDialog-33335548.esm.js → CreateItemDialog-7008b050.esm.js} +1 -1
- package/dist/{CreateItemDialog-56cf59b7.cjs.js → CreateItemDialog-a0cab315.cjs.js} +1 -1
- package/dist/{PageContainer-7db73317.esm.js → PageContainer-5ae731cc.esm.js} +25 -18
- package/dist/{PageContainer-27c27f10.cjs.js → PageContainer-abd7159f.cjs.js} +25 -18
- package/dist/{admin-meta-graphql-6f7f5331.esm.js → admin-meta-graphql-0e6e606e.esm.js} +1 -1
- package/dist/{admin-meta-graphql-c8f926e9.cjs.js → admin-meta-graphql-306c224a.cjs.js} +1 -1
- package/dist/{context-3132c3ed.esm.js → context-af9957ed.esm.js} +2 -2
- package/dist/{context-e7a45152.cjs.js → context-b5204629.cjs.js} +2 -2
- package/dist/declarations/src/admin-ui/components/Navigation.d.ts.map +1 -1
- package/dist/declarations/src/admin-ui/components/PageContainer.d.ts.map +1 -1
- package/dist/declarations/src/helpers.d.ts.map +1 -1
- package/dist/declarations/src/index.d.ts +1 -0
- package/dist/declarations/src/index.d.ts.map +1 -1
- package/dist/declarations/src/internal-unstable/admin-ui/id-field-view.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/App/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/CreateItemPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/HomePage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/ItemPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/ListPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/admin-ui/pages/NoAccessPage/index.d.ts.map +1 -0
- package/dist/declarations/src/internal-unstable/artifacts.d.ts.map +1 -0
- package/dist/declarations/src/lib/core/initialise-lists.d.ts +1 -1
- package/dist/declarations/src/schema.d.ts.map +1 -1
- package/dist/declarations/src/types/config/index.d.ts +60 -1
- package/dist/declarations/src/types/config/index.d.ts.map +1 -1
- package/dist/declarations/src/types/config/lists.d.ts +4 -4
- package/dist/declarations/src/types/context.d.ts +150 -0
- package/dist/declarations/src/types/context.d.ts.map +1 -1
- package/dist/declarations/src/types/next-fields.d.ts +1 -1
- package/dist/{express-e9ed9a7d.cjs.js → express-455ae20c.cjs.js} +1 -1
- package/dist/{express-6743b918.esm.js → express-7559ca2d.esm.js} +1 -1
- package/dist/{index-ac01583b.cjs.js → index-89635494.cjs.js} +4 -4
- package/dist/{index-24b78415.esm.js → index-baa799e0.esm.js} +4 -4
- package/dist/nixxie-cms-core.cjs.js +104 -77
- package/dist/nixxie-cms-core.esm.js +104 -77
- package/dist/{non-null-graphql-5315718c.esm.js → non-null-graphql-a84ed64d.esm.js} +1 -1
- package/dist/{non-null-graphql-17b83ddc.cjs.js → non-null-graphql-add6bb3d.cjs.js} +1 -1
- package/dist/{resolve-hooks-66fe8a8e.cjs.js → resolve-hooks-165a9ce2.cjs.js} +1 -1
- package/dist/{resolve-hooks-17aafd37.esm.js → resolve-hooks-6813a045.esm.js} +2 -2
- package/dist/{system-dfec2f0a.esm.js → system-03e49e4f.esm.js} +8 -4
- package/dist/{system-48c5f6df.cjs.js → system-a321642d.cjs.js} +8 -4
- package/dist/{useFilter-0b5a1ee6.esm.js → useFilter-9b6db1f9.esm.js} +1 -1
- package/dist/{useFilter-1a4e6900.cjs.js → useFilter-acc9d413.cjs.js} +1 -1
- package/fields/dist/nixxie-cms-core-fields.cjs.js +16 -16
- package/fields/dist/nixxie-cms-core-fields.esm.js +17 -17
- package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.cjs.js +3 -3
- package/fields/types/bytes/dist/nixxie-cms-core-fields-types-bytes.esm.js +3 -3
- package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.cjs.js +1 -1
- package/fields/types/bytes/views/dist/nixxie-cms-core-fields-types-bytes-views.esm.js +1 -1
- package/fields/types/password/dist/nixxie-cms-core-fields-types-password.cjs.js +3 -3
- package/fields/types/password/dist/nixxie-cms-core-fields-types-password.esm.js +3 -3
- package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.cjs.js +4 -4
- package/fields/types/relationship/views/dist/nixxie-cms-core-fields-types-relationship-views.esm.js +4 -4
- package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.cjs.js +1 -1
- package/fields/types/select/views/dist/nixxie-cms-core-fields-types-select-views.esm.js +1 -1
- package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.cjs.js +1 -1
- package/fields/types/text/views/dist/nixxie-cms-core-fields-types-text-views.esm.js +1 -1
- package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.cjs.js +244 -0
- package/internal-unstable/admin-ui/id-field-view/dist/nixxie-cms-core-internal-unstable-admin-ui-id-field-view.esm.js +235 -0
- package/internal-unstable/admin-ui/id-field-view/package.json +4 -0
- package/internal-unstable/admin-ui/next-config/package.json +4 -0
- package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.cjs.js +59 -0
- package/internal-unstable/admin-ui/pages/App/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-App.esm.js +55 -0
- package/internal-unstable/admin-ui/pages/App/package.json +4 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.cjs.js +116 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-CreateItemPage.esm.js +112 -0
- package/internal-unstable/admin-ui/pages/CreateItemPage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.cjs.js +336 -0
- package/internal-unstable/admin-ui/pages/HomePage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-HomePage.esm.js +332 -0
- package/internal-unstable/admin-ui/pages/HomePage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.cjs.js +463 -0
- package/internal-unstable/admin-ui/pages/ItemPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ItemPage.esm.js +455 -0
- package/internal-unstable/admin-ui/pages/ItemPage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.cjs.js +1195 -0
- package/internal-unstable/admin-ui/pages/ListPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-ListPage.esm.js +1187 -0
- package/internal-unstable/admin-ui/pages/ListPage/package.json +4 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.d.ts +2 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.cjs.js +40 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/dist/nixxie-cms-core-internal-unstable-admin-ui-pages-NoAccessPage.esm.js +35 -0
- package/internal-unstable/admin-ui/pages/NoAccessPage/package.json +4 -0
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.d.ts +2 -0
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.cjs.js +51 -0
- package/internal-unstable/artifacts/dist/nixxie-cms-core-internal-unstable-artifacts.esm.js +38 -0
- package/internal-unstable/artifacts/package.json +4 -0
- package/package.json +44 -44
- package/scripts/cli/dist/nixxie-cms-core-scripts-cli.cjs.js +44 -15
- package/scripts/cli/dist/nixxie-cms-core-scripts-cli.esm.js +44 -15
- package/scripts/dist/nixxie-cms-core-scripts.cjs.js +3 -3
- package/scripts/dist/nixxie-cms-core-scripts.esm.js +3 -3
- package/src/admin-ui/admin-meta-graphql.ts +168 -168
- package/src/admin-ui/components/CommandPalette.tsx +433 -431
- package/src/admin-ui/components/Navigation.tsx +389 -385
- package/src/admin-ui/components/PageContainer.tsx +311 -310
- package/src/admin-ui/components/WelcomeDialog.tsx +1 -1
- package/src/admin-ui/context.tsx +338 -338
- package/src/admin-ui/templates/app.ts +60 -60
- package/src/admin-ui/templates/create-item.ts +5 -5
- package/src/admin-ui/templates/home.ts +2 -2
- package/src/admin-ui/templates/item.tsx +5 -5
- package/src/admin-ui/templates/list.tsx +5 -5
- package/src/admin-ui/templates/next-config.ts +29 -0
- package/src/admin-ui/templates/no-access.ts +7 -7
- package/src/fields/types/bigInt/index.ts +181 -181
- package/src/fields/types/bytes/index.ts +275 -275
- package/src/fields/types/calendarDay/index.ts +194 -194
- package/src/fields/types/checkbox/index.ts +76 -76
- package/src/fields/types/decimal/index.ts +182 -182
- package/src/fields/types/file/index.ts +168 -168
- package/src/fields/types/float/index.ts +133 -133
- package/src/fields/types/image/index.ts +244 -244
- package/src/fields/types/integer/index.ts +156 -156
- package/src/fields/types/json/index.ts +77 -77
- package/src/fields/types/multiselect/index.ts +212 -212
- package/src/fields/types/password/index.ts +241 -241
- package/src/fields/types/relationship/index.ts +381 -381
- package/src/fields/types/relationship/views/RelationshipTable.tsx +190 -190
- package/src/fields/types/select/index.ts +226 -226
- package/src/fields/types/text/index.ts +207 -207
- package/src/fields/types/timestamp/index.ts +116 -116
- package/src/fields/types/virtual/index.ts +108 -108
- package/src/helpers.ts +342 -316
- package/src/index.ts +4 -0
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.tsx +167 -167
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.tsx +22 -22
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.tsx +71 -71
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.tsx +333 -333
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/common.tsx +358 -358
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.tsx +483 -483
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/FilterAdd.tsx +221 -221
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/PaginationControls.tsx +170 -170
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/Tag.tsx +72 -72
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.tsx +1006 -1006
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.tsx +24 -24
- package/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.ts +5 -5
- package/src/lib/context/createContext.ts +165 -161
- package/src/lib/core/initialise-lists.ts +1097 -1097
- package/src/lib/id-field.ts +214 -214
- package/src/lib/telemetry.ts +342 -342
- package/src/schema.ts +237 -233
- package/src/scripts/telemetry.ts +1 -1
- package/src/types/config/index.ts +400 -333
- package/src/types/config/lists.ts +4 -4
- package/src/types/context.ts +700 -530
- package/src/types/next-fields.ts +499 -499
- package/src/types/telemetry.ts +51 -51
- package/tests/telemetry.test.ts +361 -361
- package/CHANGELOG.md +0 -3158
- package/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/next-config/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/package.json +0 -4
- package/___internal-do-not-use-will-break-in-patch/artifacts/package.json +0 -4
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/id-field-view.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/App/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/CreateItemPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/HomePage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ItemPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/ListPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/admin-ui/pages/NoAccessPage/index.d.ts.map +0 -1
- package/dist/declarations/src/___internal-do-not-use-will-break-in-patch/artifacts.d.ts.map +0 -1
- /package/dist/{common-1a350e11.cjs.js → common-5933f758.cjs.js} +0 -0
- /package/dist/{common-29fc82e6.esm.js → common-ea5c441a.esm.js} +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/id-field-view.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/App/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/CreateItemPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/HomePage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ItemPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/ListPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/admin-ui/pages/NoAccessPage/index.d.ts +0 -0
- /package/dist/declarations/src/{___internal-do-not-use-will-break-in-patch → internal-unstable}/artifacts.d.ts +0 -0
package/src/types/context.ts
CHANGED
|
@@ -1,530 +1,700 @@
|
|
|
1
|
-
import type { IncomingMessage, ServerResponse } from 'http'
|
|
2
|
-
import type { DocumentNode, ExecutionResult, GraphQLSchema } from 'graphql'
|
|
3
|
-
import type { TypedDocumentNode } from '@graphql-typed-document-node/core'
|
|
4
|
-
import type { InitialisedList } from '../lib/core/initialise-lists'
|
|
5
|
-
import type { SessionStrategy } from './session'
|
|
6
|
-
import type { BaseNixxieTypeInfo, BaseListTypeInfo } from './type-info'
|
|
7
|
-
import type { MaybePromise } from './utils'
|
|
8
|
-
|
|
9
|
-
// ── Email service types (defined here so @nixxie-cms/email can implement without circular deps) ──
|
|
10
|
-
|
|
11
|
-
export type NixxieEmailRecipient = string | { name?: string; address: string }
|
|
12
|
-
|
|
13
|
-
export type NixxieEmailAttachment = {
|
|
14
|
-
filename?: string
|
|
15
|
-
content?: string | Buffer
|
|
16
|
-
path?: string
|
|
17
|
-
href?: string
|
|
18
|
-
contentType?: string
|
|
19
|
-
encoding?: string
|
|
20
|
-
contentDisposition?: 'attachment' | 'inline'
|
|
21
|
-
/** Content ID for inline embedded images (used with src="cid:…") */
|
|
22
|
-
cid?: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type NixxieEmailSendOptions = {
|
|
26
|
-
to: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
27
|
-
cc?: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
28
|
-
bcc?: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
29
|
-
from?: NixxieEmailRecipient
|
|
30
|
-
replyTo?: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
31
|
-
subject: string
|
|
32
|
-
/** Name of a template file (without extension) to render */
|
|
33
|
-
template?: string
|
|
34
|
-
/** Data passed to the template engine */
|
|
35
|
-
data?: Record<string, unknown>
|
|
36
|
-
/** Raw HTML body — used when not using a template */
|
|
37
|
-
html?: string
|
|
38
|
-
/** Plain-text body */
|
|
39
|
-
text?: string
|
|
40
|
-
attachments?: NixxieEmailAttachment[]
|
|
41
|
-
headers?: Record<string, string>
|
|
42
|
-
/** Skip the suppression-list check for this send */
|
|
43
|
-
skipSuppressionCheck?: boolean
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export type NixxieEmailQueueOptions = NixxieEmailSendOptions & {
|
|
47
|
-
/** Schedule delivery for a future date */
|
|
48
|
-
sendAt?: Date
|
|
49
|
-
priority?: 'high' | 'normal' | 'low'
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export type NixxieEmailSentInfo = {
|
|
53
|
-
messageId: string
|
|
54
|
-
accepted: string[]
|
|
55
|
-
rejected: string[]
|
|
56
|
-
response?: string
|
|
57
|
-
timestamp: Date
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export type NixxieEmailQueueStats = {
|
|
61
|
-
pending: number
|
|
62
|
-
processing: number
|
|
63
|
-
failed: number
|
|
64
|
-
completed: number
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Interface that @nixxie-cms/email's EmailService implements.
|
|
69
|
-
* Defined in core so it can be referenced in NixxieContext without a circular dependency.
|
|
70
|
-
*/
|
|
71
|
-
export type NixxieEmailService = {
|
|
72
|
-
/** Send an email immediately. Resolves when the transport accepts the message. */
|
|
73
|
-
send(options: NixxieEmailSendOptions): Promise<NixxieEmailSentInfo>
|
|
74
|
-
/** Send the same email to multiple recipients individually. */
|
|
75
|
-
bulk(
|
|
76
|
-
recipients: NixxieEmailRecipient[],
|
|
77
|
-
options: Omit<NixxieEmailSendOptions, 'to'>
|
|
78
|
-
): Promise<NixxieEmailSentInfo[]>
|
|
79
|
-
/** Add an email to the outbound queue (non-blocking). Returns the job ID. */
|
|
80
|
-
queue(options: NixxieEmailQueueOptions): string
|
|
81
|
-
/** Add an address to the suppression list. */
|
|
82
|
-
addToSuppressionList(email: string): void
|
|
83
|
-
/** Remove an address from the suppression list. */
|
|
84
|
-
removeFromSuppressionList(email: string): void
|
|
85
|
-
/** Returns true if the address is suppressed. */
|
|
86
|
-
isSuppressed(email: string): boolean
|
|
87
|
-
/** Returns all currently suppressed addresses. */
|
|
88
|
-
getSuppressionList(): string[]
|
|
89
|
-
/** Returns live queue statistics. */
|
|
90
|
-
getQueueStats(): NixxieEmailQueueStats
|
|
91
|
-
/** Wait for the queue to drain, then stop processing. */
|
|
92
|
-
flushQueue(): Promise<void>
|
|
93
|
-
/** Gracefully shut down the service and close transport connections. */
|
|
94
|
-
close(): Promise<void>
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// ── Jobs service ──
|
|
98
|
-
|
|
99
|
-
export type NixxieJobDefinition = {
|
|
100
|
-
name: string
|
|
101
|
-
/** Cron expression or interval in milliseconds */
|
|
102
|
-
schedule: string | number
|
|
103
|
-
/** Handler function invoked on each tick */
|
|
104
|
-
handler: (ctx: { jobId: string; scheduledAt: Date }) => Promise<void> | void
|
|
105
|
-
/** Immediately run the job once on registration */
|
|
106
|
-
runImmediately?: boolean
|
|
107
|
-
/** Disable job without removing the definition */
|
|
108
|
-
enabled?: boolean
|
|
109
|
-
/** Milliseconds before a running job is considered stuck */
|
|
110
|
-
timeout?: number
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export type NixxieJobStatus = 'idle' | 'running' | 'error' | 'disabled'
|
|
114
|
-
|
|
115
|
-
export type NixxieJobInfo = {
|
|
116
|
-
name: string
|
|
117
|
-
status: NixxieJobStatus
|
|
118
|
-
lastRun?: Date
|
|
119
|
-
lastError?: string
|
|
120
|
-
nextRun?: Date
|
|
121
|
-
runs: number
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export type NixxieJobsService = {
|
|
125
|
-
/** Register a job definition. Call before start() or at any time for hot-registration. */
|
|
126
|
-
define(job: NixxieJobDefinition): void
|
|
127
|
-
/** Remove a registered job by name. */
|
|
128
|
-
remove(name: string): void
|
|
129
|
-
/** Manually trigger a job by name, regardless of its schedule. */
|
|
130
|
-
trigger(name: string): Promise<void>
|
|
131
|
-
/** List all registered jobs with their current status. */
|
|
132
|
-
list(): NixxieJobInfo[]
|
|
133
|
-
/** Get info for a specific job. */
|
|
134
|
-
get(name: string): NixxieJobInfo | undefined
|
|
135
|
-
/** Gracefully stop all running jobs. */
|
|
136
|
-
close(): Promise<void>
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// ── Cache service ──
|
|
140
|
-
|
|
141
|
-
export type NixxieCacheSetOptions = {
|
|
142
|
-
/** Time-to-live in milliseconds. Omit for no expiry. */
|
|
143
|
-
ttl?: number
|
|
144
|
-
/** Tags for group invalidation */
|
|
145
|
-
tags?: string[]
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export type NixxieCacheService = {
|
|
149
|
-
/** Get a cached value. Returns undefined on miss. */
|
|
150
|
-
get<T = unknown>(key: string): Promise<T | undefined>
|
|
151
|
-
/** Set a cached value. */
|
|
152
|
-
set(key: string, value: unknown, options?: NixxieCacheSetOptions): Promise<void>
|
|
153
|
-
/** Delete a single key. */
|
|
154
|
-
delete(key: string): Promise<void>
|
|
155
|
-
/** Delete all keys matching a glob pattern. */
|
|
156
|
-
deletePattern(pattern: string): Promise<void>
|
|
157
|
-
/** Delete all keys with a given tag. */
|
|
158
|
-
deleteByTag(tag: string): Promise<void>
|
|
159
|
-
/** Returns true if the key exists and has not expired. */
|
|
160
|
-
has(key: string): Promise<boolean>
|
|
161
|
-
/**
|
|
162
|
-
* Cache-aside helper. Returns the cached value if present,
|
|
163
|
-
* otherwise calls fn(), caches the result, and returns it.
|
|
164
|
-
*/
|
|
165
|
-
wrap<T>(key: string, fn: () => Promise<T>, options?: NixxieCacheSetOptions): Promise<T>
|
|
166
|
-
/** Flush the entire cache. */
|
|
167
|
-
clear(): Promise<void>
|
|
168
|
-
/** Gracefully close cache connections. */
|
|
169
|
-
close(): Promise<void>
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// ── Audit service ──
|
|
173
|
-
|
|
174
|
-
export type NixxieAuditAction =
|
|
175
|
-
| 'create'
|
|
176
|
-
| 'update'
|
|
177
|
-
| 'delete'
|
|
178
|
-
| 'read'
|
|
179
|
-
| 'login'
|
|
180
|
-
| 'logout'
|
|
181
|
-
| (string & {})
|
|
182
|
-
|
|
183
|
-
export type NixxieAuditEntry = {
|
|
184
|
-
action: NixxieAuditAction
|
|
185
|
-
/** List name (e.g. 'User', 'Post') */
|
|
186
|
-
resource?: string
|
|
187
|
-
/** Item ID that was acted upon */
|
|
188
|
-
resourceId?: string
|
|
189
|
-
/** Session / user who performed the action */
|
|
190
|
-
actor?: {
|
|
191
|
-
id?: string
|
|
192
|
-
label?: string
|
|
193
|
-
ip?: string
|
|
194
|
-
}
|
|
195
|
-
/** Fields that changed: { field: { from, to } } */
|
|
196
|
-
changes?: Record<string, { from: unknown; to: unknown }>
|
|
197
|
-
/** Arbitrary extra context */
|
|
198
|
-
meta?: Record<string, unknown>
|
|
199
|
-
timestamp?: Date
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
export type NixxieAuditQuery = {
|
|
203
|
-
action?: NixxieAuditAction
|
|
204
|
-
resource?: string
|
|
205
|
-
resourceId?: string
|
|
206
|
-
actorId?: string
|
|
207
|
-
from?: Date
|
|
208
|
-
to?: Date
|
|
209
|
-
take?: number
|
|
210
|
-
skip?: number
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export type NixxieAuditRecord = NixxieAuditEntry & {
|
|
214
|
-
id: string
|
|
215
|
-
timestamp: Date
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export type NixxieAuditService = {
|
|
219
|
-
/** Log an audit event. */
|
|
220
|
-
log(entry: NixxieAuditEntry): Promise<NixxieAuditRecord>
|
|
221
|
-
/** Query the audit log. */
|
|
222
|
-
query(filters?: NixxieAuditQuery): Promise<NixxieAuditRecord[]>
|
|
223
|
-
/** Count matching entries. */
|
|
224
|
-
count(filters?: NixxieAuditQuery): Promise<number>
|
|
225
|
-
/** Delete entries older than a given date. Returns the number of deleted records. */
|
|
226
|
-
purge(before: Date): Promise<number>
|
|
227
|
-
/** Gracefully shut down (flush pending writes). */
|
|
228
|
-
close(): Promise<void>
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// ── Webhooks service ──
|
|
232
|
-
|
|
233
|
-
export type NixxieWebhookSubscription = {
|
|
234
|
-
id: string
|
|
235
|
-
event: string
|
|
236
|
-
url: string
|
|
237
|
-
secret?: string
|
|
238
|
-
enabled: boolean
|
|
239
|
-
createdAt: Date
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export type NixxieWebhookDelivery = {
|
|
243
|
-
id: string
|
|
244
|
-
subscriptionId: string
|
|
245
|
-
event: string
|
|
246
|
-
payload: unknown
|
|
247
|
-
status: 'pending' | 'delivered' | 'failed'
|
|
248
|
-
attempts: number
|
|
249
|
-
lastAttemptAt?: Date
|
|
250
|
-
responseStatus?: number
|
|
251
|
-
responseBody?: string
|
|
252
|
-
error?: string
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
export type NixxieWebhookSubscribeOptions = {
|
|
256
|
-
/** Optional signing secret — if provided, each request gets an `X-Nixxie-Signature` header */
|
|
257
|
-
secret?: string
|
|
258
|
-
/** Custom headers to send with every delivery */
|
|
259
|
-
headers?: Record<string, string>
|
|
260
|
-
/** Max delivery retries (default: 3) */
|
|
261
|
-
retries?: number
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
export type NixxieWebhooksService = {
|
|
265
|
-
/** Register a webhook endpoint for an event. Returns the subscription ID. */
|
|
266
|
-
subscribe(event: string, url: string, options?: NixxieWebhookSubscribeOptions): Promise<NixxieWebhookSubscription>
|
|
267
|
-
/** Remove a subscription by ID. */
|
|
268
|
-
unsubscribe(id: string): Promise<void>
|
|
269
|
-
/** Fire an event, delivering to all matching subscribers. */
|
|
270
|
-
trigger(event: string, payload: unknown): Promise<void>
|
|
271
|
-
/** List all registered subscriptions. */
|
|
272
|
-
list(event?: string): NixxieWebhookSubscription[]
|
|
273
|
-
/** Get delivery history for a subscription. */
|
|
274
|
-
deliveries(subscriptionId: string, take?: number): NixxieWebhookDelivery[]
|
|
275
|
-
/** Enable or disable a subscription. */
|
|
276
|
-
setEnabled(id: string, enabled: boolean): void
|
|
277
|
-
/** Gracefully stop delivery workers. */
|
|
278
|
-
close(): Promise<void>
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// ── Rate limit service ──
|
|
282
|
-
|
|
283
|
-
export type NixxieRateLimitResult = {
|
|
284
|
-
allowed: boolean
|
|
285
|
-
remaining: number
|
|
286
|
-
resetAt: Date
|
|
287
|
-
/** Total limit for the window */
|
|
288
|
-
limit: number
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
export type NixxieRateLimitOptions = {
|
|
292
|
-
/** Maximum number of requests in the window */
|
|
293
|
-
limit: number
|
|
294
|
-
/** Window duration in milliseconds */
|
|
295
|
-
window: number
|
|
296
|
-
/** Cost of this operation (default: 1) */
|
|
297
|
-
cost?: number
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export type NixxieRateLimitService = {
|
|
301
|
-
/**
|
|
302
|
-
* Check without consuming — returns whether the key is within the limit.
|
|
303
|
-
* Does NOT decrement the counter.
|
|
304
|
-
*/
|
|
305
|
-
check(key: string, options: NixxieRateLimitOptions): Promise<NixxieRateLimitResult>
|
|
306
|
-
/**
|
|
307
|
-
* Consume from the limit. Returns the updated result.
|
|
308
|
-
* Does NOT throw on exceeded limits — callers should check `result.allowed`.
|
|
309
|
-
*/
|
|
310
|
-
consume(key: string, options: NixxieRateLimitOptions): Promise<NixxieRateLimitResult>
|
|
311
|
-
/** Reset the counter for a key. */
|
|
312
|
-
reset(key: string): Promise<void>
|
|
313
|
-
/** Gracefully shut down (close Redis connections etc.). */
|
|
314
|
-
close(): Promise<void>
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// ── Health service ──
|
|
318
|
-
|
|
319
|
-
export type NixxieHealthCheckFn = () => Promise<{ ok: boolean; message?: string; details?: unknown }>
|
|
320
|
-
|
|
321
|
-
export type NixxieHealthCheckResult = {
|
|
322
|
-
name: string
|
|
323
|
-
status: 'healthy' | 'unhealthy'
|
|
324
|
-
/** Whether this check failing marks the whole system unhealthy (true) or just degraded (false) */
|
|
325
|
-
critical: boolean
|
|
326
|
-
message?: string
|
|
327
|
-
details?: unknown
|
|
328
|
-
/** How long the check took in milliseconds */
|
|
329
|
-
latency: number
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
export type NixxieHealthReport = {
|
|
333
|
-
/** Overall system status */
|
|
334
|
-
status: 'healthy' | 'degraded' | 'unhealthy'
|
|
335
|
-
timestamp: string
|
|
336
|
-
/**
|
|
337
|
-
|
|
338
|
-
/** process.
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
): Promise<
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
export type
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
)
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'http'
|
|
2
|
+
import type { DocumentNode, ExecutionResult, GraphQLSchema } from 'graphql'
|
|
3
|
+
import type { TypedDocumentNode } from '@graphql-typed-document-node/core'
|
|
4
|
+
import type { InitialisedList } from '../lib/core/initialise-lists'
|
|
5
|
+
import type { SessionStrategy } from './session'
|
|
6
|
+
import type { BaseNixxieTypeInfo, BaseListTypeInfo } from './type-info'
|
|
7
|
+
import type { MaybePromise } from './utils'
|
|
8
|
+
|
|
9
|
+
// ── Email service types (defined here so @nixxie-cms/email can implement without circular deps) ──
|
|
10
|
+
|
|
11
|
+
export type NixxieEmailRecipient = string | { name?: string; address: string }
|
|
12
|
+
|
|
13
|
+
export type NixxieEmailAttachment = {
|
|
14
|
+
filename?: string
|
|
15
|
+
content?: string | Buffer
|
|
16
|
+
path?: string
|
|
17
|
+
href?: string
|
|
18
|
+
contentType?: string
|
|
19
|
+
encoding?: string
|
|
20
|
+
contentDisposition?: 'attachment' | 'inline'
|
|
21
|
+
/** Content ID for inline embedded images (used with src="cid:…") */
|
|
22
|
+
cid?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type NixxieEmailSendOptions = {
|
|
26
|
+
to: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
27
|
+
cc?: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
28
|
+
bcc?: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
29
|
+
from?: NixxieEmailRecipient
|
|
30
|
+
replyTo?: NixxieEmailRecipient | NixxieEmailRecipient[]
|
|
31
|
+
subject: string
|
|
32
|
+
/** Name of a template file (without extension) to render */
|
|
33
|
+
template?: string
|
|
34
|
+
/** Data passed to the template engine */
|
|
35
|
+
data?: Record<string, unknown>
|
|
36
|
+
/** Raw HTML body — used when not using a template */
|
|
37
|
+
html?: string
|
|
38
|
+
/** Plain-text body */
|
|
39
|
+
text?: string
|
|
40
|
+
attachments?: NixxieEmailAttachment[]
|
|
41
|
+
headers?: Record<string, string>
|
|
42
|
+
/** Skip the suppression-list check for this send */
|
|
43
|
+
skipSuppressionCheck?: boolean
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type NixxieEmailQueueOptions = NixxieEmailSendOptions & {
|
|
47
|
+
/** Schedule delivery for a future date */
|
|
48
|
+
sendAt?: Date
|
|
49
|
+
priority?: 'high' | 'normal' | 'low'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type NixxieEmailSentInfo = {
|
|
53
|
+
messageId: string
|
|
54
|
+
accepted: string[]
|
|
55
|
+
rejected: string[]
|
|
56
|
+
response?: string
|
|
57
|
+
timestamp: Date
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type NixxieEmailQueueStats = {
|
|
61
|
+
pending: number
|
|
62
|
+
processing: number
|
|
63
|
+
failed: number
|
|
64
|
+
completed: number
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Interface that @nixxie-cms/email's EmailService implements.
|
|
69
|
+
* Defined in core so it can be referenced in NixxieContext without a circular dependency.
|
|
70
|
+
*/
|
|
71
|
+
export type NixxieEmailService = {
|
|
72
|
+
/** Send an email immediately. Resolves when the transport accepts the message. */
|
|
73
|
+
send(options: NixxieEmailSendOptions): Promise<NixxieEmailSentInfo>
|
|
74
|
+
/** Send the same email to multiple recipients individually. */
|
|
75
|
+
bulk(
|
|
76
|
+
recipients: NixxieEmailRecipient[],
|
|
77
|
+
options: Omit<NixxieEmailSendOptions, 'to'>
|
|
78
|
+
): Promise<NixxieEmailSentInfo[]>
|
|
79
|
+
/** Add an email to the outbound queue (non-blocking). Returns the job ID. */
|
|
80
|
+
queue(options: NixxieEmailQueueOptions): string
|
|
81
|
+
/** Add an address to the suppression list. */
|
|
82
|
+
addToSuppressionList(email: string): void
|
|
83
|
+
/** Remove an address from the suppression list. */
|
|
84
|
+
removeFromSuppressionList(email: string): void
|
|
85
|
+
/** Returns true if the address is suppressed. */
|
|
86
|
+
isSuppressed(email: string): boolean
|
|
87
|
+
/** Returns all currently suppressed addresses. */
|
|
88
|
+
getSuppressionList(): string[]
|
|
89
|
+
/** Returns live queue statistics. */
|
|
90
|
+
getQueueStats(): NixxieEmailQueueStats
|
|
91
|
+
/** Wait for the queue to drain, then stop processing. */
|
|
92
|
+
flushQueue(): Promise<void>
|
|
93
|
+
/** Gracefully shut down the service and close transport connections. */
|
|
94
|
+
close(): Promise<void>
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ── Jobs service ──
|
|
98
|
+
|
|
99
|
+
export type NixxieJobDefinition = {
|
|
100
|
+
name: string
|
|
101
|
+
/** Cron expression or interval in milliseconds */
|
|
102
|
+
schedule: string | number
|
|
103
|
+
/** Handler function invoked on each tick */
|
|
104
|
+
handler: (ctx: { jobId: string; scheduledAt: Date }) => Promise<void> | void
|
|
105
|
+
/** Immediately run the job once on registration */
|
|
106
|
+
runImmediately?: boolean
|
|
107
|
+
/** Disable job without removing the definition */
|
|
108
|
+
enabled?: boolean
|
|
109
|
+
/** Milliseconds before a running job is considered stuck */
|
|
110
|
+
timeout?: number
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type NixxieJobStatus = 'idle' | 'running' | 'error' | 'disabled'
|
|
114
|
+
|
|
115
|
+
export type NixxieJobInfo = {
|
|
116
|
+
name: string
|
|
117
|
+
status: NixxieJobStatus
|
|
118
|
+
lastRun?: Date
|
|
119
|
+
lastError?: string
|
|
120
|
+
nextRun?: Date
|
|
121
|
+
runs: number
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export type NixxieJobsService = {
|
|
125
|
+
/** Register a job definition. Call before start() or at any time for hot-registration. */
|
|
126
|
+
define(job: NixxieJobDefinition): void
|
|
127
|
+
/** Remove a registered job by name. */
|
|
128
|
+
remove(name: string): void
|
|
129
|
+
/** Manually trigger a job by name, regardless of its schedule. */
|
|
130
|
+
trigger(name: string): Promise<void>
|
|
131
|
+
/** List all registered jobs with their current status. */
|
|
132
|
+
list(): NixxieJobInfo[]
|
|
133
|
+
/** Get info for a specific job. */
|
|
134
|
+
get(name: string): NixxieJobInfo | undefined
|
|
135
|
+
/** Gracefully stop all running jobs. */
|
|
136
|
+
close(): Promise<void>
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ── Cache service ──
|
|
140
|
+
|
|
141
|
+
export type NixxieCacheSetOptions = {
|
|
142
|
+
/** Time-to-live in milliseconds. Omit for no expiry. */
|
|
143
|
+
ttl?: number
|
|
144
|
+
/** Tags for group invalidation */
|
|
145
|
+
tags?: string[]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export type NixxieCacheService = {
|
|
149
|
+
/** Get a cached value. Returns undefined on miss. */
|
|
150
|
+
get<T = unknown>(key: string): Promise<T | undefined>
|
|
151
|
+
/** Set a cached value. */
|
|
152
|
+
set(key: string, value: unknown, options?: NixxieCacheSetOptions): Promise<void>
|
|
153
|
+
/** Delete a single key. */
|
|
154
|
+
delete(key: string): Promise<void>
|
|
155
|
+
/** Delete all keys matching a glob pattern. */
|
|
156
|
+
deletePattern(pattern: string): Promise<void>
|
|
157
|
+
/** Delete all keys with a given tag. */
|
|
158
|
+
deleteByTag(tag: string): Promise<void>
|
|
159
|
+
/** Returns true if the key exists and has not expired. */
|
|
160
|
+
has(key: string): Promise<boolean>
|
|
161
|
+
/**
|
|
162
|
+
* Cache-aside helper. Returns the cached value if present,
|
|
163
|
+
* otherwise calls fn(), caches the result, and returns it.
|
|
164
|
+
*/
|
|
165
|
+
wrap<T>(key: string, fn: () => Promise<T>, options?: NixxieCacheSetOptions): Promise<T>
|
|
166
|
+
/** Flush the entire cache. */
|
|
167
|
+
clear(): Promise<void>
|
|
168
|
+
/** Gracefully close cache connections. */
|
|
169
|
+
close(): Promise<void>
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ── Audit service ──
|
|
173
|
+
|
|
174
|
+
export type NixxieAuditAction =
|
|
175
|
+
| 'create'
|
|
176
|
+
| 'update'
|
|
177
|
+
| 'delete'
|
|
178
|
+
| 'read'
|
|
179
|
+
| 'login'
|
|
180
|
+
| 'logout'
|
|
181
|
+
| (string & {})
|
|
182
|
+
|
|
183
|
+
export type NixxieAuditEntry = {
|
|
184
|
+
action: NixxieAuditAction
|
|
185
|
+
/** List name (e.g. 'User', 'Post') */
|
|
186
|
+
resource?: string
|
|
187
|
+
/** Item ID that was acted upon */
|
|
188
|
+
resourceId?: string
|
|
189
|
+
/** Session / user who performed the action */
|
|
190
|
+
actor?: {
|
|
191
|
+
id?: string
|
|
192
|
+
label?: string
|
|
193
|
+
ip?: string
|
|
194
|
+
}
|
|
195
|
+
/** Fields that changed: { field: { from, to } } */
|
|
196
|
+
changes?: Record<string, { from: unknown; to: unknown }>
|
|
197
|
+
/** Arbitrary extra context */
|
|
198
|
+
meta?: Record<string, unknown>
|
|
199
|
+
timestamp?: Date
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export type NixxieAuditQuery = {
|
|
203
|
+
action?: NixxieAuditAction
|
|
204
|
+
resource?: string
|
|
205
|
+
resourceId?: string
|
|
206
|
+
actorId?: string
|
|
207
|
+
from?: Date
|
|
208
|
+
to?: Date
|
|
209
|
+
take?: number
|
|
210
|
+
skip?: number
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export type NixxieAuditRecord = NixxieAuditEntry & {
|
|
214
|
+
id: string
|
|
215
|
+
timestamp: Date
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export type NixxieAuditService = {
|
|
219
|
+
/** Log an audit event. */
|
|
220
|
+
log(entry: NixxieAuditEntry): Promise<NixxieAuditRecord>
|
|
221
|
+
/** Query the audit log. */
|
|
222
|
+
query(filters?: NixxieAuditQuery): Promise<NixxieAuditRecord[]>
|
|
223
|
+
/** Count matching entries. */
|
|
224
|
+
count(filters?: NixxieAuditQuery): Promise<number>
|
|
225
|
+
/** Delete entries older than a given date. Returns the number of deleted records. */
|
|
226
|
+
purge(before: Date): Promise<number>
|
|
227
|
+
/** Gracefully shut down (flush pending writes). */
|
|
228
|
+
close(): Promise<void>
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ── Webhooks service ──
|
|
232
|
+
|
|
233
|
+
export type NixxieWebhookSubscription = {
|
|
234
|
+
id: string
|
|
235
|
+
event: string
|
|
236
|
+
url: string
|
|
237
|
+
secret?: string
|
|
238
|
+
enabled: boolean
|
|
239
|
+
createdAt: Date
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export type NixxieWebhookDelivery = {
|
|
243
|
+
id: string
|
|
244
|
+
subscriptionId: string
|
|
245
|
+
event: string
|
|
246
|
+
payload: unknown
|
|
247
|
+
status: 'pending' | 'delivered' | 'failed'
|
|
248
|
+
attempts: number
|
|
249
|
+
lastAttemptAt?: Date
|
|
250
|
+
responseStatus?: number
|
|
251
|
+
responseBody?: string
|
|
252
|
+
error?: string
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export type NixxieWebhookSubscribeOptions = {
|
|
256
|
+
/** Optional signing secret — if provided, each request gets an `X-Nixxie-Signature` header */
|
|
257
|
+
secret?: string
|
|
258
|
+
/** Custom headers to send with every delivery */
|
|
259
|
+
headers?: Record<string, string>
|
|
260
|
+
/** Max delivery retries (default: 3) */
|
|
261
|
+
retries?: number
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export type NixxieWebhooksService = {
|
|
265
|
+
/** Register a webhook endpoint for an event. Returns the subscription ID. */
|
|
266
|
+
subscribe(event: string, url: string, options?: NixxieWebhookSubscribeOptions): Promise<NixxieWebhookSubscription>
|
|
267
|
+
/** Remove a subscription by ID. */
|
|
268
|
+
unsubscribe(id: string): Promise<void>
|
|
269
|
+
/** Fire an event, delivering to all matching subscribers. */
|
|
270
|
+
trigger(event: string, payload: unknown): Promise<void>
|
|
271
|
+
/** List all registered subscriptions. */
|
|
272
|
+
list(event?: string): NixxieWebhookSubscription[]
|
|
273
|
+
/** Get delivery history for a subscription. */
|
|
274
|
+
deliveries(subscriptionId: string, take?: number): NixxieWebhookDelivery[]
|
|
275
|
+
/** Enable or disable a subscription. */
|
|
276
|
+
setEnabled(id: string, enabled: boolean): void
|
|
277
|
+
/** Gracefully stop delivery workers. */
|
|
278
|
+
close(): Promise<void>
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// ── Rate limit service ──
|
|
282
|
+
|
|
283
|
+
export type NixxieRateLimitResult = {
|
|
284
|
+
allowed: boolean
|
|
285
|
+
remaining: number
|
|
286
|
+
resetAt: Date
|
|
287
|
+
/** Total limit for the window */
|
|
288
|
+
limit: number
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export type NixxieRateLimitOptions = {
|
|
292
|
+
/** Maximum number of requests in the window */
|
|
293
|
+
limit: number
|
|
294
|
+
/** Window duration in milliseconds */
|
|
295
|
+
window: number
|
|
296
|
+
/** Cost of this operation (default: 1) */
|
|
297
|
+
cost?: number
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export type NixxieRateLimitService = {
|
|
301
|
+
/**
|
|
302
|
+
* Check without consuming — returns whether the key is within the limit.
|
|
303
|
+
* Does NOT decrement the counter.
|
|
304
|
+
*/
|
|
305
|
+
check(key: string, options: NixxieRateLimitOptions): Promise<NixxieRateLimitResult>
|
|
306
|
+
/**
|
|
307
|
+
* Consume from the limit. Returns the updated result.
|
|
308
|
+
* Does NOT throw on exceeded limits — callers should check `result.allowed`.
|
|
309
|
+
*/
|
|
310
|
+
consume(key: string, options: NixxieRateLimitOptions): Promise<NixxieRateLimitResult>
|
|
311
|
+
/** Reset the counter for a key. */
|
|
312
|
+
reset(key: string): Promise<void>
|
|
313
|
+
/** Gracefully shut down (close Redis connections etc.). */
|
|
314
|
+
close(): Promise<void>
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ── Health service ──
|
|
318
|
+
|
|
319
|
+
export type NixxieHealthCheckFn = () => Promise<{ ok: boolean; message?: string; details?: unknown }>
|
|
320
|
+
|
|
321
|
+
export type NixxieHealthCheckResult = {
|
|
322
|
+
name: string
|
|
323
|
+
status: 'healthy' | 'unhealthy'
|
|
324
|
+
/** Whether this check failing marks the whole system unhealthy (true) or just degraded (false) */
|
|
325
|
+
critical: boolean
|
|
326
|
+
message?: string
|
|
327
|
+
details?: unknown
|
|
328
|
+
/** How long the check took in milliseconds */
|
|
329
|
+
latency: number
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export type NixxieHealthReport = {
|
|
333
|
+
/** Overall system status */
|
|
334
|
+
status: 'healthy' | 'degraded' | 'unhealthy'
|
|
335
|
+
timestamp: string
|
|
336
|
+
/** Application version, if configured */
|
|
337
|
+
version?: string
|
|
338
|
+
/** process.uptime() in seconds */
|
|
339
|
+
uptime: number
|
|
340
|
+
/** process.memoryUsage().heapUsed in MB */
|
|
341
|
+
memoryMb: number
|
|
342
|
+
checks: NixxieHealthCheckResult[]
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export type NixxieHealthService = {
|
|
346
|
+
/**
|
|
347
|
+
* Register a named health check.
|
|
348
|
+
* @param critical If true (default), failure marks the system 'unhealthy'. If false, 'degraded'.
|
|
349
|
+
*/
|
|
350
|
+
register(name: string, check: NixxieHealthCheckFn, options?: { critical?: boolean }): void
|
|
351
|
+
/** Remove a registered check by name. */
|
|
352
|
+
unregister(name: string): void
|
|
353
|
+
/** Run all registered checks and return the full health report. */
|
|
354
|
+
check(): Promise<NixxieHealthReport>
|
|
355
|
+
/**
|
|
356
|
+
* Returns an Express Router with two routes:
|
|
357
|
+
* - GET /live — liveness (process is up, returns 200 immediately)
|
|
358
|
+
* - GET /ready — readiness (runs all checks, returns 200 or 503)
|
|
359
|
+
*
|
|
360
|
+
* Mount in extendExpressApp: `app.use('/health', context.services.health.router())`
|
|
361
|
+
*/
|
|
362
|
+
router(options?: { livePath?: string; readyPath?: string }): unknown
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// ── Storage service ──
|
|
366
|
+
|
|
367
|
+
export type NixxieStoredFile = {
|
|
368
|
+
/** Storage key / path the file is stored under */
|
|
369
|
+
key: string
|
|
370
|
+
/** Public or signed URL for retrieving the file */
|
|
371
|
+
url: string
|
|
372
|
+
/** Size in bytes, if known */
|
|
373
|
+
size?: number
|
|
374
|
+
/** Detected or provided content type */
|
|
375
|
+
contentType?: string
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export type NixxiePutOptions = {
|
|
379
|
+
/** MIME type to store alongside the object */
|
|
380
|
+
contentType?: string
|
|
381
|
+
/** Whether the object should be publicly readable (driver permitting). Default: false */
|
|
382
|
+
public?: boolean
|
|
383
|
+
/** Arbitrary metadata stored with the object */
|
|
384
|
+
metadata?: Record<string, string>
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export type NixxieSignedUrlOptions = {
|
|
388
|
+
/** Expiry in seconds. Default: 900 (15 minutes) */
|
|
389
|
+
expiresIn?: number
|
|
390
|
+
/** 'get' for download URLs, 'put' for direct browser uploads. Default: 'get' */
|
|
391
|
+
operation?: 'get' | 'put'
|
|
392
|
+
/** Content type required on the upload when operation is 'put' */
|
|
393
|
+
contentType?: string
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Pluggable blob storage. Implemented by @nixxie-cms/storage (local, S3, GCS, Azure). */
|
|
397
|
+
export type NixxieStorageService = {
|
|
398
|
+
/** Store a file and return its key + URL. */
|
|
399
|
+
put(key: string, data: Buffer | Uint8Array | string, options?: NixxiePutOptions): Promise<NixxieStoredFile>
|
|
400
|
+
/** Read a file's bytes. Resolves undefined when the key does not exist. */
|
|
401
|
+
get(key: string): Promise<Buffer | undefined>
|
|
402
|
+
/** Delete a file. No-op if it does not exist. */
|
|
403
|
+
delete(key: string): Promise<void>
|
|
404
|
+
/** Whether a key exists. */
|
|
405
|
+
has(key: string): Promise<boolean>
|
|
406
|
+
/** Public URL for a key (may be unsigned and require the object to be public). */
|
|
407
|
+
url(key: string): string
|
|
408
|
+
/** Create a time-limited signed URL for download or direct upload. */
|
|
409
|
+
signedUrl(key: string, options?: NixxieSignedUrlOptions): Promise<string>
|
|
410
|
+
/** List keys under a prefix. */
|
|
411
|
+
list(prefix?: string): Promise<string[]>
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ── Search service ──
|
|
415
|
+
|
|
416
|
+
export type NixxieSearchDocument = Record<string, unknown> & { id: string }
|
|
417
|
+
|
|
418
|
+
export type NixxieSearchQuery = {
|
|
419
|
+
/** Free-text query string. */
|
|
420
|
+
q: string
|
|
421
|
+
/** Maximum results to return. Default: 20 */
|
|
422
|
+
limit?: number
|
|
423
|
+
/** Number of results to skip (pagination). */
|
|
424
|
+
offset?: number
|
|
425
|
+
/** Equality filters applied to indexed attributes. */
|
|
426
|
+
filter?: Record<string, string | number | boolean>
|
|
427
|
+
/** Attributes to sort by, e.g. ['createdAt:desc']. */
|
|
428
|
+
sort?: string[]
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
export type NixxieSearchHit<T = NixxieSearchDocument> = {
|
|
432
|
+
document: T
|
|
433
|
+
/** Relevance score (driver-specific scale), when available. */
|
|
434
|
+
score?: number
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
export type NixxieSearchResults<T = NixxieSearchDocument> = {
|
|
438
|
+
hits: NixxieSearchHit<T>[]
|
|
439
|
+
/** Total matches, when the backend reports it. */
|
|
440
|
+
total: number
|
|
441
|
+
/** Query processing time in milliseconds, when available. */
|
|
442
|
+
tookMs?: number
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** Pluggable full-text search. Implemented by @nixxie-cms/search (memory, Meilisearch, Typesense, Algolia, Elasticsearch). */
|
|
446
|
+
export type NixxieSearchService = {
|
|
447
|
+
/** Create or update one or more documents in an index. */
|
|
448
|
+
index(indexName: string, documents: NixxieSearchDocument | NixxieSearchDocument[]): Promise<void>
|
|
449
|
+
/** Remove a document from an index by id. */
|
|
450
|
+
remove(indexName: string, id: string): Promise<void>
|
|
451
|
+
/** Run a search against an index. */
|
|
452
|
+
search<T = NixxieSearchDocument>(indexName: string, query: NixxieSearchQuery): Promise<NixxieSearchResults<T>>
|
|
453
|
+
/** Delete every document in an index. */
|
|
454
|
+
clear(indexName: string): Promise<void>
|
|
455
|
+
/** Gracefully close any open connections. */
|
|
456
|
+
close(): Promise<void>
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// ── Notifications service ──
|
|
460
|
+
|
|
461
|
+
export type NixxieNotificationChannel = string
|
|
462
|
+
|
|
463
|
+
export type NixxieNotification = {
|
|
464
|
+
/** Channel(s) to deliver on. Omit to use every configured channel. */
|
|
465
|
+
channel?: NixxieNotificationChannel | NixxieNotificationChannel[]
|
|
466
|
+
/** Recipient address — meaning depends on the channel (Slack channel id, phone number, etc.). */
|
|
467
|
+
to?: string
|
|
468
|
+
/** Short title / subject. */
|
|
469
|
+
title?: string
|
|
470
|
+
/** Body of the notification. */
|
|
471
|
+
body: string
|
|
472
|
+
/** Arbitrary structured data forwarded to the channel. */
|
|
473
|
+
data?: Record<string, unknown>
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
export type NixxieNotificationResult = {
|
|
477
|
+
channel: NixxieNotificationChannel
|
|
478
|
+
ok: boolean
|
|
479
|
+
/** Provider message id when delivery succeeded. */
|
|
480
|
+
id?: string
|
|
481
|
+
/** Error message when delivery failed. */
|
|
482
|
+
error?: string
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/** Multi-channel notifications (Slack, Discord, SMS, webhook, custom). Implemented by @nixxie-cms/notifications. */
|
|
486
|
+
export type NixxieNotificationsService = {
|
|
487
|
+
/** Send a notification across the requested (or all configured) channels. */
|
|
488
|
+
send(notification: NixxieNotification): Promise<NixxieNotificationResult[]>
|
|
489
|
+
/** List the names of the configured channels. */
|
|
490
|
+
channels(): NixxieNotificationChannel[]
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// ── AI service ──
|
|
494
|
+
|
|
495
|
+
export type NixxieAiMessage = {
|
|
496
|
+
role: 'system' | 'user' | 'assistant'
|
|
497
|
+
content: string
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
export type NixxieAiCompleteOptions = {
|
|
501
|
+
/** Override the configured model for this call. */
|
|
502
|
+
model?: string
|
|
503
|
+
/** System prompt prepended to the conversation. */
|
|
504
|
+
system?: string
|
|
505
|
+
/** Sampling temperature. */
|
|
506
|
+
temperature?: number
|
|
507
|
+
/** Maximum tokens to generate. */
|
|
508
|
+
maxTokens?: number
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
export type NixxieAiCompletion = {
|
|
512
|
+
text: string
|
|
513
|
+
model: string
|
|
514
|
+
usage?: { inputTokens?: number; outputTokens?: number }
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/** Pluggable LLM + embeddings access. Implemented by @nixxie-cms/ai (Anthropic, OpenAI). */
|
|
518
|
+
export type NixxieAiService = {
|
|
519
|
+
/** Complete a single prompt. */
|
|
520
|
+
complete(prompt: string, options?: NixxieAiCompleteOptions): Promise<NixxieAiCompletion>
|
|
521
|
+
/** Complete a multi-turn conversation. */
|
|
522
|
+
chat(messages: NixxieAiMessage[], options?: NixxieAiCompleteOptions): Promise<NixxieAiCompletion>
|
|
523
|
+
/** Produce an embedding vector for a string. */
|
|
524
|
+
embed(text: string): Promise<number[]>
|
|
525
|
+
/** Produce embedding vectors for many strings in one call. */
|
|
526
|
+
embedMany(texts: string[]): Promise<number[][]>
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// ── Context ──
|
|
530
|
+
|
|
531
|
+
export type NixxieContext<TypeInfo extends BaseNixxieTypeInfo = BaseNixxieTypeInfo> = {
|
|
532
|
+
db: NixxieDbAPI<TypeInfo['lists']>
|
|
533
|
+
query: NixxieListsAPI<TypeInfo['lists']>
|
|
534
|
+
graphql: NixxieGraphQLAPI
|
|
535
|
+
prisma: TypeInfo['prisma']
|
|
536
|
+
/** Runtime services configured in nixxie.ts — available everywhere context is available */
|
|
537
|
+
services: {
|
|
538
|
+
email: NixxieEmailService | null
|
|
539
|
+
jobs: NixxieJobsService | null
|
|
540
|
+
cache: NixxieCacheService | null
|
|
541
|
+
audit: NixxieAuditService | null
|
|
542
|
+
webhooks: NixxieWebhooksService | null
|
|
543
|
+
rateLimit: NixxieRateLimitService | null
|
|
544
|
+
health: NixxieHealthService | null
|
|
545
|
+
storage: NixxieStorageService | null
|
|
546
|
+
search: NixxieSearchService | null
|
|
547
|
+
notifications: NixxieNotificationsService | null
|
|
548
|
+
ai: NixxieAiService | null
|
|
549
|
+
}
|
|
550
|
+
transaction: <T>(
|
|
551
|
+
f: (context: NixxieContext<TypeInfo>) => MaybePromise<T>,
|
|
552
|
+
options?: {
|
|
553
|
+
maxWait?: number
|
|
554
|
+
timeout?: number
|
|
555
|
+
isolationLevel?: {
|
|
556
|
+
Serializable: 'Serializable'
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
) => Promise<T>
|
|
560
|
+
|
|
561
|
+
req?: IncomingMessage
|
|
562
|
+
res?: ServerResponse
|
|
563
|
+
sessionStrategy?: SessionStrategy<TypeInfo['session'], TypeInfo>
|
|
564
|
+
session?: TypeInfo['session']
|
|
565
|
+
withRequest: (req: IncomingMessage, res?: ServerResponse) => Promise<NixxieContext<TypeInfo>>
|
|
566
|
+
withSession: (session?: TypeInfo['session']) => NixxieContext<TypeInfo>
|
|
567
|
+
|
|
568
|
+
// privilege escalation
|
|
569
|
+
internal: () => NixxieContext<TypeInfo> // WARNING: name may change
|
|
570
|
+
sudo: () => NixxieContext<TypeInfo>
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* WARNING: may change in patch
|
|
574
|
+
*/
|
|
575
|
+
__internal: {
|
|
576
|
+
sudo: boolean
|
|
577
|
+
lists: Record<string, InitialisedList>
|
|
578
|
+
prisma: {
|
|
579
|
+
DbNull: unknown
|
|
580
|
+
JsonNull: unknown
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// List item API
|
|
586
|
+
|
|
587
|
+
type UniqueWhereInput<ListTypeInfo extends BaseListTypeInfo> =
|
|
588
|
+
false extends ListTypeInfo['isSingleton']
|
|
589
|
+
? { readonly where: ListTypeInfo['inputs']['uniqueWhere'] }
|
|
590
|
+
: { readonly where?: ListTypeInfo['inputs']['uniqueWhere'] }
|
|
591
|
+
|
|
592
|
+
type ListAPI<ListTypeInfo extends BaseListTypeInfo> = {
|
|
593
|
+
findMany(
|
|
594
|
+
args?: {
|
|
595
|
+
readonly where?: ListTypeInfo['inputs']['where']
|
|
596
|
+
readonly take?: number
|
|
597
|
+
readonly skip?: number
|
|
598
|
+
readonly orderBy?:
|
|
599
|
+
| ListTypeInfo['inputs']['orderBy']
|
|
600
|
+
| readonly ListTypeInfo['inputs']['orderBy'][]
|
|
601
|
+
readonly cursor?: ListTypeInfo['inputs']['uniqueWhere']
|
|
602
|
+
} & ResolveFields
|
|
603
|
+
): Promise<readonly Record<string, any>[]>
|
|
604
|
+
findOne(args: UniqueWhereInput<ListTypeInfo> & ResolveFields): Promise<Record<string, any>>
|
|
605
|
+
count(args?: { readonly where?: ListTypeInfo['inputs']['where'] }): Promise<number>
|
|
606
|
+
updateOne(
|
|
607
|
+
args: UniqueWhereInput<ListTypeInfo> & {
|
|
608
|
+
readonly data: ListTypeInfo['inputs']['update']
|
|
609
|
+
} & ResolveFields
|
|
610
|
+
): Promise<Record<string, any>>
|
|
611
|
+
updateMany(
|
|
612
|
+
args: {
|
|
613
|
+
readonly data: readonly (UniqueWhereInput<ListTypeInfo> & {
|
|
614
|
+
readonly data: ListTypeInfo['inputs']['update']
|
|
615
|
+
})[]
|
|
616
|
+
} & ResolveFields
|
|
617
|
+
): Promise<Record<string, any>[]>
|
|
618
|
+
createOne(
|
|
619
|
+
args: { readonly data: ListTypeInfo['inputs']['create'] } & ResolveFields
|
|
620
|
+
): Promise<Record<string, any>>
|
|
621
|
+
createMany(
|
|
622
|
+
args: {
|
|
623
|
+
readonly data: readonly ListTypeInfo['inputs']['create'][]
|
|
624
|
+
} & ResolveFields
|
|
625
|
+
): Promise<Record<string, any>[]>
|
|
626
|
+
deleteOne(
|
|
627
|
+
args: UniqueWhereInput<ListTypeInfo> & ResolveFields
|
|
628
|
+
): Promise<Record<string, any> | null>
|
|
629
|
+
deleteMany(
|
|
630
|
+
args: {
|
|
631
|
+
readonly where: readonly ListTypeInfo['inputs']['uniqueWhere'][]
|
|
632
|
+
} & ResolveFields
|
|
633
|
+
): Promise<Record<string, any>[]>
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
export type NixxieListsAPI<ListsTypeInfo extends Record<string, BaseListTypeInfo>> = {
|
|
637
|
+
[Key in keyof ListsTypeInfo]: ListAPI<ListsTypeInfo[Key]>
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
type ResolveFields = {
|
|
641
|
+
/**
|
|
642
|
+
* @default 'id'
|
|
643
|
+
*/
|
|
644
|
+
readonly query?: string
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
type DbAPI<ListTypeInfo extends BaseListTypeInfo> = {
|
|
648
|
+
findMany(args?: {
|
|
649
|
+
readonly where?: ListTypeInfo['inputs']['where']
|
|
650
|
+
readonly take?: number
|
|
651
|
+
readonly skip?: number
|
|
652
|
+
readonly orderBy?:
|
|
653
|
+
| ListTypeInfo['inputs']['orderBy']
|
|
654
|
+
| readonly ListTypeInfo['inputs']['orderBy'][]
|
|
655
|
+
readonly cursor?: ListTypeInfo['inputs']['uniqueWhere']
|
|
656
|
+
}): Promise<readonly ListTypeInfo['item'][]>
|
|
657
|
+
findOne(args: UniqueWhereInput<ListTypeInfo>): Promise<ListTypeInfo['item'] | null>
|
|
658
|
+
count(args?: { readonly where?: ListTypeInfo['inputs']['where'] }): Promise<number>
|
|
659
|
+
updateOne(
|
|
660
|
+
args: UniqueWhereInput<ListTypeInfo> & {
|
|
661
|
+
readonly data: ListTypeInfo['inputs']['update']
|
|
662
|
+
}
|
|
663
|
+
): Promise<ListTypeInfo['item']>
|
|
664
|
+
updateMany(args: {
|
|
665
|
+
readonly data: readonly (UniqueWhereInput<ListTypeInfo> & {
|
|
666
|
+
readonly data: ListTypeInfo['inputs']['update']
|
|
667
|
+
})[]
|
|
668
|
+
}): Promise<ListTypeInfo['item'][]>
|
|
669
|
+
createOne(args: {
|
|
670
|
+
readonly data: ListTypeInfo['inputs']['create']
|
|
671
|
+
}): Promise<ListTypeInfo['item']>
|
|
672
|
+
createMany(args: {
|
|
673
|
+
readonly data: readonly ListTypeInfo['inputs']['create'][]
|
|
674
|
+
}): Promise<ListTypeInfo['item'][]>
|
|
675
|
+
deleteOne(args: UniqueWhereInput<ListTypeInfo>): Promise<ListTypeInfo['item']>
|
|
676
|
+
deleteMany(args: {
|
|
677
|
+
readonly where: readonly ListTypeInfo['inputs']['uniqueWhere'][]
|
|
678
|
+
}): Promise<ListTypeInfo['item'][]>
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
export type NixxieDbAPI<ListsTypeInfo extends Record<string, BaseListTypeInfo>> = {
|
|
682
|
+
[Key in keyof ListsTypeInfo]: DbAPI<ListsTypeInfo[Key]>
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// GraphQL API
|
|
686
|
+
|
|
687
|
+
export type NixxieGraphQLAPI = {
|
|
688
|
+
schema: GraphQLSchema
|
|
689
|
+
run: <TData, TVariables extends Record<string, any>>(
|
|
690
|
+
args: GraphQLExecutionArguments<TData, TVariables>
|
|
691
|
+
) => Promise<TData>
|
|
692
|
+
raw: <TData, TVariables extends Record<string, any>>(
|
|
693
|
+
args: GraphQLExecutionArguments<TData, TVariables>
|
|
694
|
+
) => Promise<ExecutionResult<TData>>
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
type GraphQLExecutionArguments<TData, TVariables> = {
|
|
698
|
+
query: string | DocumentNode | TypedDocumentNode<TData, TVariables>
|
|
699
|
+
variables?: TVariables
|
|
700
|
+
}
|