@nivaro/extension-kit 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +78 -0
  2. package/dist/column-probe.d.ts +9 -0
  3. package/dist/column-probe.d.ts.map +1 -0
  4. package/dist/column-probe.js +58 -0
  5. package/dist/column-probe.js.map +1 -0
  6. package/dist/context.d.ts +361 -0
  7. package/dist/context.d.ts.map +1 -0
  8. package/dist/context.js +2 -0
  9. package/dist/context.js.map +1 -0
  10. package/dist/flows.d.ts +58 -0
  11. package/dist/flows.d.ts.map +1 -0
  12. package/dist/flows.js +2 -0
  13. package/dist/flows.js.map +1 -0
  14. package/dist/hooks.d.ts +26 -0
  15. package/dist/hooks.d.ts.map +1 -0
  16. package/dist/hooks.js +2 -0
  17. package/dist/hooks.js.map +1 -0
  18. package/dist/imports.d.ts +155 -0
  19. package/dist/imports.d.ts.map +1 -0
  20. package/dist/imports.js +2 -0
  21. package/dist/imports.js.map +1 -0
  22. package/dist/index.d.ts +22 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +15 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/notifications.d.ts +183 -0
  27. package/dist/notifications.d.ts.map +1 -0
  28. package/dist/notifications.js +2 -0
  29. package/dist/notifications.js.map +1 -0
  30. package/dist/obligations.d.ts +66 -0
  31. package/dist/obligations.d.ts.map +1 -0
  32. package/dist/obligations.js +2 -0
  33. package/dist/obligations.js.map +1 -0
  34. package/dist/registrations.d.ts +470 -0
  35. package/dist/registrations.d.ts.map +1 -0
  36. package/dist/registrations.js +2 -0
  37. package/dist/registrations.js.map +1 -0
  38. package/dist/requester-columns.d.ts +26 -0
  39. package/dist/requester-columns.d.ts.map +1 -0
  40. package/dist/requester-columns.js +17 -0
  41. package/dist/requester-columns.js.map +1 -0
  42. package/dist/signals.d.ts +77 -0
  43. package/dist/signals.d.ts.map +1 -0
  44. package/dist/signals.js +2 -0
  45. package/dist/signals.js.map +1 -0
  46. package/dist/testing.d.ts +193 -0
  47. package/dist/testing.d.ts.map +1 -0
  48. package/dist/testing.js +615 -0
  49. package/dist/testing.js.map +1 -0
  50. package/dist/user.d.ts +27 -0
  51. package/dist/user.d.ts.map +1 -0
  52. package/dist/user.js +2 -0
  53. package/dist/user.js.map +1 -0
  54. package/package.json +59 -0
