@tekki-forge/runtime-api 0.1.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.
Files changed (74) hide show
  1. package/README.md +5 -0
  2. package/dist/access.d.ts +15 -0
  3. package/dist/access.js +51 -0
  4. package/dist/access.js.map +1 -0
  5. package/dist/api-keys.d.ts +140 -0
  6. package/dist/api-keys.js +361 -0
  7. package/dist/api-keys.js.map +1 -0
  8. package/dist/backup.d.ts +142 -0
  9. package/dist/backup.js +280 -0
  10. package/dist/backup.js.map +1 -0
  11. package/dist/bootstrap.d.ts +57 -0
  12. package/dist/bootstrap.js +191 -0
  13. package/dist/bootstrap.js.map +1 -0
  14. package/dist/comments.d.ts +139 -0
  15. package/dist/comments.js +370 -0
  16. package/dist/comments.js.map +1 -0
  17. package/dist/computed.d.ts +27 -0
  18. package/dist/computed.js +174 -0
  19. package/dist/computed.js.map +1 -0
  20. package/dist/controllers.d.ts +309 -0
  21. package/dist/controllers.js +634 -0
  22. package/dist/controllers.js.map +1 -0
  23. package/dist/dashboard.d.ts +58 -0
  24. package/dist/dashboard.js +258 -0
  25. package/dist/dashboard.js.map +1 -0
  26. package/dist/errors.d.ts +6 -0
  27. package/dist/errors.js +55 -0
  28. package/dist/errors.js.map +1 -0
  29. package/dist/events.d.ts +39 -0
  30. package/dist/events.js +36 -0
  31. package/dist/events.js.map +1 -0
  32. package/dist/extension.d.ts +103 -0
  33. package/dist/extension.js +8 -0
  34. package/dist/extension.js.map +1 -0
  35. package/dist/import.d.ts +69 -0
  36. package/dist/import.js +347 -0
  37. package/dist/import.js.map +1 -0
  38. package/dist/index.d.ts +22 -0
  39. package/dist/index.js +23 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/jobs.d.ts +41 -0
  42. package/dist/jobs.js +10 -0
  43. package/dist/jobs.js.map +1 -0
  44. package/dist/notifications.d.ts +61 -0
  45. package/dist/notifications.js +195 -0
  46. package/dist/notifications.js.map +1 -0
  47. package/dist/plugin.d.ts +43 -0
  48. package/dist/plugin.js +4 -0
  49. package/dist/plugin.js.map +1 -0
  50. package/dist/query.d.ts +29 -0
  51. package/dist/query.js +192 -0
  52. package/dist/query.js.map +1 -0
  53. package/dist/saved-views.d.ts +42 -0
  54. package/dist/saved-views.js +130 -0
  55. package/dist/saved-views.js.map +1 -0
  56. package/dist/search.d.ts +17 -0
  57. package/dist/search.js +42 -0
  58. package/dist/search.js.map +1 -0
  59. package/dist/seed.d.ts +12 -0
  60. package/dist/seed.js +132 -0
  61. package/dist/seed.js.map +1 -0
  62. package/dist/serialize.d.ts +37 -0
  63. package/dist/serialize.js +165 -0
  64. package/dist/serialize.js.map +1 -0
  65. package/dist/service.d.ts +168 -0
  66. package/dist/service.js +757 -0
  67. package/dist/service.js.map +1 -0
  68. package/dist/teams.d.ts +63 -0
  69. package/dist/teams.js +131 -0
  70. package/dist/teams.js.map +1 -0
  71. package/dist/testing.d.ts +63 -0
  72. package/dist/testing.js +420 -0
  73. package/dist/testing.js.map +1 -0
  74. package/package.json +61 -0
