@softacus-software/elwis-data-mcp 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 (118) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +6 -0
  3. package/README.md +183 -0
  4. package/dist/app-scope.js +92 -0
  5. package/dist/app-scope.js.map +1 -0
  6. package/dist/artifact-read.js +114 -0
  7. package/dist/artifact-read.js.map +1 -0
  8. package/dist/audit.js +36 -0
  9. package/dist/audit.js.map +1 -0
  10. package/dist/builders/artifact-type-execute.js +100 -0
  11. package/dist/builders/artifact-type-execute.js.map +1 -0
  12. package/dist/builders/artifact-type-plan.js +139 -0
  13. package/dist/builders/artifact-type-plan.js.map +1 -0
  14. package/dist/builders/design-interview.js +246 -0
  15. package/dist/builders/design-interview.js.map +1 -0
  16. package/dist/builders/entity-lifecycle-execute.js +12 -0
  17. package/dist/builders/entity-lifecycle-execute.js.map +1 -0
  18. package/dist/builders/entity-lifecycle-plan.js +345 -0
  19. package/dist/builders/entity-lifecycle-plan.js.map +1 -0
  20. package/dist/builders/links-execute.js +50 -0
  21. package/dist/builders/links-execute.js.map +1 -0
  22. package/dist/builders/links-plan.js +62 -0
  23. package/dist/builders/links-plan.js.map +1 -0
  24. package/dist/builders/page-execute.js +38 -0
  25. package/dist/builders/page-execute.js.map +1 -0
  26. package/dist/builders/page-plan.js +148 -0
  27. package/dist/builders/page-plan.js.map +1 -0
  28. package/dist/builders/records-execute.js +24 -0
  29. package/dist/builders/records-execute.js.map +1 -0
  30. package/dist/builders/records-lifecycle-execute.js +30 -0
  31. package/dist/builders/records-lifecycle-execute.js.map +1 -0
  32. package/dist/builders/records-lifecycle-plan.js +199 -0
  33. package/dist/builders/records-lifecycle-plan.js.map +1 -0
  34. package/dist/builders/records-plan.js +74 -0
  35. package/dist/builders/records-plan.js.map +1 -0
  36. package/dist/builders/update-page-execute.js +38 -0
  37. package/dist/builders/update-page-execute.js.map +1 -0
  38. package/dist/builders/update-page-plan.js +137 -0
  39. package/dist/builders/update-page-plan.js.map +1 -0
  40. package/dist/builders/workflow-execute.js +11 -0
  41. package/dist/builders/workflow-execute.js.map +1 -0
  42. package/dist/builders/workflow-plan.js +115 -0
  43. package/dist/builders/workflow-plan.js.map +1 -0
  44. package/dist/cli/client-configs.js +98 -0
  45. package/dist/cli/client-configs.js.map +1 -0
  46. package/dist/cli/login.js +64 -0
  47. package/dist/cli/login.js.map +1 -0
  48. package/dist/cli/prompter.js +77 -0
  49. package/dist/cli/prompter.js.map +1 -0
  50. package/dist/cli/setup.js +214 -0
  51. package/dist/cli/setup.js.map +1 -0
  52. package/dist/config.js +38 -0
  53. package/dist/config.js.map +1 -0
  54. package/dist/confirm.js +22 -0
  55. package/dist/confirm.js.map +1 -0
  56. package/dist/elwis-api.js +96 -0
  57. package/dist/elwis-api.js.map +1 -0
  58. package/dist/http-client.js +142 -0
  59. package/dist/http-client.js.map +1 -0
  60. package/dist/index.js +20 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/jwt.js +18 -0
  63. package/dist/jwt.js.map +1 -0
  64. package/dist/prune.js +9 -0
  65. package/dist/prune.js.map +1 -0
  66. package/dist/resolve.js +71 -0
  67. package/dist/resolve.js.map +1 -0
  68. package/dist/result.js +16 -0
  69. package/dist/result.js.map +1 -0
  70. package/dist/server.js +82 -0
  71. package/dist/server.js.map +1 -0
  72. package/dist/session-store.js +51 -0
  73. package/dist/session-store.js.map +1 -0
  74. package/dist/tools/build-artifact-type.js +36 -0
  75. package/dist/tools/build-artifact-type.js.map +1 -0
  76. package/dist/tools/build-links.js +33 -0
  77. package/dist/tools/build-links.js.map +1 -0
  78. package/dist/tools/build-page.js +40 -0
  79. package/dist/tools/build-page.js.map +1 -0
  80. package/dist/tools/build-workflow.js +36 -0
  81. package/dist/tools/build-workflow.js.map +1 -0
  82. package/dist/tools/create-application.js +44 -0
  83. package/dist/tools/create-application.js.map +1 -0
  84. package/dist/tools/create-artifacts.js +33 -0
  85. package/dist/tools/create-artifacts.js.map +1 -0
  86. package/dist/tools/create-folder.js +55 -0
  87. package/dist/tools/create-folder.js.map +1 -0
  88. package/dist/tools/delete-artifacts.js +33 -0
  89. package/dist/tools/delete-artifacts.js.map +1 -0
  90. package/dist/tools/delete-entity.js +35 -0
  91. package/dist/tools/delete-entity.js.map +1 -0
  92. package/dist/tools/explain-access.js +40 -0
  93. package/dist/tools/explain-access.js.map +1 -0
  94. package/dist/tools/get-entity.js +36 -0
  95. package/dist/tools/get-entity.js.map +1 -0
  96. package/dist/tools/get-page.js +75 -0
  97. package/dist/tools/get-page.js.map +1 -0
  98. package/dist/tools/list-apps.js +22 -0
  99. package/dist/tools/list-apps.js.map +1 -0
  100. package/dist/tools/list-entities.js +43 -0
  101. package/dist/tools/list-entities.js.map +1 -0
  102. package/dist/tools/propose-page-design.js +17 -0
  103. package/dist/tools/propose-page-design.js.map +1 -0
  104. package/dist/tools/raw-api.js +132 -0
  105. package/dist/tools/raw-api.js.map +1 -0
  106. package/dist/tools/read-artifacts.js +197 -0
  107. package/dist/tools/read-artifacts.js.map +1 -0
  108. package/dist/tools/resolve-entity.js +22 -0
  109. package/dist/tools/resolve-entity.js.map +1 -0
  110. package/dist/tools/update-artifacts.js +33 -0
  111. package/dist/tools/update-artifacts.js.map +1 -0
  112. package/dist/tools/update-entity.js +41 -0
  113. package/dist/tools/update-entity.js.map +1 -0
  114. package/dist/tools/update-page.js +40 -0
  115. package/dist/tools/update-page.js.map +1 -0
  116. package/dist/write-gate.js +25 -0
  117. package/dist/write-gate.js.map +1 -0
  118. package/package.json +55 -0