@@ -0,0 +1,193 @@
1
+ /**
2
+ * A test double for the extension context (#829): every registration is
3
+ * recorded, every side effect is captured instead of sent, hooks and crons
4
+ * can be run by the test, and the database is an in-memory fake with the
5
+ * knex chain shape extensions actually use. Nothing here boots the API.
6
+ *
7
+ * const ctx = createTestContext({ tables: { orders: [{ id: 1, total: 5 }] } })
8
+ * await myExtension.register(ctx)
9
+ * await ctx.runHooks('orders', 'create', 'after', { keys: [1], result: { id: 1, total: 5 } })
10
+ * expect(ctx.calls.notifications).toHaveLength(1)
11
+ */
12
+ import type { Knex } from 'knex';
13
+ import type { ExtensionContext, ExtensionCronMeta, ExtensionCronOpts, ExtensionEventHandler, ExtensionSettingValue } from './context.js';
14
+ import type { FlowOpRegistration, FlowTriggerRegistration } from './flows.js';
15
+ import type { ExtensionHookContext, ExtensionHookHandler, HookAction, HookTiming } from './hooks.js';
16
+ import type { ImportProcessorDef } from './imports.js';
17
+ import type { DigestSectionProvider, MailTypeDef, NotificationChannelDef, NotificationSourceProvider, NotifyUserOptions } from './notifications.js';
18
+ import type { ObligationKindDef, ObligationResolvePatch, ObligationTrigger, ObligationTriggerContext } from './obligations.js';
19
+ import type { BotToolDef, BriefLineProvider, BulkActionDef, CallOptions, CallResult, CollectionViewDef, ConfigSeedDef, DashboardWidgetDef, EventSourceDef, FieldTypeDef, ImportParserDef, IntegrityCheck, ItemActionDef, LinkRegistration, MachineMarkerSet, OpsTaskDef, OpsTaskOutcome, ReadinessCheck, RelatedNoteProvider, SchemaStepDef, StorageAdapter, ValidatorDef } from './registrations.js';
20
+ import type { IntegrationSignal, SignalActionHandler } from './signals.js';
21
+ import type { ExtensionUser } from './user.js';
22
+ type Row = Record<string, unknown>;
23
+ export interface TestDbState {
24
+ tables: Record<string, Row[]>;
25
+ /** Every statement the fake ran, in order — assert on writes. */
26
+ log: Array<{
27
+ table: string;
28
+ op: 'select' | 'insert' | 'update' | 'delete' | 'raw' | 'schema';
29
+ detail?: unknown;
30
+ }>;
31
+ }
32
+ /**
33
+ * A knex-shaped in-memory database. Supports the chain extensions use:
34
+ * select / where (object, col=val, col op val, callback) / whereIn /
35
+ * whereNotIn / whereNull / whereNotNull / orderBy / limit / offset /
36
+ * first / pluck / count / insert(+returning) / update / del, `db.raw`
37
+ * (answers `[]` unless `raw` is given), `db.schema.hasColumn` / hasTable /
38
+ * createTable / alterTable / dropTable (tables recorded, columns not
39
+ * modelled), `db.transaction`, `db.fn.now`. Joins are accepted and ignored — a test
40
+ * seeds the joined columns on the row it expects back.
41
+ */
42
+ export declare function createTestDb(opts?: {
43
+ tables?: Record<string, Row[]>;
44
+ raw?: (sql: string, bindings?: unknown) => unknown;
45
+ }): Knex & {
46
+ state: TestDbState;
47
+ };
48
+ export interface TestRoute {
49
+ method: string;
50
+ url: string;
51
+ handler: (req: unknown, reply: unknown) => unknown;
52
+ opts: Record<string, unknown>;
53
+ }
54
+ export interface TestContextOptions {
55
+ /** A knex, or seed rows for the in-memory fake (`createTestDb`). */
56
+ db?: Knex;
57
+ tables?: Record<string, Row[]>;
58
+ /** The acting user hooks see; defaults to an active admin-less person. */
59
+ user?: Partial<ExtensionUser>;
60
+ /** Values `ctx.settings.get` answers. */
61
+ settings?: Record<string, ExtensionSettingValue>;
62
+ /** What `callExternalApi` answers; default `{status: 200, body: {}}`. */
63
+ externalApi?: (nameOrId: string | number, options?: CallOptions) => CallResult | Promise<CallResult>;
64
+ /** What `mail.renderTemplate` returns; default the template name. */
65
+ renderTemplate?: (name: string, data: Record<string, unknown>) => string;
66
+ }
67
+ export interface TestContext extends ExtensionContext {
68
+ database: Knex & {
69
+ state?: TestDbState;
70
+ };
71
+ user: ExtensionUser;
72
+ /** Every side effect the extension asked for, in order. */
73
+ calls: {
74
+ notifications: Array<{
75
+ userId: string;
76
+ opts: NotifyUserOptions;
77
+ }>;
78
+ externalApi: Array<{
79
+ nameOrId: string | number;
80
+ options?: CallOptions;
81
+ result: CallResult;
82
+ }>;
83
+ activity: Array<Parameters<ExtensionContext['logActivity']>[0]>;
84
+ flowsEmitted: Array<{
85
+ type: string;
86
+ payload: Record<string, unknown>;
87
+ }>;
88
+ eventsPublished: Array<{
89
+ eventType: string;
90
+ payload: unknown;
91
+ }>;
92
+ obligationsOpened: Array<{
93
+ ctx: ObligationTriggerContext;
94
+ trigger: ObligationTrigger;
95
+ trigger_ref: string | null;
96
+ id: number;
97
+ }>;
98
+ obligationsResolved: Array<{
99
+ id: number | null;
100
+ patch: ObligationResolvePatch;
101
+ }>;
102
+ longSql: Array<{
103
+ sql: string;
104
+ opts?: {
105
+ timeoutMs?: number;
106
+ };
107
+ }>;
108
+ log: Array<{
109
+ level: 'info' | 'warn' | 'error' | 'debug';
110
+ args: unknown[];
111
+ }>;
112
+ };
113
+ /** Everything the extension registered, by kind. */
114
+ registered: {
115
+ hooks: Array<{
116
+ collection: string;
117
+ action: string;
118
+ timing: HookTiming;
119
+ fn: ExtensionHookHandler;
120
+ }>;
121
+ crons: Map<string, {
122
+ expression: string;
123
+ fn: () => void | Promise<void>;
124
+ opts?: ExtensionCronOpts;
125
+ meta?: ExtensionCronMeta;
126
+ }>;
127
+ routes: TestRoute[];
128
+ eventHandlers: Array<{
129
+ eventType: string;
130
+ fn: ExtensionEventHandler;
131
+ }>;
132
+ bulkActions: BulkActionDef[];
133
+ itemActions: ItemActionDef[];
134
+ notificationChannels: NotificationChannelDef[];
135
+ notificationSources: NotificationSourceProvider[];
136
+ noteSources: RelatedNoteProvider[];
137
+ machineMarkers: MachineMarkerSet[];
138
+ dashboardWidgets: DashboardWidgetDef[];
139
+ storage: Map<string, StorageAdapter>;
140
+ activeStorage: string | null;
141
+ fieldTypes: FieldTypeDef[];
142
+ collectionViews: CollectionViewDef[];
143
+ importParsers: ImportParserDef[];
144
+ importProcessors: ImportProcessorDef[];
145
+ validators: ValidatorDef[];
146
+ briefLines: Array<{
147
+ collection: string;
148
+ fn: BriefLineProvider;
149
+ }>;
150
+ digestSections: DigestSectionProvider[];
151
+ readinessChecks: ReadinessCheck[];
152
+ tasks: OpsTaskDef[];
153
+ seeds: ConfigSeedDef[];
154
+ schemaSteps: SchemaStepDef[];
155
+ obligationKinds: ObligationKindDef[];
156
+ signals: IntegrationSignal[];
157
+ signalActions: SignalActionHandler[];
158
+ eventSources: EventSourceDef[];
159
+ integrityChecks: IntegrityCheck[];
160
+ links: LinkRegistration[];
161
+ mailTypes: MailTypeDef[];
162
+ flowOps: FlowOpRegistration[];
163
+ flowTriggers: FlowTriggerRegistration[];
164
+ botTools: BotToolDef[];
165
+ };
166
+ /** Run the registered hooks for a write, as the items service would. */
167
+ runHooks(collection: string, action: HookAction, timing: HookTiming, ctx: Partial<Omit<ExtensionHookContext, 'collection' | 'action' | 'database'>>): Promise<ExtensionHookContext>;
168
+ /** Run one registered cron job by its (unscoped) id. */
169
+ runCron(id: string): Promise<void>;
170
+ /** Run a registered operational task; its log lines come back with the outcome. */
171
+ runTask(key: string, opts?: {
172
+ execute?: boolean;
173
+ }): Promise<OpsTaskOutcome & {
174
+ log: string[];
175
+ }>;
176
+ /** Deliver an event to the registered handlers. */
177
+ deliverEvent(eventType: string, payload: unknown): Promise<void>;
178
+ /** Call a registered route with a fake request; answers `{status, body}`. */
179
+ invoke(method: string, url: string, req?: {
180
+ params?: Row;
181
+ query?: Row;
182
+ body?: unknown;
183
+ headers?: Record<string, string>;
184
+ user?: ExtensionUser | null;
185
+ }): Promise<{
186
+ status: number;
187
+ body: unknown;
188
+ }>;
189
+ }
190
+ /** Build a context whose every effect is recorded. */
191
+ export declare function createTestContext(opts?: TestContextOptions): TestContext;
192
+ export {};
193
+ //# sourceMappingURL=testing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}