@@ -0,0 +1,69 @@
1
+ import type { EntityIR, FieldIR } from "@tekki-forge/compiler";
2
+ import type { ForgeRequestContext } from "./extension.js";
3
+ import type { ForgeService } from "./service.js";
4
+ export declare const MAX_IMPORT_ROWS = 1000;
5
+ export type DateOrder = "ymd" | "dmy" | "mdy";
6
+ export interface ImportOptions {
7
+ /** Rows keyed by field name, raw text values (as read from the CSV). */
8
+ rows: Record<string, unknown>[];
9
+ /** Update the record whose `matchBy` field (unique field or "id") equals the row's value; create otherwise. */
10
+ matchBy?: string;
11
+ /** Validate and resolve everything but write nothing. */
12
+ dryRun?: boolean;
13
+ /** How to read slashed dates like 03/04/2026. Default "ymd" (ISO); dmy = 03 April, mdy = March 4. */
14
+ dateOrder?: DateOrder;
15
+ }
16
+ export interface ImportRowResult {
17
+ /** 0-based index in `rows`. */
18
+ index: number;
19
+ status: "created" | "updated" | "create" | "update" | "skipped" | "error";
20
+ id?: string;
21
+ errors?: {
22
+ field: string;
23
+ message: string;
24
+ }[];
25
+ }
26
+ type Converted = {
27
+ value: unknown;
28
+ } | {
29
+ error: string;
30
+ };
31
+ /** Fields a CSV column can feed: writable, not files, not the workflow state (set by transitions). */
32
+ export declare function importableFields(entity: EntityIR): FieldIR[];
33
+ /** "1 234,50" / "1,234.50" / "€12" → "1234.50" (string, so decimals keep their precision). */
34
+ export declare function parseNumber(raw: string): string | null;
35
+ export declare function parseDate(raw: string, order?: DateOrder): string | null;
36
+ /** Convert one raw CSV cell into the API input value for `f` (relations are resolved separately). */
37
+ export declare function convertCell(f: FieldIR, raw: string, dateOrder?: DateOrder): Converted;
38
+ /** Split a many-to-many cell: "a; b" or "a | b", falling back to commas. */
39
+ export declare const splitList: (s: string) => string[];
40
+ export declare class ImportService {
41
+ private readonly service;
42
+ private readonly logger;
43
+ constructor(service: ForgeService);
44
+ run(entity: EntityIR, body: unknown, ctx: ForgeRequestContext): Promise<{
45
+ dryRun: boolean;
46
+ summary: {
47
+ create: number;
48
+ update: number;
49
+ errors: number;
50
+ skipped: number;
51
+ created?: undefined;
52
+ updated?: undefined;
53
+ } | {
54
+ created: number;
55
+ updated: number;
56
+ errors: number;
57
+ skipped: number;
58
+ create?: undefined;
59
+ update?: undefined;
60
+ };
61
+ rows: ImportRowResult[];
62
+ }>;
63
+ private parseOptions;
64
+ private resolveLabels;
65
+ private matchExisting;
66
+ private fieldName;
67
+ private errorsOf;
68
+ }
69
+ export {};
package/dist/import.js ADDED
@@ -0,0 +1,347 @@
1
+ import { authorize } from "@tekki-forge/runtime-permissions";
2
+ import { validateInput, writableFields } from "@tekki-forge/runtime-schema";
3
+ import { BadRequestException, ForbiddenException, HttpException, Logger } from "@nestjs/common";
4
+ export const MAX_IMPORT_ROWS = 1000;
5
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
6
+ const TRUE = new Set(["true", "yes", "y", "1", "x", "✓", "on", "oui", "si", "ja"]);
7
+ const FALSE = new Set(["false", "no", "n", "0", "off", "non", "nein"]);
8
+ /** Fields a CSV column can feed: writable, not files, not the workflow state (set by transitions). */
9
+ export function importableFields(entity) {
10
+ return writableFields(entity).filter((f) => !f.file && f.name !== entity.workflow?.field);
11
+ }
12
+ /** "1 234,50" / "1,234.50" / "€12" → "1234.50" (string, so decimals keep their precision). */
13
+ export function parseNumber(raw) {
14
+ let s = raw.replace(/[\s '’]/g, "").replace(/^[^\d+-]+|[^\d]+$/g, "");
15
+ if (!s)
16
+ return null;
17
+ const lastComma = s.lastIndexOf(",");
18
+ const lastDot = s.lastIndexOf(".");
19
+ if (lastComma >= 0 && lastDot >= 0) {
20
+ // The last separator is the decimal one.
21
+ s = lastComma > lastDot ? s.replace(/\./g, "").replace(",", ".") : s.replace(/,/g, "");
22
+ }
23
+ else if (lastComma >= 0) {
24
+ s = /^[+-]?\d{1,3}(,\d{3})+$/.test(s) ? s.replace(/,/g, "") : s.replace(",", ".");
25
+ }
26
+ return /^[+-]?\d+(\.\d+)?$/.test(s) ? s.replace(/^\+/, "") : null;
27
+ }
28
+ export function parseDate(raw, order = "ymd") {
29
+ const s = raw.trim();
30
+ const iso = /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[T ].*)?$/.exec(s);
31
+ const parts = iso ? [iso[1], iso[2], iso[3]] : /^(\d{1,4})[/.-](\d{1,2})[/.-](\d{1,4})$/.exec(s)?.slice(1);
32
+ if (!parts) {
33
+ const t = Date.parse(s);
34
+ return Number.isNaN(t) ? null : new Date(t).toISOString().slice(0, 10);
35
+ }
36
+ const [a, b, c] = parts.map(Number);
37
+ const [y, m, d] = iso || String(parts[0]).length === 4 ? [a, b, c] : order === "mdy" ? [c, a, b] : [c, b, a];
38
+ const year = y < 100 ? 2000 + y : y;
39
+ const date = new Date(Date.UTC(year, m - 1, d));
40
+ if (date.getUTCFullYear() !== year || date.getUTCMonth() !== m - 1 || date.getUTCDate() !== d)
41
+ return null;
42
+ return date.toISOString().slice(0, 10);
43
+ }
44
+ const norm = (s) => s.normalize("NFKD").replace(/\p{M}+/gu, "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "");
45
+ /** Convert one raw CSV cell into the API input value for `f` (relations are resolved separately). */
46
+ export function convertCell(f, raw, dateOrder = "ymd") {
47
+ const s = raw.trim();
48
+ switch (f.kind) {
49
+ case "integer": {
50
+ const n = parseNumber(s);
51
+ return n === null || !Number.isInteger(Number(n)) ? { error: `"${s}" is not a whole number` } : { value: Number(n) };
52
+ }
53
+ case "percentage": {
54
+ const n = parseNumber(s.replace(/%$/, ""));
55
+ return n === null ? { error: `"${s}" is not a number` } : { value: Number(n) };
56
+ }
57
+ case "decimal":
58
+ case "money": {
59
+ const n = parseNumber(s);
60
+ return n === null ? { error: `"${s}" is not a number` } : { value: n };
61
+ }
62
+ case "boolean": {
63
+ const v = s.toLowerCase();
64
+ if (TRUE.has(v))
65
+ return { value: true };
66
+ if (FALSE.has(v))
67
+ return { value: false };
68
+ return { error: `"${s}" is not yes/no` };
69
+ }
70
+ case "enum": {
71
+ const hit = f.enumValues.find((e) => e.value === s) ?? f.enumValues.find((e) => norm(e.value) === norm(s) || norm(e.label) === norm(s));
72
+ return hit ? { value: hit.value } : { error: `"${s}" is not one of ${f.enumValues.map((e) => e.label).join(", ")}` };
73
+ }
74
+ case "date": {
75
+ const d = parseDate(s, dateOrder);
76
+ return d ? { value: d } : { error: `"${s}" is not a date` };
77
+ }
78
+ case "datetime": {
79
+ const dateOnly = parseDate(s, dateOrder);
80
+ const t = /^\d{4}-\d{2}-\d{2}[T ]\d/.test(s) ? Date.parse(s.replace(" ", "T")) : dateOnly ? Date.parse(`${dateOnly}T00:00:00Z`) : Date.parse(s);
81
+ return Number.isNaN(t) ? { error: `"${s}" is not a date and time` } : { value: new Date(t).toISOString() };
82
+ }
83
+ case "location": {
84
+ const m = /^\s*(-?\d+(?:\.\d+)?)\s*[,; ]\s*(-?\d+(?:\.\d+)?)\s*$/.exec(s);
85
+ return m ? { value: { lat: Number(m[1]), lng: Number(m[2]) } } : { error: `"${s}" is not "latitude, longitude"` };
86
+ }
87
+ case "json":
88
+ try {
89
+ return { value: JSON.parse(s) };
90
+ }
91
+ catch {
92
+ return { error: "Invalid JSON" };
93
+ }
94
+ default:
95
+ return { value: s };
96
+ }
97
+ }
98
+ /** Split a many-to-many cell: "a; b" or "a | b", falling back to commas. */
99
+ export const splitList = (s) => (/[;|]/.test(s) ? s.split(/[;|]/) : s.split(",")).map((x) => x.trim()).filter(Boolean);
100
+ export class ImportService {
101
+ service;
102
+ logger = new Logger("ForgeImport");
103
+ constructor(service) {
104
+ this.service = service;
105
+ }
106
+ async run(entity, body, ctx) {
107
+ const opts = this.parseOptions(entity, body);
108
+ if (!authorize(entity, "create", ctx.principal).allowed && !(opts.matchBy && authorize(entity, "update", ctx.principal).allowed)) {
109
+ throw new ForbiddenException(`You cannot import ${entity.pluralLabel.toLowerCase()}`);
110
+ }
111
+ const fields = new Map(importableFields(entity).map((f) => [f.name, f]));
112
+ const results = [];
113
+ const prepared = [];
114
+ // 1. Convert cells.
115
+ const labels = new Map(); // relation field → labels to resolve
116
+ for (const [index, raw] of opts.rows.entries()) {
117
+ const payload = {};
118
+ const errors = [];
119
+ let key;
120
+ for (const [name, value] of Object.entries(raw)) {
121
+ const text = value === null || value === undefined ? "" : String(value).trim();
122
+ if (name === opts.matchBy)
123
+ key = text || undefined;
124
+ if (!text)
125
+ continue;
126
+ if (name === "id")
127
+ continue;
128
+ const f = fields.get(name);
129
+ if (!f) {
130
+ errors.push({ field: name, message: "This column cannot be imported" });
131
+ continue;
132
+ }
133
+ if (f.relation) {
134
+ const list = f.relation.type === "many-to-many" ? splitList(text) : [text];
135
+ const set = labels.get(f.name) ?? new Set();
136
+ for (const l of list)
137
+ set.add(l);
138
+ labels.set(f.name, set);
139
+ payload[f.apiName] = f.relation.type === "many-to-many" ? list : text;
140
+ continue;
141
+ }
142
+ const c = convertCell(f, text, opts.dateOrder);
143
+ if ("error" in c)
144
+ errors.push({ field: f.name, message: c.error });
145
+ else
146
+ payload[f.apiName] = c.value;
147
+ }
148
+ if (!Object.keys(payload).length && !errors.length && !key) {
149
+ results.push({ index, status: "skipped" });
150
+ continue;
151
+ }
152
+ prepared.push({ index, payload, ...(key ? { key } : {}), errors });
153
+ }
154
+ // 2. Resolve relation labels (by id or display value, within what the caller can see).
155
+ const resolved = new Map();
156
+ for (const [name, set] of labels)
157
+ resolved.set(name, await this.resolveLabels(fields.get(name), [...set], ctx));
158
+ for (const p of prepared) {
159
+ for (const [name] of labels) {
160
+ const f = fields.get(name);
161
+ const v = p.payload[f.apiName];
162
+ if (v === undefined)
163
+ continue;
164
+ const ids = [];
165
+ for (const l of Array.isArray(v) ? v : [v]) {
166
+ const hits = resolved.get(name).get(l.toLowerCase()) ?? [];
167
+ if (hits.length === 1)
168
+ ids.push(hits[0]);
169
+ else
170
+ p.errors.push({ field: f.name, message: hits.length ? `"${l}" matches several ${f.label.toLowerCase()} records` : `"${l}" not found` });
171
+ }
172
+ p.payload[f.apiName] = Array.isArray(v) ? ids : ids[0];
173
+ }
174
+ }
175
+ // 3. Match existing records.
176
+ const existing = opts.matchBy ? await this.matchExisting(entity, opts.matchBy, prepared.map((p) => p.key).filter((k) => !!k), ctx) : new Map();
177
+ // 4. Validate (dry run) or write, one record at a time through the regular pipeline (permissions, hooks, events).
178
+ for (const p of prepared) {
179
+ const id = p.key ? existing.get(p.key) : undefined;
180
+ if (opts.matchBy && p.key && !id && opts.matchBy !== "id") {
181
+ const f = fields.get(opts.matchBy);
182
+ if (f && p.payload[f.apiName] === undefined)
183
+ p.payload[f.apiName] = p.key;
184
+ }
185
+ if (opts.matchBy === "id" && p.key && !id)
186
+ p.errors.push({ field: "id", message: `No record with id "${p.key}"` });
187
+ if (p.errors.length) {
188
+ results.push({ index: p.index, status: "error", errors: p.errors });
189
+ continue;
190
+ }
191
+ const mode = id ? "update" : "create";
192
+ if (!authorize(entity, mode, ctx.principal).allowed) {
193
+ results.push({ index: p.index, status: "error", errors: [{ field: "", message: `You cannot ${mode} ${entity.pluralLabel.toLowerCase()}` }] });
194
+ continue;
195
+ }
196
+ if (opts.dryRun) {
197
+ const v = validateInput(entity, mode, p.payload);
198
+ const errors = v.success ? [] : v.issues.map((i) => ({ field: this.fieldName(entity, i.path), message: i.message }));
199
+ results.push(errors.length ? { index: p.index, status: "error", errors } : { index: p.index, status: mode, ...(id ? { id } : {}) });
200
+ continue;
201
+ }
202
+ try {
203
+ const record = id ? await this.service.update(entity, id, p.payload, ctx) : await this.service.create(entity, p.payload, ctx);
204
+ results.push({ index: p.index, status: id ? "updated" : "created", id: record.id });
205
+ }
206
+ catch (e) {
207
+ results.push({ index: p.index, status: "error", errors: this.errorsOf(entity, e) });
208
+ }
209
+ }
210
+ results.sort((a, b) => a.index - b.index);
211
+ const count = (s) => results.filter((r) => r.status === s).length;
212
+ return {
213
+ dryRun: !!opts.dryRun,
214
+ summary: opts.dryRun
215
+ ? { create: count("create"), update: count("update"), errors: count("error"), skipped: count("skipped") }
216
+ : { created: count("created"), updated: count("updated"), errors: count("error"), skipped: count("skipped") },
217
+ rows: results,
218
+ };
219
+ }
220
+ parseOptions(entity, body) {
221
+ const b = (body ?? {});
222
+ if (!Array.isArray(b.rows))
223
+ throw new BadRequestException("rows must be an array");
224
+ if (b.rows.length > MAX_IMPORT_ROWS)
225
+ throw new BadRequestException(`At most ${MAX_IMPORT_ROWS} rows per request — send the file in batches`);
226
+ if (b.rows.some((r) => !r || typeof r !== "object" || Array.isArray(r)))
227
+ throw new BadRequestException("Each row must be an object keyed by field name");
228
+ const dateOrder = b.dateOrder ?? "ymd";
229
+ if (!["ymd", "dmy", "mdy"].includes(dateOrder))
230
+ throw new BadRequestException("dateOrder must be ymd, dmy or mdy");
231
+ if (b.matchBy !== undefined && b.matchBy !== null) {
232
+ const f = entity.fields.find((x) => x.name === b.matchBy);
233
+ if (b.matchBy !== "id" && !(f && f.unique && !f.relation))
234
+ throw new BadRequestException(`matchBy must be "id" or a unique field of ${entity.name}`);
235
+ }
236
+ return { rows: b.rows, dateOrder, ...(b.matchBy ? { matchBy: b.matchBy } : {}), dryRun: b.dryRun === true };
237
+ }
238
+ async resolveLabels(f, labels, ctx) {
239
+ const rel = f.relation;
240
+ const out = new Map();
241
+ const add = (key, id) => {
242
+ if (key === null || key === undefined)
243
+ return;
244
+ const k = String(key).toLowerCase();
245
+ const list = out.get(k) ?? [];
246
+ if (!list.includes(id))
247
+ list.push(id);
248
+ out.set(k, list);
249
+ };
250
+ for (let i = 0; i < labels.length; i += 500) {
251
+ const chunk = labels.slice(i, i + 500);
252
+ const chunkIds = chunk.filter((l) => UUID.test(l));
253
+ if (rel.entity === "User") {
254
+ const where = [{ OR: [{ id: { in: chunkIds } }, { email: { in: chunk, mode: "insensitive" } }, { name: { in: chunk, mode: "insensitive" } }] }];
255
+ if (this.service.app.tenancy.enabled)
256
+ where.push({ members: { some: { organizationId: ctx.principal?.organizationId ?? "__none__" } } });
257
+ const users = await this.service.prisma.user.findMany({ where: { AND: where }, select: { id: true, email: true, name: true } });
258
+ for (const u of users) {
259
+ add(u.id, u.id);
260
+ add(u.email, u.id);
261
+ add(u.name, u.id); // two users with the same name → ambiguous (use their email)
262
+ }
263
+ continue;
264
+ }
265
+ if (rel.entity === "Team") {
266
+ const teams = await this.service.prisma.team.findMany({
267
+ where: { organizationId: ctx.principal?.organizationId ?? "__none__", OR: [{ id: { in: chunkIds } }, { name: { in: chunk, mode: "insensitive" } }] },
268
+ select: { id: true, name: true },
269
+ });
270
+ for (const t of teams) {
271
+ add(t.id, t.id);
272
+ add(t.name, t.id);
273
+ }
274
+ continue;
275
+ }
276
+ const target = this.service.entityByName(rel.entity);
277
+ if (!target)
278
+ continue;
279
+ if (!authorize(target, "read", ctx.principal).allowed)
280
+ continue;
281
+ const display = rel.targetDisplay;
282
+ const or = [{ id: { in: chunkIds } }];
283
+ if (display !== "id")
284
+ or.push({ [display]: { in: chunk, mode: "insensitive" } });
285
+ const rows = await this.service.delegate(target).findMany({
286
+ where: { AND: [...this.service.readWhere(target, ctx), { OR: or }] },
287
+ select: { id: true, ...(display !== "id" ? { [display]: true } : {}) },
288
+ take: 5000,
289
+ });
290
+ for (const r of rows) {
291
+ add(r.id, r.id);
292
+ if (display !== "id")
293
+ add(r[display], r.id);
294
+ }
295
+ }
296
+ return out;
297
+ }
298
+ async matchExisting(entity, matchBy, keys, ctx) {
299
+ const out = new Map();
300
+ const f = entity.fields.find((x) => x.name === matchBy);
301
+ const column = matchBy === "id" ? "id" : f.name;
302
+ let values = [...new Set(keys)];
303
+ if (matchBy === "id")
304
+ values = values.filter((v) => UUID.test(String(v)));
305
+ else if (f && f.kind !== "string" && f.kind !== "email" && f.kind !== "url" && f.kind !== "phone" && f.kind !== "text") {
306
+ values = values.map((v) => {
307
+ const c = convertCell(f, String(v));
308
+ return "value" in c ? c.value : undefined;
309
+ });
310
+ }
311
+ for (let i = 0; i < values.length; i += 500) {
312
+ const chunk = values.slice(i, i + 500).filter((v) => v !== undefined);
313
+ if (!chunk.length)
314
+ continue;
315
+ const rows = await this.service.delegate(entity).findMany({ where: { AND: [...this.service.readWhere(entity, ctx), { [column]: { in: chunk } }] }, select: { id: true, [column]: true } });
316
+ for (const r of rows)
317
+ out.set(String(r[column]), r.id);
318
+ }
319
+ // Map raw keys back to ids (the raw text may differ from the stored value, e.g. " 42 " vs 42).
320
+ const byRaw = new Map();
321
+ for (const k of keys) {
322
+ const c = matchBy === "id" || !f ? { value: k } : convertCell(f, k);
323
+ const id = "value" in c ? out.get(String(c.value)) : undefined;
324
+ if (id)
325
+ byRaw.set(k, id);
326
+ }
327
+ return byRaw;
328
+ }
329
+ fieldName(entity, path) {
330
+ return entity.fields.find((f) => f.apiName === path || f.name === path)?.name ?? path;
331
+ }
332
+ errorsOf(entity, e) {
333
+ if (e instanceof HttpException) {
334
+ const body = e.getResponse();
335
+ if (typeof body === "object" && Array.isArray(body.issues) && body.issues.length) {
336
+ return body.issues.map((i) => ({ field: this.fieldName(entity, String(i.path)), message: String(i.message) }));
337
+ }
338
+ return [{ field: "", message: typeof body === "string" ? body : String(body.message ?? e.message) }];
339
+ }
340
+ const code = e?.code;
341
+ if (code === "P2002")
342
+ return [{ field: "", message: "A record with the same unique value already exists" }];
343
+ this.logger.error(e);
344
+ return [{ field: "", message: "Could not save this row" }];
345
+ }
346
+ }
347
+ //# sourceMappingURL=import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import.js","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export * from "./extension.js";
2
+ export * from "./query.js";
3
+ export * from "./serialize.js";
4
+ export * from "./service.js";
5
+ export * from "./errors.js";
6
+ export { FORGE_SERVICE, ResourceController, SystemController, requestContext } from "./controllers.js";
7
+ export * from "./plugin.js";
8
+ export * from "./bootstrap.js";
9
+ export { BadRequestException, ConflictException, ForbiddenException, NotFoundException, UnauthorizedException, } from "@nestjs/common";
10
+ export * from "./seed.js";
11
+ export * from "./events.js";
12
+ export * from "./computed.js";
13
+ export * from "./access.js";
14
+ export * from "./notifications.js";
15
+ export * from "./jobs.js";
16
+ export * from "./dashboard.js";
17
+ export * from "./saved-views.js";
18
+ export * from "./search.js";
19
+ export * from "./import.js";
20
+ export * from "./teams.js";
21
+ export * from "./api-keys.js";
22
+ export * from "./comments.js";
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ export * from "./extension.js";
2
+ export * from "./query.js";
3
+ export * from "./serialize.js";
4
+ export * from "./service.js";
5
+ export * from "./errors.js";
6
+ export { FORGE_SERVICE, ResourceController, SystemController, requestContext } from "./controllers.js";
7
+ export * from "./plugin.js";
8
+ export * from "./bootstrap.js";
9
+ export { BadRequestException, ConflictException, ForbiddenException, NotFoundException, UnauthorizedException, } from "@nestjs/common";
10
+ export * from "./seed.js";
11
+ export * from "./events.js";
12
+ export * from "./computed.js";
13
+ export * from "./access.js";
14
+ export * from "./notifications.js";
15
+ export * from "./jobs.js";
16
+ export * from "./dashboard.js";
17
+ export * from "./saved-views.js";
18
+ export * from "./search.js";
19
+ export * from "./import.js";
20
+ export * from "./teams.js";
21
+ export * from "./api-keys.js";
22
+ export * from "./comments.js";
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvG,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
package/dist/jobs.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ import type { HookContext } from "./extension.js";
2
+ export interface JobContext extends Omit<HookContext, "entity" | "principal" | "user" | "session"> {
3
+ /** Payload given to enqueue(). */
4
+ data: any;
5
+ /** Attempt number, starting at 1. */
6
+ attempt: number;
7
+ log(message: string): void;
8
+ /** Update progress (0–100) shown in the admin jobs page. */
9
+ progress(percent: number): Promise<void>;
10
+ }
11
+ export interface JobDefinition<D = any> {
12
+ name: string;
13
+ /** Cron pattern for scheduled jobs, e.g. "0 8 * * 1" (Mondays 08:00). */
14
+ schedule?: string;
15
+ /** IANA time zone for the schedule. Default UTC. */
16
+ timezone?: string;
17
+ /** Attempts before the job is marked failed. Default 3. */
18
+ attempts?: number;
19
+ /** First retry delay in ms (doubles each time). Default 30s. */
20
+ backoff?: number;
21
+ /** Abort after this many ms. Default 5 minutes. */
22
+ timeout?: number;
23
+ handler(ctx: JobContext & {
24
+ data: D;
25
+ }): unknown | Promise<unknown>;
26
+ }
27
+ /**
28
+ * A background job. Put it in apps/api/src/jobs/<name>.job.ts; `forge generate` registers it.
29
+ * Enqueue from hooks/actions: `ctx.use<JobQueue>("jobs")?.enqueue("sendReport", { id })`.
30
+ */
31
+ export declare function defineJob<D = any>(name: string, definition: Omit<JobDefinition<D>, "name">): JobDefinition<D>;
32
+ /** Shared by the jobs plugin under the name "jobs". */
33
+ export interface JobQueue {
34
+ enqueue(name: string, data?: unknown, options?: {
35
+ delay?: number;
36
+ jobId?: string;
37
+ attempts?: number;
38
+ priority?: number;
39
+ backoff?: number;
40
+ }): Promise<string>;
41
+ }
package/dist/jobs.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * A background job. Put it in apps/api/src/jobs/<name>.job.ts; `forge generate` registers it.
3
+ * Enqueue from hooks/actions: `ctx.use<JobQueue>("jobs")?.enqueue("sendReport", { id })`.
4
+ */
5
+ export function defineJob(name, definition) {
6
+ if (!/^[a-zA-Z][\w.-]*$/.test(name))
7
+ throw new Error(`Invalid job name "${name}"`);
8
+ return { name, ...definition };
9
+ }
10
+ //# sourceMappingURL=jobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../src/jobs.ts"],"names":[],"mappings":"AA2BA;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAU,IAAY,EAAE,UAA0C;IACzF,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;IACnF,OAAO,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,CAAC;AACjC,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { AppIR, EntityIR } from "@tekki-forge/compiler";
2
+ import { type Principal } from "@tekki-forge/runtime-permissions";
3
+ import type { ForgeEvent } from "./events.js";
4
+ import type { ForgeRequestContext } from "./extension.js";
5
+ type Row = Record<string, any>;
6
+ export interface NotifyInput {
7
+ title: string;
8
+ body?: string;
9
+ link?: string;
10
+ organizationId?: string | null;
11
+ entity?: string;
12
+ recordId?: string;
13
+ event?: string;
14
+ /** Also email each recipient (templated "notification" email). */
15
+ email?: boolean;
16
+ }
17
+ export interface MailSender {
18
+ send(input: {
19
+ to: string;
20
+ template: string;
21
+ props?: Record<string, unknown>;
22
+ }): Promise<void>;
23
+ }
24
+ /** Stored notifications, live delivery (SSE) and the rules declared in forge.config.ts. */
25
+ export declare class NotificationService {
26
+ private readonly app;
27
+ private readonly prisma;
28
+ private readonly mail?;
29
+ private readonly policyCheck?;
30
+ private readonly logger;
31
+ private readonly local;
32
+ /** Cross-instance fan-out (the jobs plugin plugs Redis pub/sub in here). */
33
+ private publisher?;
34
+ constructor(app: AppIR, prisma: any, mail?: MailSender | undefined, policyCheck?: ((entity: EntityIR, principal: Principal) => (name: string, record: Row) => boolean | Promise<boolean>) | undefined);
35
+ usePubSub(publish: (userId: string, payload: Row) => void): void;
36
+ /** Deliver a payload published by another instance to this instance's open streams. */
37
+ receive(userId: string, payload: Row): void;
38
+ notify(userIds: string[], input: NotifyInput): Promise<number>;
39
+ private fill;
40
+ private principalFor;
41
+ private recipients;
42
+ /** Apply the configured rules to one event (subscribed on the event bus). */
43
+ handle(event: ForgeEvent): Promise<void>;
44
+ private scope;
45
+ list(ctx: ForgeRequestContext, query: Row): Promise<{
46
+ data: any;
47
+ unread: any;
48
+ meta: {
49
+ page: number;
50
+ pageSize: number;
51
+ total: any;
52
+ pages: number;
53
+ };
54
+ }>;
55
+ markRead(ctx: ForgeRequestContext, body: Row): Promise<{
56
+ updated: any;
57
+ }>;
58
+ /** Subscribe to live notifications for this user; returns an unsubscribe function. */
59
+ subscribe(userId: string, send: (payload: Row) => void): () => void;
60
+ }
61
+ export {};