@@ -0,0 +1,345 @@
1
+ import { z } from 'zod';
2
+ import { AmbiguityError, IsObjectId, ResolveOneId, ResolveApplicationId } from '../resolve.js';
3
+ export const UPDATE_ENTITY_KINDS = ['application', 'dataType', 'attribute', 'artifactType', 'linkType', 'workflow', 'folder'];
4
+ export const DELETE_ENTITY_KINDS = ['application', 'dataType', 'attribute', 'artifactType', 'linkType', 'workflow', 'page', 'link', 'folder'];
5
+ const KIND_MAP = {
6
+ application: 'application',
7
+ dataType: 'data-type',
8
+ attribute: 'attribute',
9
+ artifactType: 'artifact-type',
10
+ linkType: 'link-type',
11
+ workflow: 'workflow',
12
+ page: 'page',
13
+ link: 'link',
14
+ folder: 'folder',
15
+ };
16
+ export const UPDATABLE_FIELDS = {
17
+ application: ['name', 'description', 'defaultPageId', 'thumbnailFileArtifactId'],
18
+ dataType: ['name', 'description', 'uri', 'values', 'minimum', 'maximum', 'siUnit', 'units', 'deletedOptions'],
19
+ attribute: ['name', 'alias', 'description', 'icon', 'uri', 'counterFormat', 'counterNextValue', 'multipleValuesOrdering'],
20
+ artifactType: ['name', 'description', 'icon', 'format', 'color', 'attributes', 'primaryAttributes', 'defaultFolderId', 'defaultPageId', 'defaultWidgets', 'delimiter', 'isLoggingDisabled', 'avrMapper', 'avrTriggers', 'preferredArtifactTypeIds', 'inheritableAcl', 'defaultIsHeading'],
21
+ linkType: ['name', 'alias', 'description', 'uri', 'source', 'destination', 'restrictions'],
22
+ workflow: ['name', 'description', 'defaultArtifactTypeId', 'triggers', 'usedIn', 'global', 'priority', 'condition', 'state', 'actions'],
23
+ folder: ['name', 'parentFolderId', 'folderSequence'],
24
+ };
25
+ const TargetRef = z.string().min(1).describe('Entity name, alias, or 24-char hex id (links have no name and must be addressed by id)');
26
+ const ConfirmField = z.string().optional().describe('Confirmation token from the previous preview of this exact plan; required to execute when confirmation mode is on');
27
+ export const UpdateEntityInput = z.object({
28
+ entity: z.enum(UPDATE_ENTITY_KINDS),
29
+ applicationId: z.string().optional(),
30
+ applicationName: z.string().optional(),
31
+ target: TargetRef,
32
+ changes: z
33
+ .record(z.string(), z.any())
34
+ .describe('Fields to change; everything not listed keeps its current value. Pass name to rename. Structured fields (values, actions, attributes) replace as a whole: read the entity first and send the entire corrected field.'),
35
+ dryRun: z.boolean().default(false).describe('Preview the resolved entity and the before/after field diff without writing anything'),
36
+ confirm: ConfirmField,
37
+ });
38
+ export const DeleteEntityInput = z.object({
39
+ entity: z.enum(DELETE_ENTITY_KINDS),
40
+ applicationId: z.string().optional(),
41
+ applicationName: z.string().optional(),
42
+ target: TargetRef,
43
+ dryRun: z.boolean().default(false).describe('Preview the resolved entity and what still references it without deleting, always run this first'),
44
+ confirm: ConfirmField,
45
+ });
46
+ export async function ResolveDocument(api, entity, scope, target) {
47
+ const kind = KIND_MAP[entity];
48
+ let id;
49
+ if (IsObjectId(target)) {
50
+ id = target;
51
+ }
52
+ else if (entity === 'link') {
53
+ throw new Error('Links have no name; pass the 24-char hex link id');
54
+ }
55
+ else if (entity === 'application') {
56
+ id = await ResolveApplicationId(api, target);
57
+ }
58
+ else if (entity === 'folder') {
59
+ const folder = await ResolveFolder(api, scope.applicationId, target);
60
+ id = folder.id;
61
+ }
62
+ else if (entity === 'workflow') {
63
+ id = await ResolveWorkflowId(api, target);
64
+ }
65
+ else {
66
+ id = await ResolveOneId(api, kind, scope.applicationId, target);
67
+ }
68
+ const doc = entity === 'page' ? await FetchPage(api, id) : await api.getOne(kind, id);
69
+ if (doc.deleted)
70
+ throw new Error(`The ${entity} "${doc.name ?? id}" is already deleted; ask an administrator to restore it first`);
71
+ await AssertOwnership(api, entity, doc, scope);
72
+ return doc;
73
+ }
74
+ async function FetchPage(api, id) {
75
+ const rows = await api.list('page', { _id: { $oid: id } }, 1);
76
+ if (!rows.length)
77
+ throw new Error(`No active page with id ${id}`);
78
+ return rows[0];
79
+ }
80
+ async function AssertOwnership(api, entity, doc, scope) {
81
+ if (entity === 'application') {
82
+ if (String(doc.id) !== scope.applicationId) {
83
+ throw new Error(`The resolved application "${doc.name}" (${String(doc.id)}) is not the one this call is scoped to; refusing to touch it`);
84
+ }
85
+ if (doc.isProtected) {
86
+ throw new Error(`The application "${doc.name}" is protected and cannot be modified or deleted`);
87
+ }
88
+ return;
89
+ }
90
+ if (entity === 'folder') {
91
+ const root = await AppRootFolder(api, scope.applicationId);
92
+ if (String(doc.id) === root.id) {
93
+ throw new Error(`The folder "${doc.name}" is the application's root folder; it cannot be renamed, moved, or deleted`);
94
+ }
95
+ if (!FolderFullPath(doc).startsWith(root.fullPath)) {
96
+ throw new Error(`The folder "${String(doc.folderPath)}${doc.name}" lives outside this application's folder tree (${root.fullPath}); refusing to touch it`);
97
+ }
98
+ return;
99
+ }
100
+ if (entity === 'link') {
101
+ if (!doc.linkTypeId)
102
+ throw new Error('The link has no link type; refusing to touch it');
103
+ const linkType = await api.getOne('link-type', String(doc.linkTypeId));
104
+ RequireSameApplication('link (via its link type)', linkType, scope.applicationId);
105
+ return;
106
+ }
107
+ if (entity === 'workflow') {
108
+ const candidates = new Set((Array.isArray(doc.usedIn) ? doc.usedIn : []).map(String));
109
+ if (doc.ownerType === 'application' && doc.ownerId)
110
+ candidates.add(String(doc.ownerId));
111
+ if (candidates.has(scope.applicationId))
112
+ return;
113
+ const ownerApp = await ResolveWorkflowOwnerApp(api, doc);
114
+ if (ownerApp) {
115
+ if (ownerApp !== scope.applicationId) {
116
+ throw new Error(`The workflow "${doc.name}" belongs to a different application (${ownerApp}); refusing to touch it from this application's scope`);
117
+ }
118
+ return;
119
+ }
120
+ if (scope.restricted) {
121
+ throw new Error(`The workflow "${doc.name}" is not owned by an allowlisted application (owner: ${doc.ownerType ?? 'unknown'}); a restricted connection cannot modify it`);
122
+ }
123
+ return;
124
+ }
125
+ RequireSameApplication(entity, doc, scope.applicationId);
126
+ }
127
+ function RequireSameApplication(label, doc, applicationId) {
128
+ const owner = doc.applicationId;
129
+ if (owner === undefined || owner === null) {
130
+ throw new Error(`Could not determine which application owns this ${label}; refusing to touch it`);
131
+ }
132
+ if (String(owner) !== applicationId) {
133
+ throw new Error(`The ${label} "${doc.name ?? doc.id}" belongs to a different application (${String(owner)}); refusing to touch it from this application's scope`);
134
+ }
135
+ }
136
+ export function FolderFullPath(doc) {
137
+ return `${String(doc.folderPath ?? '/')}${String(doc.name ?? '')}/`;
138
+ }
139
+ export async function AppRootFolder(api, applicationId) {
140
+ const app = await api.getOne('application', applicationId);
141
+ if (!app.defaultFolderId)
142
+ throw new Error('Could not determine the application root folder');
143
+ const root = await api.getOne('folder', String(app.defaultFolderId));
144
+ return { id: String(root.id), fullPath: FolderFullPath(root) };
145
+ }
146
+ export async function ResolveFolder(api, applicationId, target) {
147
+ if (IsObjectId(target))
148
+ return api.getOne('folder', target);
149
+ const root = await AppRootFolder(api, applicationId);
150
+ if (target.includes('/')) {
151
+ const segments = target.split('/').filter(Boolean);
152
+ if (!segments.length)
153
+ throw new Error('Empty folder path');
154
+ const rootName = root.fullPath.split('/').filter(Boolean).pop() ?? '';
155
+ if (segments.length > 1 && segments[0] === rootName)
156
+ segments.shift();
157
+ if (segments.length === 1 && segments[0] === rootName)
158
+ return api.getOne('folder', root.id);
159
+ const name = segments[segments.length - 1];
160
+ const prefix = segments.slice(0, -1).join('/');
161
+ const folderPath = prefix ? `${root.fullPath}${prefix}/` : root.fullPath;
162
+ const rows = await api.list('folder', { folderPath, name }, 2);
163
+ if (rows.length === 1)
164
+ return rows[0];
165
+ if (rows.length === 0)
166
+ throw new AmbiguityError(`No active folder at "${folderPath}${name}/"`, []);
167
+ throw new AmbiguityError(`Multiple folders at "${folderPath}${name}/"; pass an explicit id`, rows.map(r => ({ id: r.id, name: r.name })));
168
+ }
169
+ const rows = await api.list('folder', { name: target }, 200);
170
+ const inApp = rows.filter(r => FolderFullPath(r).startsWith(root.fullPath) || String(r.id) === root.id);
171
+ if (inApp.length === 1)
172
+ return inApp[0];
173
+ if (inApp.length === 0)
174
+ throw new AmbiguityError(`No active folder named "${target}" in the application`, []);
175
+ throw new AmbiguityError(`Multiple folders named "${target}" in the application; pass the full path (like "${String(inApp[0].folderPath)}${target}") or an explicit id`, inApp.map(r => ({ id: r.id, name: `${String(r.folderPath)}${r.name}` })));
176
+ }
177
+ const OWNER_DOC_KINDS = ['data-type', 'attribute', 'artifact-type', 'link-type', 'page', 'widget'];
178
+ async function ResolveWorkflowOwnerApp(api, doc) {
179
+ const ownerId = doc.ownerId ? String(doc.ownerId) : null;
180
+ if (!ownerId)
181
+ return null;
182
+ const declared = typeof doc.ownerType === 'string' ? doc.ownerType : '';
183
+ if (declared === 'application')
184
+ return ownerId;
185
+ const tries = [];
186
+ if (declared === 'artifact')
187
+ tries.push('artifact', 'artifact-type');
188
+ else if (OWNER_DOC_KINDS.includes(declared))
189
+ tries.push(declared);
190
+ for (const kind of tries) {
191
+ try {
192
+ const owner = await api.getOne(kind, ownerId);
193
+ if (owner?.applicationId)
194
+ return String(owner.applicationId);
195
+ }
196
+ catch {
197
+ continue;
198
+ }
199
+ }
200
+ return null;
201
+ }
202
+ async function ResolveWorkflowId(api, target) {
203
+ const rows = await api.list('workflow', { name: target });
204
+ if (rows.length === 1)
205
+ return rows[0].id;
206
+ if (rows.length === 0)
207
+ throw new AmbiguityError(`No active workflow named "${target}"`, []);
208
+ throw new AmbiguityError(`Multiple workflows named "${target}"; pass an explicit id`, rows.map(r => ({ id: r.id, name: r.name })));
209
+ }
210
+ function SameValue(a, b) {
211
+ return JSON.stringify(a ?? null) === JSON.stringify(b ?? null);
212
+ }
213
+ export async function BuildEntityUpdatePlan(api, input, scope) {
214
+ const allowed = UPDATABLE_FIELDS[input.entity];
215
+ const unknown = Object.keys(input.changes).filter(f => !allowed.includes(f));
216
+ if (unknown.length) {
217
+ throw new Error(`Fields that cannot be changed on a ${input.entity}: ${unknown.join(', ')}. Updatable fields: ${allowed.join(', ')}`);
218
+ }
219
+ if (!Object.keys(input.changes).length)
220
+ throw new Error('changes is empty; pass at least one field to update');
221
+ const doc = await ResolveDocument(api, input.entity, scope, input.target);
222
+ if (input.entity === 'folder' && typeof input.changes.parentFolderId === 'string') {
223
+ const root = await AppRootFolder(api, scope.applicationId);
224
+ const newParent = await api.getOne('folder', input.changes.parentFolderId);
225
+ if (newParent.deleted)
226
+ throw new Error('The new parent folder is deleted; pick an active folder');
227
+ const parentPath = FolderFullPath(newParent);
228
+ if (String(newParent.id) !== root.id && !parentPath.startsWith(root.fullPath)) {
229
+ throw new Error(`The new parent folder "${parentPath}" lives outside this application's folder tree (${root.fullPath}); refusing to move`);
230
+ }
231
+ if (parentPath.startsWith(FolderFullPath(doc))) {
232
+ throw new Error('Cannot move a folder into itself or one of its own subfolders');
233
+ }
234
+ }
235
+ const document = { id: doc.id, ...input.changes };
236
+ const changedFields = Object.entries(input.changes)
237
+ .filter(([field, to]) => !SameValue(doc[field], to))
238
+ .map(([field, to]) => ({ field, from: doc[field] ?? null, to }));
239
+ return { entity: input.entity, kind: KIND_MAP[input.entity], id: doc.id, name: doc.name ?? doc.id, changedFields, document };
240
+ }
241
+ const USAGE_SAMPLE_LIMIT = 5;
242
+ async function CollectUsage(api, entity, id, applicationId) {
243
+ const usage = [];
244
+ const probe = async (label, note, fetch) => {
245
+ try {
246
+ const { count, samples } = await fetch();
247
+ if (count > 0)
248
+ usage.push({ kind: label, count, note, samples: samples.slice(0, USAGE_SAMPLE_LIMIT) });
249
+ }
250
+ catch {
251
+ usage.push({ kind: label, count: -1, note: `could not be determined, check manually before deleting (${note})`, samples: [] });
252
+ }
253
+ };
254
+ if (entity === 'application') {
255
+ const app = { applicationId: { $oid: id } };
256
+ let typeIds = [];
257
+ await probe('artifactType', 'artifact types defined in this application; they disappear with it', async () => {
258
+ const rows = await api.list('artifact-type', app, 200);
259
+ typeIds = rows.map(r => r.id);
260
+ return { count: rows.length, samples: rows.map(r => ({ id: r.id, name: r.name })) };
261
+ });
262
+ await probe('page', 'pages of this application; they stop working', async () => {
263
+ const rows = await api.list('page', app, 200);
264
+ return { count: rows.length, samples: rows.map(r => ({ id: r.id, name: r.name })) };
265
+ });
266
+ if (typeIds.length) {
267
+ await probe('artifact', 'data records living in this application; they become unreachable', async () => {
268
+ const page = await api.listRecords('artifact', { artifactTypeId: { $in: typeIds.map(t => ({ $oid: t })) } }, { limit: 1 });
269
+ return { count: page.meta?.totalCount ?? page.data.length, samples: [] };
270
+ });
271
+ }
272
+ }
273
+ if (entity === 'dataType') {
274
+ await probe('attribute', 'attributes still using this data type; the backend will refuse the delete while they exist', async () => {
275
+ const rows = await api.list('attribute', { applicationId: { $oid: applicationId }, dataTypeId: { $oid: id } }, 200);
276
+ return { count: rows.length, samples: rows.map(r => ({ id: r.id, name: r.name })) };
277
+ });
278
+ }
279
+ if (entity === 'attribute') {
280
+ await probe('artifactType', 'artifact types that still assign this attribute; records lose this field', async () => {
281
+ const rows = await api.list('artifact-type', { applicationId: { $oid: applicationId }, [`attributes.${id}`]: { $exists: true } }, 200);
282
+ return { count: rows.length, samples: rows.map(r => ({ id: r.id, name: r.name })) };
283
+ });
284
+ }
285
+ if (entity === 'artifactType') {
286
+ await probe('artifact', 'records of this type; they become unreachable when the type is deleted', async () => {
287
+ const page = await api.listRecords('artifact', { artifactTypeId: { $oid: id } }, { limit: 1 });
288
+ return { count: page.meta?.totalCount ?? page.data.length, samples: [] };
289
+ });
290
+ await probe('linkType', 'link types restricted to this artifact type; the backend will refuse the delete while they exist', async () => {
291
+ const app = { applicationId: { $oid: applicationId } };
292
+ const source = await api.list('link-type', { ...app, 'restrictions.sourceArtifactTypeId': { $oid: id } }, 200);
293
+ const destination = await api.list('link-type', { ...app, 'restrictions.destinationArtifactTypeId': { $oid: id } }, 200);
294
+ const unique = new Map(source.concat(destination).map(r => [r.id, r]));
295
+ return { count: unique.size, samples: [...unique.values()].map(r => ({ id: r.id, name: r.name })) };
296
+ });
297
+ }
298
+ if (entity === 'linkType') {
299
+ await probe('link', 'links of this type; they stop resolving when the type is deleted', async () => {
300
+ const page = await api.listRecords('link', { linkTypeId: { $oid: id } }, { limit: 1 });
301
+ return { count: page.meta?.totalCount ?? page.data.length, samples: [] };
302
+ });
303
+ }
304
+ if (entity === 'folder') {
305
+ await probe('folder', 'subfolders inside this folder; they go with it', async () => {
306
+ const rows = await api.list('folder', { parentFolderId: { $oid: id } }, 200);
307
+ return { count: rows.length, samples: rows.map(r => ({ id: r.id, name: r.name })) };
308
+ });
309
+ await probe('artifact', 'records stored in this folder or below it', async () => {
310
+ const doc = await api.getOne('folder', id);
311
+ const prefix = FolderFullPath(doc).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
312
+ const page = await api.listRecords('artifact', { 'folderData.path': { $regex: `^${prefix}` } }, { limit: 1 });
313
+ return { count: page.meta?.totalCount ?? page.data.length, samples: [] };
314
+ });
315
+ }
316
+ return usage;
317
+ }
318
+ const UNPROBED_KINDS = {
319
+ workflow: 'no automated usage analysis for workflows, check which pages or triggers rely on it before deleting',
320
+ page: 'no automated usage analysis for pages, check menus and links that navigate to it before deleting',
321
+ link: 'deleting a link only disconnects the two records; the records themselves are untouched',
322
+ };
323
+ export async function BuildEntityDeletePlan(api, input, scope) {
324
+ const doc = await ResolveDocument(api, input.entity, scope, input.target);
325
+ const usage = await CollectUsage(api, input.entity, doc.id, scope.applicationId);
326
+ const plan = {
327
+ entity: input.entity,
328
+ kind: KIND_MAP[input.entity],
329
+ id: doc.id,
330
+ name: doc.name ?? doc.id,
331
+ usage,
332
+ };
333
+ const note = UNPROBED_KINDS[input.entity];
334
+ if (note)
335
+ plan.usageNote = note;
336
+ if (input.entity === 'workflow' && doc.state === 'ACTIVE') {
337
+ plan.disableFirst = true;
338
+ plan.usageNote = `${plan.usageNote}, the workflow is ACTIVE and will be set to DISABLED first, then deleted`;
339
+ }
340
+ if (usage.some(u => u.count !== 0)) {
341
+ plan.warning = 'This entity is still referenced (see usage). Show the user what depends on it and get an explicit go-ahead before deleting.';
342
+ }
343
+ return plan;
344
+ }
345
+ //# sourceMappingURL=entity-lifecycle-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-lifecycle-plan.js","sourceRoot":"","sources":["../../src/builders/entity-lifecycle-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { HttpErrorDetail } from '../http-client.js';
2
+ export async function ExecuteLinksPlan(api, plan) {
3
+ let linkTypeId;
4
+ let linkTypeName;
5
+ let created = false;
6
+ if (plan.linkType.reuse) {
7
+ linkTypeId = plan.linkType.reuse.id;
8
+ linkTypeName = plan.linkType.reuse.name;
9
+ }
10
+ else {
11
+ try {
12
+ const linkType = await api.create('link-type', plan.linkType.createBody);
13
+ linkTypeId = linkType.id;
14
+ linkTypeName = linkType.name;
15
+ created = true;
16
+ }
17
+ catch (e) {
18
+ throw new Error(`build_links failed creating the link type: ${e.message}${HttpErrorDetail(e)}`, { cause: e });
19
+ }
20
+ }
21
+ const toCreate = [];
22
+ const skippedExisting = [];
23
+ for (const link of plan.links) {
24
+ const page = await api.listRecords('link', {
25
+ linkTypeId: { $oid: linkTypeId },
26
+ sourceArtifactId: { $oid: link.sourceId },
27
+ destinationArtifactId: { $oid: link.destinationId },
28
+ }, { limit: 1 });
29
+ if (page.data.length > 0)
30
+ skippedExisting.push({ sourceName: link.sourceName, destinationName: link.destinationName });
31
+ else
32
+ toCreate.push(link);
33
+ }
34
+ if (toCreate.length > 0) {
35
+ try {
36
+ await api.createLinks({
37
+ links: toCreate.map(l => ({ linkTypeId, sourceArtifactId: l.sourceId, destinationArtifactId: l.destinationId })),
38
+ });
39
+ }
40
+ catch (e) {
41
+ throw new Error(`build_links failed creating link instances: ${e.message}${HttpErrorDetail(e)}${created ? `; link type "${linkTypeName}" (${linkTypeId}) was created and kept` : ''}`, { cause: e });
42
+ }
43
+ }
44
+ return {
45
+ linkType: { id: linkTypeId, name: linkTypeName, created },
46
+ createdLinks: toCreate.map(l => ({ sourceName: l.sourceName, destinationName: l.destinationName })),
47
+ skippedExisting,
48
+ };
49
+ }
50
+ //# sourceMappingURL=links-execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links-execute.js","sourceRoot":"","sources":["../../src/builders/links-execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ import { AmbiguityError, ResolveArtifactByRef, ResolveOneId } from '../resolve.js';
3
+ import { Prune } from '../prune.js';
4
+ export const BuildLinksInput = z.object({
5
+ applicationId: z.string().optional(),
6
+ applicationName: z.string().optional(),
7
+ name: z.string().min(1).describe('Link type name; an existing active link type with this name is reused'),
8
+ sourceArtifactType: z.string().optional().describe('Source artifact type name or id; required when the link type does not exist yet'),
9
+ destinationArtifactType: z.string().optional().describe('Destination artifact type name or id; required when the link type does not exist yet'),
10
+ sourceLabel: z.string().optional().describe('Label shown on the source side (defaults to the link type name)'),
11
+ destinationLabel: z.string().optional().describe('Label shown on the destination side (defaults to the link type name)'),
12
+ description: z.string().optional(),
13
+ links: z
14
+ .array(z.object({ source: z.string().min(1), destination: z.string().min(1) }))
15
+ .max(50)
16
+ .default([])
17
+ .describe('Link instances by artifact name or id; source names resolve within the source artifact type, destination names within the destination artifact type'),
18
+ dryRun: z.boolean().default(false),
19
+ confirm: z.string().optional().describe('Confirmation token from the previous preview of this exact plan; required to execute when confirmation mode is on'),
20
+ });
21
+ export async function BuildLinksPlan(api, raw, applicationId) {
22
+ const input = BuildLinksInput.parse(raw);
23
+ const existing = (await api.list('link-type', { applicationId: { $oid: applicationId }, name: input.name }));
24
+ if (existing.length > 1)
25
+ throw new AmbiguityError(`Multiple active link types named "${input.name}"; pass an explicit id`, existing.map(e => ({ id: e.id, name: e.name })));
26
+ let linkType;
27
+ let sourceTypeId;
28
+ let destinationTypeId;
29
+ if (existing.length === 1) {
30
+ linkType = { reuse: { id: existing[0].id, name: existing[0].name } };
31
+ const restriction = existing[0].restrictions?.[0];
32
+ sourceTypeId = restriction?.sourceArtifactTypeId ? String(restriction.sourceArtifactTypeId) : null;
33
+ destinationTypeId = restriction?.destinationArtifactTypeId ? String(restriction.destinationArtifactTypeId) : null;
34
+ }
35
+ else {
36
+ if (!input.sourceArtifactType || !input.destinationArtifactType) {
37
+ throw new Error(`Link type "${input.name}" does not exist; provide sourceArtifactType and destinationArtifactType to create it`);
38
+ }
39
+ sourceTypeId = await ResolveOneId(api, 'artifact-type', applicationId, input.sourceArtifactType);
40
+ destinationTypeId = await ResolveOneId(api, 'artifact-type', applicationId, input.destinationArtifactType);
41
+ linkType = {
42
+ createBody: Prune({
43
+ applicationId,
44
+ name: input.name,
45
+ description: input.description ?? '',
46
+ uri: '',
47
+ source: { cardinality: { min: 0, max: null }, notify: false, name: input.sourceLabel ?? input.name },
48
+ destination: { cardinality: { min: 0, max: null }, notify: false, name: input.destinationLabel ?? input.name },
49
+ restrictions: [{ sourceArtifactTypeId: sourceTypeId, destinationArtifactTypeId: destinationTypeId }],
50
+ }),
51
+ };
52
+ }
53
+ const sys = await api.systemAttributes();
54
+ const links = [];
55
+ for (const pair of input.links) {
56
+ const source = await ResolveArtifactByRef(api, sys.nameAttributeId, sourceTypeId, pair.source, 'source');
57
+ const destination = await ResolveArtifactByRef(api, sys.nameAttributeId, destinationTypeId, pair.destination, 'destination');
58
+ links.push({ sourceId: source.id, sourceName: source.name, destinationId: destination.id, destinationName: destination.name });
59
+ }
60
+ return { linkType, links };
61
+ }
62
+ //# sourceMappingURL=links-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"links-plan.js","sourceRoot":"","sources":["../../src/builders/links-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { HttpErrorDetail } from '../http-client.js';
2
+ export async function ExecutePagePlan(api, plan) {
3
+ const created = [];
4
+ const widgets = [];
5
+ try {
6
+ const ids = [];
7
+ for (const w of plan.widgets) {
8
+ const res = await api.create('widget', { code: w.code, value: w.value });
9
+ created.push(res.id);
10
+ ids.push(res.id);
11
+ widgets.push({ id: res.id, code: w.code });
12
+ }
13
+ const body = ResolveWidgetIndices(plan.pageBody, ids);
14
+ const page = await api.create('page', body);
15
+ return { page: { id: page.id, name: page.name }, widgets };
16
+ }
17
+ catch (e) {
18
+ const orphans = created.length
19
+ ? ` Created widgets are unowned and left for the backend's scheduled orphan cleanup: ${created.join(', ')}.`
20
+ : '';
21
+ throw new Error(`build_page failed: ${e.message}${HttpErrorDetail(e)}.${orphans}`, { cause: e });
22
+ }
23
+ }
24
+ export function ResolveWidgetIndices(value, ids) {
25
+ if (Array.isArray(value))
26
+ return value.map((v) => ResolveWidgetIndices(v, ids));
27
+ if (value !== null && typeof value === 'object') {
28
+ const obj = value;
29
+ if (typeof obj.$widgetIndex === 'number')
30
+ return ids[obj.$widgetIndex];
31
+ const out = {};
32
+ for (const [k, v] of Object.entries(obj))
33
+ out[k] = ResolveWidgetIndices(v, ids);
34
+ return out;
35
+ }
36
+ return value;
37
+ }
38
+ //# sourceMappingURL=page-execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-execute.js","sourceRoot":"","sources":["../../src/builders/page-execute.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOpD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAa,EAAE,IAAc;IACjE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAmC,EAAE,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAa,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAiB,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACzF,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACrB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAA4B,CAAC;QACjF,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,MAAM,CAA+B,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1E,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC;IAC7D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM;YAC5B,CAAC,CAAC,qFAAqF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YAC5G,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,sBAAuB,CAAW,CAAC,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9G,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAc,EAAE,GAAa;IAChE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAChF,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,GAAG,GAAG,KAAgC,CAAC;QAC7C,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ;YAAE,OAAO,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACvE,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,oBAAoB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAChF,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}