@fractal_cloud/sdk 1.5.2 → 2.0.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.
@@ -0,0 +1,1248 @@
1
+ import superagent from "superagent";
2
+
3
+ //#region src/model/core.ts
4
+ /** Build an offer constructor (pure). Default instantiate merges neutral params + vendor config. */
5
+ const defineOffer = (spec) => (config) => ({
6
+ satisfies: spec.satisfies,
7
+ offerType: spec.offerType,
8
+ provider: spec.provider,
9
+ deliveryModel: spec.deliveryModel,
10
+ config,
11
+ instantiate: (ctx) => spec.instantiate ? spec.instantiate(ctx, config) : [{
12
+ id: ctx.id,
13
+ type: spec.offerType,
14
+ provider: spec.provider,
15
+ deliveryModel: spec.deliveryModel,
16
+ parameters: {
17
+ ...ctx.parameters,
18
+ ...config
19
+ },
20
+ dependencies: ctx.dependencies,
21
+ links: ctx.links
22
+ }]
23
+ });
24
+ /** Authoring primitive: create a fresh node for a Component factory. */
25
+ const newNode = (id, component) => ({
26
+ id,
27
+ component,
28
+ parameters: {},
29
+ locked: /* @__PURE__ */ new Set(),
30
+ dependencies: []
31
+ });
32
+ /** Authoring primitive: set a neutral param AND lock it (guardrail, design time). */
33
+ const guardrail = (s, key, value) => ({
34
+ ...s,
35
+ parameters: {
36
+ ...s.parameters,
37
+ [key]: value
38
+ },
39
+ locked: new Set([...s.locked, key])
40
+ });
41
+ /** Authoring primitive: declare a structural dependency on another node. */
42
+ const addDependency = (s, depId) => ({
43
+ ...s,
44
+ dependencies: [...s.dependencies, depId]
45
+ });
46
+ /** Collect the links a component is the source of, in wire shape. */
47
+ const linksFor = (st, sourceId) => st.links.filter((l) => l.sourceId === sourceId).map((l) => ({
48
+ componentId: l.targetId,
49
+ settings: l.settings
50
+ }));
51
+ const ensureUnlocked = (node, key) => {
52
+ if (node.locked.has(key)) throw new Error(`Parameter '${key}' on '${node.id}' is a locked guardrail and cannot be changed.`);
53
+ };
54
+ const setOpen = (st, id, key, value) => {
55
+ const node = st.nodes[id];
56
+ ensureUnlocked(node, key);
57
+ return {
58
+ ...st,
59
+ nodes: {
60
+ ...st.nodes,
61
+ [id]: {
62
+ ...node,
63
+ parameters: {
64
+ ...node.parameters,
65
+ [key]: value
66
+ }
67
+ }
68
+ }
69
+ };
70
+ };
71
+ const appendOpen = (st, id, key, value) => {
72
+ const node = st.nodes[id];
73
+ ensureUnlocked(node, key);
74
+ const prev = node.parameters[key] ?? [];
75
+ return {
76
+ ...st,
77
+ nodes: {
78
+ ...st.nodes,
79
+ [id]: {
80
+ ...node,
81
+ parameters: {
82
+ ...node.parameters,
83
+ [key]: [...prev, value]
84
+ }
85
+ }
86
+ }
87
+ };
88
+ };
89
+ const addChild = (st, parentId, child) => ({
90
+ ...st,
91
+ children: {
92
+ ...st.children,
93
+ [parentId]: [...st.children[parentId] ?? [], child]
94
+ }
95
+ });
96
+ const slotOps = (id) => ({
97
+ set: (k, v) => (st) => setOpen(st, id, k, v),
98
+ append: (k, v) => (st) => appendOpen(st, id, k, v),
99
+ addChild: (child) => (st) => addChild(st, id, child.state)
100
+ });
101
+ /** Collect a parent's child components in instantiation-context shape. */
102
+ const childrenFor = (st, parentId) => (st.children[parentId] ?? []).map((c) => ({
103
+ id: c.id,
104
+ parameters: { ...c.parameters },
105
+ dependencies: [...c.dependencies, parentId],
106
+ links: linksFor(st, c.id)
107
+ }));
108
+ const serialize = (st) => ({
109
+ fractalId: st.fractalId,
110
+ components: st.order.map((id) => {
111
+ const n = st.nodes[id];
112
+ return {
113
+ id,
114
+ component: n.component,
115
+ parameters: { ...n.parameters },
116
+ locked: [...n.locked],
117
+ dependencies: [...n.dependencies],
118
+ links: linksFor(st, id)
119
+ };
120
+ })
121
+ });
122
+ const toLiveSystem = (st, args) => {
123
+ const validIds = new Set(st.order);
124
+ for (const key of Object.keys(args.select)) if (!validIds.has(key)) throw new Error(`Selection key '${key}' does not match any component in the fractal. Valid components: ${st.order.join(", ")}.`);
125
+ const components = [];
126
+ for (const id of st.order) {
127
+ const node = st.nodes[id];
128
+ const offer = args.select[id];
129
+ if (!offer) throw new Error(`Missing offer selection for component '${id}'.`);
130
+ if (offer.satisfies !== node.component) throw new Error(`Offer '${offer.offerType}' does not satisfy component '${node.component}' (selected for '${id}').`);
131
+ const children = childrenFor(st, id);
132
+ const emitted = offer.instantiate({
133
+ id,
134
+ parameters: { ...node.parameters },
135
+ dependencies: node.dependencies,
136
+ links: linksFor(st, id),
137
+ children
138
+ });
139
+ if (children.length > 0) {
140
+ const emittedIds = new Set(emitted.map((c) => c.id));
141
+ const dropped = children.filter((c) => !emittedIds.has(c.id));
142
+ if (dropped.length > 0) throw new Error(`Offer '${offer.offerType}' selected for '${id}' does not emit its child component(s) [${dropped.map((c) => c.id).join(", ")}]. The selected offer must support child components (e.g. databases added via an operation).`);
143
+ }
144
+ components.push(...emitted);
145
+ }
146
+ return {
147
+ name: args.name,
148
+ fractalId: st.fractalId,
149
+ fractalName: st.fractalName,
150
+ version: st.version,
151
+ boundedContext: st.boundedContext,
152
+ environment: args.environment,
153
+ components
154
+ };
155
+ };
156
+ const fluent = (ops, st) => {
157
+ const api = {
158
+ value: st,
159
+ blueprint: serialize(st),
160
+ toLiveSystem: (args) => toLiveSystem(st, args)
161
+ };
162
+ for (const k of Object.keys(ops)) api[k] = (...args) => fluent(ops, ops[k](...args)(st));
163
+ return api;
164
+ };
165
+ function createFractal(def) {
166
+ const order = [];
167
+ const linkRecords = [];
168
+ const slots = def.blueprint({
169
+ add: (n) => {
170
+ order.push(n.state.id);
171
+ return n;
172
+ },
173
+ link: (source, target, settings = {}) => {
174
+ linkRecords.push({
175
+ sourceId: source.state.id,
176
+ targetId: target.state.id,
177
+ settings
178
+ });
179
+ }
180
+ });
181
+ const nodes = {};
182
+ const slotToId = {};
183
+ for (const key of Object.keys(slots)) {
184
+ const node = slots[key];
185
+ nodes[node.state.id] = node.state;
186
+ slotToId[key] = node.state.id;
187
+ }
188
+ const fractalId = `${def.id}:${def.version.major}.${def.version.minor}.${def.version.patch}`;
189
+ const state = {
190
+ fractalId,
191
+ fractalName: def.id,
192
+ version: def.version,
193
+ boundedContext: def.boundedContextId,
194
+ nodes,
195
+ order,
196
+ links: linkRecords,
197
+ children: {}
198
+ };
199
+ const slotOpsMap = {};
200
+ for (const key of Object.keys(slotToId)) slotOpsMap[key] = slotOps(slotToId[key]);
201
+ const ops = def.operations ? def.operations(slotOpsMap) : {};
202
+ return {
203
+ fractalId,
204
+ blueprint: serialize(state),
205
+ ops,
206
+ specialize: () => fluent(ops, state),
207
+ toLiveSystem: (args) => toLiveSystem(state, args)
208
+ };
209
+ }
210
+
211
+ //#endregion
212
+ //#region src/model/service.ts
213
+ /**
214
+ * service.ts — deploy a model LiveSystem to the Fractal Cloud API.
215
+ *
216
+ * Self-contained (the interim SDK service is unproven and not reused). Builds the
217
+ * API payload from the model LiveSystem, submits (create or update), and — in
218
+ * `wait` mode — polls to Active, emitting the canonical SDK wait-mode log lines
219
+ * (see ~/Projects/CLAUDE.md "SDK — Wait Mode Log Format").
220
+ *
221
+ * NOTE: not runtime-verified here (no Fractal Cloud credentials) — covered by
222
+ * mocked-HTTP unit tests in service.test.ts; smoke against the live API with real
223
+ * credentials before release.
224
+ */
225
+ const FRACTAL_API_URL = "https://api.fractal.cloud";
226
+ const CLIENT_ID_HEADER = "X-ClientID";
227
+ const CLIENT_SECRET_HEADER = "X-ClientSecret";
228
+ const DEFAULT_POLL_INTERVAL_MS = 5e3;
229
+ const DEFAULT_TIMEOUT_MS = 6e5;
230
+ const TERMINAL_FAILURE_STATUSES = ["FailedMutation", "Error"];
231
+ const bcString = (bc) => `${bc.ownerType ?? "Personal"}/${bc.ownerId ?? ""}/${bc.name ?? ""}`;
232
+ const liveSystemId = (ls) => `${bcString(ls.boundedContext)}/${ls.name}`;
233
+ const fractalApiId = (ls) => `${bcString(ls.boundedContext)}/${ls.fractalName}:${ls.version.major}.${ls.version.minor}.${ls.version.patch}`;
234
+ const buildBody = (ls) => ({
235
+ liveSystemId: liveSystemId(ls),
236
+ fractalId: fractalApiId(ls),
237
+ blueprintMap: ls.components.reduce((acc, c) => {
238
+ acc[c.id] = {
239
+ type: c.type,
240
+ id: c.id,
241
+ provider: c.provider,
242
+ deliveryModel: c.deliveryModel,
243
+ parameters: c.parameters,
244
+ dependencies: [...c.dependencies],
245
+ links: c.links.map((l) => ({
246
+ componentId: l.componentId,
247
+ settings: l.settings
248
+ }))
249
+ };
250
+ return acc;
251
+ }, {}),
252
+ environment: {
253
+ id: {
254
+ type: ls.environment.ownerType ?? "Personal",
255
+ ownerId: ls.environment.ownerId ?? "",
256
+ shortName: ls.environment.name ?? ""
257
+ },
258
+ parameters: {}
259
+ }
260
+ });
261
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
262
+ const authHeaders = (c) => ({
263
+ [CLIENT_ID_HEADER]: c.clientId,
264
+ [CLIENT_SECRET_HEADER]: c.clientSecret
265
+ });
266
+ const log = (quiet, level, message, fields = {}) => {
267
+ if (quiet) return;
268
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
269
+ const fieldStr = Object.entries(fields).map(([k, v]) => `${k}=${v}`).join(" ");
270
+ console.log(`[${ts}] ${level.padEnd(5)} ${message}${fieldStr ? " " + fieldStr : ""}`);
271
+ };
272
+ const elapsedSec = (startMs) => `${Math.round((Date.now() - startMs) / 1e3)}s`;
273
+ const submit = async (ls, creds) => {
274
+ const url = `${FRACTAL_API_URL}/livesystems/${liveSystemId(ls)}`;
275
+ const existing = await superagent.get(url).ok((res) => res.status === 200 || res.status === 404).set(authHeaders(creds));
276
+ const body = buildBody(ls);
277
+ if (existing.status === 200) await superagent.put(url).set(authHeaders(creds)).send(body);
278
+ else await superagent.post(`${FRACTAL_API_URL}/livesystems`).set(authHeaders(creds)).send(body);
279
+ };
280
+ const getStatus = async (id, creds) => {
281
+ return (await superagent.get(`${FRACTAL_API_URL}/livesystems/${id}`).set(authHeaders(creds))).body.status;
282
+ };
283
+ const pollUntilActive = async (ls, creds, opts, startMs) => {
284
+ const quiet = opts.quiet ?? false;
285
+ const interval = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
286
+ const deadline = Date.now() + (opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
287
+ const id = liveSystemId(ls);
288
+ let round = 0;
289
+ while (Date.now() < deadline) {
290
+ await sleep(interval);
291
+ round++;
292
+ let status;
293
+ try {
294
+ status = await getStatus(id, creds);
295
+ } catch (err) {
296
+ const code = err.status;
297
+ if (code !== void 0 && code >= 400 && code < 500) {
298
+ log(quiet, "ERROR", "Fatal error polling Live System status", {
299
+ system: id,
300
+ round,
301
+ elapsed: elapsedSec(startMs)
302
+ });
303
+ throw err;
304
+ }
305
+ log(quiet, "WARN", "Transient error polling status, retrying", {
306
+ system: id,
307
+ round,
308
+ elapsed: elapsedSec(startMs)
309
+ });
310
+ continue;
311
+ }
312
+ if (status === "Active") return;
313
+ if (TERMINAL_FAILURE_STATUSES.includes(status)) {
314
+ log(quiet, "ERROR", "Live System deployment failed", {
315
+ system: id,
316
+ status,
317
+ elapsed: elapsedSec(startMs)
318
+ });
319
+ throw new Error(`Live system deployment failed with status: ${status}`);
320
+ }
321
+ log(quiet, "CHECK", "Polling Live System status", {
322
+ system: id,
323
+ round,
324
+ status,
325
+ elapsed: elapsedSec(startMs)
326
+ });
327
+ }
328
+ log(quiet, "ERROR", "Live System deployment timed out", {
329
+ system: id,
330
+ elapsed: elapsedSec(startMs),
331
+ timeoutMs: opts.timeoutMs ?? DEFAULT_TIMEOUT_MS
332
+ });
333
+ throw new Error("Live system deployment timed out");
334
+ };
335
+ /** Deploy (create or update) a LiveSystem. `fire-and-forget` submits and returns;
336
+ * `wait` polls until Active (or failure/timeout) emitting wait-mode log lines. */
337
+ async function deploy(ls, creds, opts = { mode: "fire-and-forget" }) {
338
+ if (opts.mode === "fire-and-forget") {
339
+ await submit(ls, creds);
340
+ return;
341
+ }
342
+ const quiet = opts.quiet ?? false;
343
+ const startMs = Date.now();
344
+ log(quiet, "INFO", "Deploying Live System", {
345
+ system: liveSystemId(ls),
346
+ fractal: fractalApiId(ls)
347
+ });
348
+ await submit(ls, creds);
349
+ await pollUntilActive(ls, creds, opts, startMs);
350
+ log(quiet, "INFO", "Live System Active", {
351
+ system: liveSystemId(ls),
352
+ elapsed: elapsedSec(startMs)
353
+ });
354
+ }
355
+ /** Destroy a deployed LiveSystem. */
356
+ async function destroy(ls, creds) {
357
+ await superagent.delete(`${FRACTAL_API_URL}/livesystems/${liveSystemId(ls)}`).set(authHeaders(creds));
358
+ }
359
+
360
+ //#endregion
361
+ //#region src/model/components/network_and_compute.ts
362
+ /**
363
+ * components/network_and_compute.ts — NetworkAndCompute Component factories.
364
+ *
365
+ * Each agnostic blueprint parameter is a typed `.withXxx()` guardrail setter
366
+ * (locked at design time). Components that can sit under another expose
367
+ * `dependsOn(other)` to declare a structural dependency. Vendor knobs do NOT
368
+ * live here — they belong on Offers (see offers/network_and_compute.ts).
369
+ */
370
+ const virtualNetworkNode = (s) => ({
371
+ state: s,
372
+ withCidrBlock: (v) => virtualNetworkNode(guardrail(s, "cidrBlock", v)),
373
+ withRegion: (v) => virtualNetworkNode(guardrail(s, "region", v)),
374
+ withTags: (v) => virtualNetworkNode(guardrail(s, "tags", v))
375
+ });
376
+ const VirtualNetwork = (cfg) => virtualNetworkNode(newNode(cfg.id, "NetworkAndCompute.VirtualNetwork"));
377
+ const subnetNode = (s) => ({
378
+ state: s,
379
+ withCidrBlock: (v) => subnetNode(guardrail(s, "cidrBlock", v)),
380
+ dependsOn: (other) => subnetNode(addDependency(s, other.state.id))
381
+ });
382
+ const Subnet = (cfg) => subnetNode(newNode(cfg.id, "NetworkAndCompute.Subnet"));
383
+ const securityGroupNode = (s) => ({
384
+ state: s,
385
+ withIngressRules: (v) => securityGroupNode(guardrail(s, "ingressRules", v)),
386
+ withEgressRules: (v) => securityGroupNode(guardrail(s, "egressRules", v)),
387
+ dependsOn: (other) => securityGroupNode(addDependency(s, other.state.id))
388
+ });
389
+ const SecurityGroup = (cfg) => securityGroupNode(newNode(cfg.id, "NetworkAndCompute.SecurityGroup"));
390
+ const virtualMachineNode = (s) => ({
391
+ state: s,
392
+ withOsType: (v) => virtualMachineNode(guardrail(s, "osType", v)),
393
+ withSize: (v) => virtualMachineNode(guardrail(s, "size", v)),
394
+ withTags: (v) => virtualMachineNode(guardrail(s, "tags", v)),
395
+ dependsOn: (other) => virtualMachineNode(addDependency(s, other.state.id))
396
+ });
397
+ const VirtualMachine = (cfg) => virtualMachineNode(newNode(cfg.id, "NetworkAndCompute.VirtualMachine"));
398
+ const containerPlatformNode = (s) => ({
399
+ state: s,
400
+ withNodePools: (v) => containerPlatformNode(guardrail(s, "nodePools", v)),
401
+ withKubernetesVersion: (v) => containerPlatformNode(guardrail(s, "kubernetesVersion", v)),
402
+ withNetworkPolicyProvider: (v) => containerPlatformNode(guardrail(s, "networkPolicyProvider", v)),
403
+ dependsOn: (other) => containerPlatformNode(addDependency(s, other.state.id))
404
+ });
405
+ const ContainerPlatform = (cfg) => containerPlatformNode(newNode(cfg.id, "NetworkAndCompute.ContainerPlatform"));
406
+ const loadBalancerNode = (s) => ({
407
+ state: s,
408
+ withScheme: (v) => loadBalancerNode(guardrail(s, "scheme", v)),
409
+ dependsOn: (other) => loadBalancerNode(addDependency(s, other.state.id))
410
+ });
411
+ const LoadBalancer = (cfg) => loadBalancerNode(newNode(cfg.id, "NetworkAndCompute.LoadBalancer"));
412
+
413
+ //#endregion
414
+ //#region src/model/components/storage.ts
415
+ /**
416
+ * components/storage.ts — Storage domain Component factories (Level 1).
417
+ *
418
+ * Abstract, vendor-agnostic capability contracts:
419
+ * - Storage.ObjectStorage
420
+ * - Storage.RelationalDbms
421
+ * - Storage.RelationalDatabase
422
+ *
423
+ * Each agnostic parameter is a typed `.withXxx()` guardrail setter (locks the
424
+ * key at design time). Built exclusively on the LOCKED engine in ../core.
425
+ */
426
+ const objectStorageNode = (s) => ({
427
+ state: s,
428
+ withVersioningEnabled: (v) => objectStorageNode(guardrail(s, "versioningEnabled", v)),
429
+ withStorageClass: (v) => objectStorageNode(guardrail(s, "storageClass", v)),
430
+ withPublicAccess: (v) => objectStorageNode(guardrail(s, "publicAccess", v)),
431
+ withEncryption: (v) => objectStorageNode(guardrail(s, "encryption", v)),
432
+ withRetentionDays: (v) => objectStorageNode(guardrail(s, "retentionDays", v)),
433
+ withTags: (v) => objectStorageNode(guardrail(s, "tags", v))
434
+ });
435
+ const ObjectStorage = (cfg) => objectStorageNode(newNode(cfg.id, "Storage.ObjectStorage"));
436
+ const relationalDbmsNode = (s) => ({
437
+ state: s,
438
+ withEngineVersion: (v) => relationalDbmsNode(guardrail(s, "engineVersion", v)),
439
+ withSizeTier: (v) => relationalDbmsNode(guardrail(s, "sizeTier", v)),
440
+ withStorageGb: (v) => relationalDbmsNode(guardrail(s, "storageGb", v)),
441
+ withBackupRetentionDays: (v) => relationalDbmsNode(guardrail(s, "backupRetentionDays", v)),
442
+ withHighAvailability: (v) => relationalDbmsNode(guardrail(s, "highAvailability", v))
443
+ });
444
+ const RelationalDbms = (cfg) => relationalDbmsNode(newNode(cfg.id, "Storage.RelationalDbms"));
445
+ const relationalDatabaseNode = (s) => ({
446
+ state: s,
447
+ withCharset: (v) => relationalDatabaseNode(guardrail(s, "charset", v)),
448
+ withCollation: (v) => relationalDatabaseNode(guardrail(s, "collation", v)),
449
+ dependsOn: (other) => relationalDatabaseNode(addDependency(s, other.state.id))
450
+ });
451
+ const RelationalDatabase = (cfg) => relationalDatabaseNode(newNode(cfg.id, "Storage.RelationalDatabase"));
452
+
453
+ //#endregion
454
+ //#region src/model/components/big_data.ts
455
+ /**
456
+ * components/big_data.ts — BigData domain Component factories (Level 1, abstract).
457
+ *
458
+ * Each agnostic param is a typed `.withXxx()` guardrail setter (locked at design
459
+ * time via `guardrail`). Structural relationships are declared with `dependsOn`
460
+ * (via `addDependency`). Vendor knobs never appear here — they live on Offers.
461
+ */
462
+ const computeClusterNode = (s) => ({
463
+ state: s,
464
+ withClusterName: (v) => computeClusterNode(guardrail(s, "clusterName", v)),
465
+ withSparkVersion: (v) => computeClusterNode(guardrail(s, "sparkVersion", v)),
466
+ withMinWorkers: (v) => computeClusterNode(guardrail(s, "minWorkers", v)),
467
+ withMaxWorkers: (v) => computeClusterNode(guardrail(s, "maxWorkers", v)),
468
+ withAutoTerminationMinutes: (v) => computeClusterNode(guardrail(s, "autoTerminationMinutes", v)),
469
+ withDataSecurityMode: (v) => computeClusterNode(guardrail(s, "dataSecurityMode", v))
470
+ });
471
+ const ComputeCluster = (cfg) => computeClusterNode(newNode(cfg.id, "BigData.ComputeCluster"));
472
+ const dataProcessingJobNode = (s) => ({
473
+ state: s,
474
+ withJobName: (v) => dataProcessingJobNode(guardrail(s, "jobName", v)),
475
+ withTaskType: (v) => dataProcessingJobNode(guardrail(s, "taskType", v)),
476
+ withCronSchedule: (v) => dataProcessingJobNode(guardrail(s, "cronSchedule", v)),
477
+ withMaxRetries: (v) => dataProcessingJobNode(guardrail(s, "maxRetries", v)),
478
+ dependsOn: (other) => dataProcessingJobNode(addDependency(s, other.state.id))
479
+ });
480
+ const DataProcessingJob = (cfg) => dataProcessingJobNode(newNode(cfg.id, "BigData.DataProcessingJob"));
481
+ const mlExperimentNode = (s) => ({
482
+ state: s,
483
+ withExperimentName: (v) => mlExperimentNode(guardrail(s, "experimentName", v))
484
+ });
485
+ const MlExperiment = (cfg) => mlExperimentNode(newNode(cfg.id, "BigData.MlExperiment"));
486
+ const datalakeNode = (s) => ({
487
+ state: s,
488
+ withRegion: (v) => datalakeNode(guardrail(s, "region", v)),
489
+ withVersioningEnabled: (v) => datalakeNode(guardrail(s, "versioningEnabled", v)),
490
+ withRetentionDays: (v) => datalakeNode(guardrail(s, "retentionDays", v))
491
+ });
492
+ const Datalake = (cfg) => datalakeNode(newNode(cfg.id, "BigData.Datalake"));
493
+ const distributedDataProcessingNode = (s) => ({
494
+ state: s,
495
+ withWorkspaceName: (v) => distributedDataProcessingNode(guardrail(s, "workspaceName", v))
496
+ });
497
+ const DistributedDataProcessing = (cfg) => distributedDataProcessingNode(newNode(cfg.id, "BigData.DistributedDataProcessing"));
498
+
499
+ //#endregion
500
+ //#region src/model/components/messaging.ts
501
+ /**
502
+ * components/messaging.ts — Messaging domain Component factories (Level 1).
503
+ *
504
+ * Abstract, vendor-agnostic Components for the locked Fractal model. Agnostic
505
+ * `.withXxx()` setters are GUARDRAILS (locked at design time) via guardrail().
506
+ * Offers that satisfy these Components live in offers/messaging.ts.
507
+ */
508
+ const brokerNode = (s) => ({
509
+ state: s,
510
+ withTier: (v) => brokerNode(guardrail(s, "tier", v)),
511
+ withRegion: (v) => brokerNode(guardrail(s, "region", v)),
512
+ withEncryption: (v) => brokerNode(guardrail(s, "encryption", v))
513
+ });
514
+ const Broker = (cfg) => brokerNode(newNode(cfg.id, "Messaging.Broker"));
515
+ const messagingEntityNode = (s) => ({
516
+ state: s,
517
+ withMessageRetentionHours: (v) => messagingEntityNode(guardrail(s, "messageRetentionHours", v)),
518
+ withPartitionCount: (v) => messagingEntityNode(guardrail(s, "partitionCount", v)),
519
+ withDeadLetterEnabled: (v) => messagingEntityNode(guardrail(s, "deadLetterEnabled", v)),
520
+ withMaxDeliveryAttempts: (v) => messagingEntityNode(guardrail(s, "maxDeliveryAttempts", v)),
521
+ dependsOn: (other) => messagingEntityNode(addDependency(s, other.state.id))
522
+ });
523
+ const MessagingEntity = (cfg) => messagingEntityNode(newNode(cfg.id, "Messaging.MessagingEntity"));
524
+
525
+ //#endregion
526
+ //#region src/model/components/api_management.ts
527
+ /**
528
+ * components/api_management.ts — APIManagement Component factories.
529
+ *
530
+ * Each agnostic blueprint parameter is a typed `.withXxx()` guardrail setter
531
+ * (locked at design time). Vendor knobs do NOT live here — they belong on
532
+ * Offers (see offers/api_management.ts).
533
+ */
534
+ const apiGatewayNode = (s) => ({
535
+ state: s,
536
+ withHttpsOnly: (v) => apiGatewayNode(guardrail(s, "httpsOnly", v)),
537
+ withCustomDomain: (v) => apiGatewayNode(guardrail(s, "customDomain", v)),
538
+ withCors: (v) => apiGatewayNode(guardrail(s, "cors", v)),
539
+ withRateLimit: (v) => apiGatewayNode(guardrail(s, "rateLimit", v)),
540
+ withRoutes: (v) => apiGatewayNode(guardrail(s, "routes", v))
541
+ });
542
+ const ApiGateway = (cfg) => apiGatewayNode(newNode(cfg.id, "APIManagement.ApiGateway"));
543
+
544
+ //#endregion
545
+ //#region src/model/components/observability.ts
546
+ /**
547
+ * components/observability.ts — Observability domain Component factories (Level 1).
548
+ *
549
+ * Abstract, vendor-agnostic capability contracts:
550
+ * - Observability.Monitoring
551
+ * - Observability.Tracing
552
+ * - Observability.Logging
553
+ *
554
+ * Each agnostic parameter is a typed `.withXxx()` guardrail setter (locks the
555
+ * key at design time). Built exclusively on the LOCKED engine in ../core.
556
+ */
557
+ const monitoringNode = (s) => ({
558
+ state: s,
559
+ withRetentionDays: (v) => monitoringNode(guardrail(s, "retentionDays", v)),
560
+ withScrapeInterval: (v) => monitoringNode(guardrail(s, "scrapeInterval", v))
561
+ });
562
+ const Monitoring = (cfg) => monitoringNode(newNode(cfg.id, "Observability.Monitoring"));
563
+ const tracingNode = (s) => ({
564
+ state: s,
565
+ withRetentionDays: (v) => tracingNode(guardrail(s, "retentionDays", v)),
566
+ withSamplingRate: (v) => tracingNode(guardrail(s, "samplingRate", v))
567
+ });
568
+ const Tracing = (cfg) => tracingNode(newNode(cfg.id, "Observability.Tracing"));
569
+ const loggingNode = (s) => ({
570
+ state: s,
571
+ withRetentionDays: (v) => loggingNode(guardrail(s, "retentionDays", v))
572
+ });
573
+ const Logging = (cfg) => loggingNode(newNode(cfg.id, "Observability.Logging"));
574
+
575
+ //#endregion
576
+ //#region src/model/components/security.ts
577
+ /**
578
+ * components/security.ts — Security domain Component factories (Level 1).
579
+ *
580
+ * Abstract, vendor-agnostic capability contracts:
581
+ * - Security.ServiceMesh
582
+ * - Security.IdentityProvider
583
+ *
584
+ * Each agnostic parameter is a typed `.withXxx()` guardrail setter (locks the
585
+ * key at design time). Built exclusively on the LOCKED engine in ../core.
586
+ */
587
+ const serviceMeshNode = (s) => ({
588
+ state: s,
589
+ withMtlsMode: (v) => serviceMeshNode(guardrail(s, "mtlsMode", v)),
590
+ withAuthenticationMode: (v) => serviceMeshNode(guardrail(s, "authenticationMode", v)),
591
+ withTags: (v) => serviceMeshNode(guardrail(s, "tags", v))
592
+ });
593
+ const ServiceMesh = (cfg) => serviceMeshNode(newNode(cfg.id, "Security.ServiceMesh"));
594
+ const identityProviderNode = (s) => ({
595
+ state: s,
596
+ withUserDirectoryName: (v) => identityProviderNode(guardrail(s, "userDirectoryName", v)),
597
+ withPasswordPolicy: (v) => identityProviderNode(guardrail(s, "passwordPolicy", v)),
598
+ withMfaConfiguration: (v) => identityProviderNode(guardrail(s, "mfaConfiguration", v)),
599
+ withSessionDuration: (v) => identityProviderNode(guardrail(s, "sessionDuration", v)),
600
+ withTags: (v) => identityProviderNode(guardrail(s, "tags", v))
601
+ });
602
+ const IdentityProvider = (cfg) => identityProviderNode(newNode(cfg.id, "Security.IdentityProvider"));
603
+
604
+ //#endregion
605
+ //#region src/model/components/custom_workloads.ts
606
+ /**
607
+ * components/custom_workloads.ts — CustomWorkloads domain Component factories
608
+ * (Level 1, abstract).
609
+ *
610
+ * Each agnostic param is a typed `.withXxx()` guardrail setter (locked at design
611
+ * time via `guardrail`). Vendor knobs never appear here — they live on Offers.
612
+ */
613
+ const workloadNode = (s) => ({
614
+ state: s,
615
+ withImage: (v) => workloadNode(guardrail(s, "image", v)),
616
+ withPort: (v) => workloadNode(guardrail(s, "port", v)),
617
+ withReplicas: (v) => workloadNode(guardrail(s, "replicas", v)),
618
+ withEnv: (v) => workloadNode(guardrail(s, "env", v)),
619
+ withCpuRequest: (v) => workloadNode(guardrail(s, "cpuRequest", v)),
620
+ withMemoryRequest: (v) => workloadNode(guardrail(s, "memoryRequest", v)),
621
+ withMaxReplicas: (v) => workloadNode(guardrail(s, "maxReplicas", v)),
622
+ withHealthCheck: (v) => workloadNode(guardrail(s, "healthCheck", v))
623
+ });
624
+ const Workload = (cfg) => workloadNode(newNode(cfg.id, "CustomWorkloads.Workload"));
625
+ const functionNode = (s) => ({
626
+ state: s,
627
+ withSourceArtifact: (v) => functionNode(guardrail(s, "sourceArtifact", v)),
628
+ withRuntime: (v) => functionNode(guardrail(s, "runtime", v)),
629
+ withEnvironment: (v) => functionNode(guardrail(s, "environment", v)),
630
+ withMemory: (v) => functionNode(guardrail(s, "memory", v)),
631
+ withTimeout: (v) => functionNode(guardrail(s, "timeout", v)),
632
+ withConcurrency: (v) => functionNode(guardrail(s, "concurrency", v))
633
+ });
634
+ const Function = (cfg) => functionNode(newNode(cfg.id, "CustomWorkloads.Function"));
635
+
636
+ //#endregion
637
+ //#region src/model/offers/network_and_compute.ts
638
+ /**
639
+ * offers/network_and_compute.ts — NetworkAndCompute Offer catalogue (Level 3).
640
+ *
641
+ * Each offer declares which abstract Component it satisfies, its 3-part offer
642
+ * type, its vendor (provider) and delivery model, and carries vendor knobs in
643
+ * its config type. Offers with no extra vendor knobs use config type `{}`.
644
+ */
645
+ const AwsVpc = defineOffer({
646
+ satisfies: "NetworkAndCompute.VirtualNetwork",
647
+ offerType: "NetworkAndCompute.IaaS.AwsVpc",
648
+ provider: "AWS",
649
+ deliveryModel: "IaaS"
650
+ });
651
+ const AzureVnet = defineOffer({
652
+ satisfies: "NetworkAndCompute.VirtualNetwork",
653
+ offerType: "NetworkAndCompute.IaaS.AzureVnet",
654
+ provider: "Azure",
655
+ deliveryModel: "IaaS"
656
+ });
657
+ const GcpVpc = defineOffer({
658
+ satisfies: "NetworkAndCompute.VirtualNetwork",
659
+ offerType: "NetworkAndCompute.IaaS.GcpVpc",
660
+ provider: "GCP",
661
+ deliveryModel: "IaaS"
662
+ });
663
+ const AwsSubnet = defineOffer({
664
+ satisfies: "NetworkAndCompute.Subnet",
665
+ offerType: "NetworkAndCompute.IaaS.AwsSubnet",
666
+ provider: "AWS",
667
+ deliveryModel: "IaaS"
668
+ });
669
+ const AzureSubnet = defineOffer({
670
+ satisfies: "NetworkAndCompute.Subnet",
671
+ offerType: "NetworkAndCompute.IaaS.AzureSubnet",
672
+ provider: "Azure",
673
+ deliveryModel: "IaaS"
674
+ });
675
+ const GcpSubnet = defineOffer({
676
+ satisfies: "NetworkAndCompute.Subnet",
677
+ offerType: "NetworkAndCompute.IaaS.GcpSubnet",
678
+ provider: "GCP",
679
+ deliveryModel: "IaaS"
680
+ });
681
+ const AwsSecurityGroup = defineOffer({
682
+ satisfies: "NetworkAndCompute.SecurityGroup",
683
+ offerType: "NetworkAndCompute.IaaS.AwsSecurityGroup",
684
+ provider: "AWS",
685
+ deliveryModel: "IaaS"
686
+ });
687
+ const AzureNsg = defineOffer({
688
+ satisfies: "NetworkAndCompute.SecurityGroup",
689
+ offerType: "NetworkAndCompute.IaaS.AzureNsg",
690
+ provider: "Azure",
691
+ deliveryModel: "IaaS"
692
+ });
693
+ const GcpFirewall = defineOffer({
694
+ satisfies: "NetworkAndCompute.SecurityGroup",
695
+ offerType: "NetworkAndCompute.IaaS.GcpFirewall",
696
+ provider: "GCP",
697
+ deliveryModel: "IaaS"
698
+ });
699
+ const Ec2Instance = defineOffer({
700
+ satisfies: "NetworkAndCompute.VirtualMachine",
701
+ offerType: "NetworkAndCompute.IaaS.Ec2Instance",
702
+ provider: "AWS",
703
+ deliveryModel: "IaaS"
704
+ });
705
+ const AzureVm = defineOffer({
706
+ satisfies: "NetworkAndCompute.VirtualMachine",
707
+ offerType: "NetworkAndCompute.IaaS.AzureVm",
708
+ provider: "Azure",
709
+ deliveryModel: "IaaS"
710
+ });
711
+ const GcpVm = defineOffer({
712
+ satisfies: "NetworkAndCompute.VirtualMachine",
713
+ offerType: "NetworkAndCompute.IaaS.GcpVm",
714
+ provider: "GCP",
715
+ deliveryModel: "IaaS"
716
+ });
717
+ const VsphereVm = defineOffer({
718
+ satisfies: "NetworkAndCompute.VirtualMachine",
719
+ offerType: "NetworkAndCompute.IaaS.VsphereVm",
720
+ provider: "VMware",
721
+ deliveryModel: "IaaS"
722
+ });
723
+ const OpenshiftVm = defineOffer({
724
+ satisfies: "NetworkAndCompute.VirtualMachine",
725
+ offerType: "NetworkAndCompute.CaaS.OpenshiftVm",
726
+ provider: "RedHat",
727
+ deliveryModel: "CaaS"
728
+ });
729
+ const Eks = defineOffer({
730
+ satisfies: "NetworkAndCompute.ContainerPlatform",
731
+ offerType: "NetworkAndCompute.PaaS.Eks",
732
+ provider: "AWS",
733
+ deliveryModel: "PaaS"
734
+ });
735
+ const Aks = defineOffer({
736
+ satisfies: "NetworkAndCompute.ContainerPlatform",
737
+ offerType: "NetworkAndCompute.PaaS.Aks",
738
+ provider: "Azure",
739
+ deliveryModel: "PaaS"
740
+ });
741
+ const Gke = defineOffer({
742
+ satisfies: "NetworkAndCompute.ContainerPlatform",
743
+ offerType: "NetworkAndCompute.PaaS.Gke",
744
+ provider: "GCP",
745
+ deliveryModel: "PaaS"
746
+ });
747
+ const AwsLb = defineOffer({
748
+ satisfies: "NetworkAndCompute.LoadBalancer",
749
+ offerType: "NetworkAndCompute.IaaS.AwsLb",
750
+ provider: "AWS",
751
+ deliveryModel: "IaaS"
752
+ });
753
+ const AzureLb = defineOffer({
754
+ satisfies: "NetworkAndCompute.LoadBalancer",
755
+ offerType: "NetworkAndCompute.IaaS.AzureLb",
756
+ provider: "Azure",
757
+ deliveryModel: "IaaS"
758
+ });
759
+ const GcpGlb = defineOffer({
760
+ satisfies: "NetworkAndCompute.LoadBalancer",
761
+ offerType: "NetworkAndCompute.IaaS.GcpGlb",
762
+ provider: "GCP",
763
+ deliveryModel: "IaaS"
764
+ });
765
+ const OciVcn = defineOffer({
766
+ satisfies: "NetworkAndCompute.VirtualNetwork",
767
+ offerType: "NetworkAndCompute.IaaS.OciVcn",
768
+ provider: "OCI",
769
+ deliveryModel: "IaaS"
770
+ });
771
+ const OciSubnet = defineOffer({
772
+ satisfies: "NetworkAndCompute.Subnet",
773
+ offerType: "NetworkAndCompute.IaaS.OciSubnet",
774
+ provider: "OCI",
775
+ deliveryModel: "IaaS"
776
+ });
777
+ const OciSecurityList = defineOffer({
778
+ satisfies: "NetworkAndCompute.SecurityGroup",
779
+ offerType: "NetworkAndCompute.IaaS.OciSecurityList",
780
+ provider: "OCI",
781
+ deliveryModel: "IaaS"
782
+ });
783
+ const OciInstance = defineOffer({
784
+ satisfies: "NetworkAndCompute.VirtualMachine",
785
+ offerType: "NetworkAndCompute.IaaS.OciInstance",
786
+ provider: "OCI",
787
+ deliveryModel: "IaaS"
788
+ });
789
+ const HetznerNetwork = defineOffer({
790
+ satisfies: "NetworkAndCompute.VirtualNetwork",
791
+ offerType: "NetworkAndCompute.IaaS.HetznerNetwork",
792
+ provider: "Hetzner",
793
+ deliveryModel: "IaaS"
794
+ });
795
+ const HetznerSubnet = defineOffer({
796
+ satisfies: "NetworkAndCompute.Subnet",
797
+ offerType: "NetworkAndCompute.IaaS.HetznerSubnet",
798
+ provider: "Hetzner",
799
+ deliveryModel: "IaaS"
800
+ });
801
+ const HetznerFirewall = defineOffer({
802
+ satisfies: "NetworkAndCompute.SecurityGroup",
803
+ offerType: "NetworkAndCompute.IaaS.HetznerFirewall",
804
+ provider: "Hetzner",
805
+ deliveryModel: "IaaS"
806
+ });
807
+ const HetznerServer = defineOffer({
808
+ satisfies: "NetworkAndCompute.VirtualMachine",
809
+ offerType: "NetworkAndCompute.IaaS.HetznerServer",
810
+ provider: "Hetzner",
811
+ deliveryModel: "IaaS"
812
+ });
813
+ const VspherePortGroup = defineOffer({
814
+ satisfies: "NetworkAndCompute.VirtualNetwork",
815
+ offerType: "NetworkAndCompute.IaaS.VspherePortGroup",
816
+ provider: "VMware",
817
+ deliveryModel: "IaaS"
818
+ });
819
+ const VsphereVlan = defineOffer({
820
+ satisfies: "NetworkAndCompute.Subnet",
821
+ offerType: "NetworkAndCompute.IaaS.VsphereVlan",
822
+ provider: "VMware",
823
+ deliveryModel: "IaaS"
824
+ });
825
+ const OpenshiftSecurityGroup = defineOffer({
826
+ satisfies: "NetworkAndCompute.SecurityGroup",
827
+ offerType: "NetworkAndCompute.CaaS.OpenshiftNetworkPolicy",
828
+ provider: "RedHat",
829
+ deliveryModel: "CaaS"
830
+ });
831
+ const OpenshiftService = defineOffer({
832
+ satisfies: "NetworkAndCompute.LoadBalancer",
833
+ offerType: "NetworkAndCompute.CaaS.OpenshiftService",
834
+ provider: "RedHat",
835
+ deliveryModel: "CaaS"
836
+ });
837
+
838
+ //#endregion
839
+ //#region src/model/offers/storage.ts
840
+ /**
841
+ * offers/storage.ts — Storage domain Offers (Catalogue, Level 3).
842
+ *
843
+ * Concrete, vendor-specific implementations declaring which abstract Storage
844
+ * Component each satisfies. Vendor knobs live in each offer's config only.
845
+ * Vendor-neutral self-hosted offers (e.g. MinIO on any cluster) omit `provider`.
846
+ */
847
+ /**
848
+ * A DBMS offer emits itself PLUS one Database live component per child the
849
+ * application added via `withDatabases` — each database lives in the DBMS's
850
+ * vendor family, so it is not independently offer-selected. Swap the DBMS offer
851
+ * and the databases' offer type follows.
852
+ */
853
+ const dbmsInstantiate = (dbmsType, provider, databaseType) => (ctx, config) => [{
854
+ id: ctx.id,
855
+ type: dbmsType,
856
+ provider,
857
+ deliveryModel: "PaaS",
858
+ parameters: {
859
+ ...ctx.parameters,
860
+ ...config
861
+ },
862
+ dependencies: [...ctx.dependencies],
863
+ links: [...ctx.links]
864
+ }, ...ctx.children.map((child) => ({
865
+ id: child.id,
866
+ type: databaseType,
867
+ provider,
868
+ deliveryModel: "PaaS",
869
+ parameters: { ...child.parameters },
870
+ dependencies: [...child.dependencies],
871
+ links: [...child.links]
872
+ }))];
873
+ const AwsS3 = defineOffer({
874
+ satisfies: "Storage.ObjectStorage",
875
+ offerType: "Storage.PaaS.S3",
876
+ provider: "AWS",
877
+ deliveryModel: "PaaS"
878
+ });
879
+ const AzureBlob = defineOffer({
880
+ satisfies: "Storage.ObjectStorage",
881
+ offerType: "Storage.PaaS.AzureBlob",
882
+ provider: "Azure",
883
+ deliveryModel: "PaaS"
884
+ });
885
+ const GcsBucket = defineOffer({
886
+ satisfies: "Storage.ObjectStorage",
887
+ offerType: "Storage.PaaS.GcsBucket",
888
+ provider: "GCP",
889
+ deliveryModel: "PaaS"
890
+ });
891
+ const MinIO = defineOffer({
892
+ satisfies: "Storage.ObjectStorage",
893
+ offerType: "Storage.CaaS.MinIO",
894
+ deliveryModel: "CaaS"
895
+ });
896
+ const AzurePostgresDbms = defineOffer({
897
+ satisfies: "Storage.RelationalDbms",
898
+ offerType: "Storage.PaaS.AzurePostgresDbms",
899
+ provider: "Azure",
900
+ deliveryModel: "PaaS",
901
+ instantiate: dbmsInstantiate("Storage.PaaS.AzurePostgresDbms", "Azure", "Storage.PaaS.AzurePostgresDatabase")
902
+ });
903
+ const GcpPostgresDbms = defineOffer({
904
+ satisfies: "Storage.RelationalDbms",
905
+ offerType: "Storage.PaaS.GcpPostgresDbms",
906
+ provider: "GCP",
907
+ deliveryModel: "PaaS",
908
+ instantiate: dbmsInstantiate("Storage.PaaS.GcpPostgresDbms", "GCP", "Storage.PaaS.GcpPostgresDatabase")
909
+ });
910
+ const ArubaMySqlDbms = defineOffer({
911
+ satisfies: "Storage.RelationalDbms",
912
+ offerType: "Storage.PaaS.ArubaMySqlDbms",
913
+ provider: "Aruba",
914
+ deliveryModel: "PaaS",
915
+ instantiate: dbmsInstantiate("Storage.PaaS.ArubaMySqlDbms", "Aruba", "Storage.PaaS.ArubaMySqlDatabase")
916
+ });
917
+ const AzurePostgresDatabase = defineOffer({
918
+ satisfies: "Storage.RelationalDatabase",
919
+ offerType: "Storage.PaaS.AzurePostgresDatabase",
920
+ provider: "Azure",
921
+ deliveryModel: "PaaS"
922
+ });
923
+ const GcpPostgresDatabase = defineOffer({
924
+ satisfies: "Storage.RelationalDatabase",
925
+ offerType: "Storage.PaaS.GcpPostgresDatabase",
926
+ provider: "GCP",
927
+ deliveryModel: "PaaS"
928
+ });
929
+ const OpenshiftPersistentVolume = defineOffer({
930
+ satisfies: "Storage.ObjectStorage",
931
+ offerType: "Storage.CaaS.OpenshiftPersistentVolume",
932
+ provider: "RedHat",
933
+ deliveryModel: "CaaS"
934
+ });
935
+
936
+ //#endregion
937
+ //#region src/model/offers/big_data.ts
938
+ /**
939
+ * offers/big_data.ts — BigData domain Offers (Catalogue, Level 3, concrete).
940
+ *
941
+ * Each offer declares which Component it satisfies, its 3-part offer type, its
942
+ * delivery model and (for cloud offers) its vendor. Vendor-neutral CaaS offers
943
+ * OMIT `provider` — they run on any cluster and are identified by deliveryModel
944
+ * + offerType. Vendor knobs live in each offer's config type.
945
+ */
946
+ const AwsDatabricksCluster = defineOffer({
947
+ satisfies: "BigData.ComputeCluster",
948
+ offerType: "BigData.PaaS.AwsDatabricksCluster",
949
+ provider: "AWS",
950
+ deliveryModel: "PaaS"
951
+ });
952
+ const AzureDatabricksCluster = defineOffer({
953
+ satisfies: "BigData.ComputeCluster",
954
+ offerType: "BigData.PaaS.AzureDatabricksCluster",
955
+ provider: "Azure",
956
+ deliveryModel: "PaaS"
957
+ });
958
+ const GcpDatabricksCluster = defineOffer({
959
+ satisfies: "BigData.ComputeCluster",
960
+ offerType: "BigData.PaaS.GcpDatabricksCluster",
961
+ provider: "GCP",
962
+ deliveryModel: "PaaS"
963
+ });
964
+ const CaaSSparkCluster = defineOffer({
965
+ satisfies: "BigData.ComputeCluster",
966
+ offerType: "BigData.CaaS.CaaSSparkCluster",
967
+ deliveryModel: "CaaS"
968
+ });
969
+ const AwsDatabricksJob = defineOffer({
970
+ satisfies: "BigData.DataProcessingJob",
971
+ offerType: "BigData.PaaS.AwsDatabricksJob",
972
+ provider: "AWS",
973
+ deliveryModel: "PaaS"
974
+ });
975
+ const AzureDatabricksJob = defineOffer({
976
+ satisfies: "BigData.DataProcessingJob",
977
+ offerType: "BigData.PaaS.AzureDatabricksJob",
978
+ provider: "Azure",
979
+ deliveryModel: "PaaS"
980
+ });
981
+ const GcpDatabricksJob = defineOffer({
982
+ satisfies: "BigData.DataProcessingJob",
983
+ offerType: "BigData.PaaS.GcpDatabricksJob",
984
+ provider: "GCP",
985
+ deliveryModel: "PaaS"
986
+ });
987
+ const CaaSSparkJob = defineOffer({
988
+ satisfies: "BigData.DataProcessingJob",
989
+ offerType: "BigData.CaaS.CaaSSparkJob",
990
+ deliveryModel: "CaaS"
991
+ });
992
+ const AwsDatabricksMlflow = defineOffer({
993
+ satisfies: "BigData.MlExperiment",
994
+ offerType: "BigData.PaaS.AwsDatabricksMlflow",
995
+ provider: "AWS",
996
+ deliveryModel: "PaaS"
997
+ });
998
+ const AzureDatabricksMlflow = defineOffer({
999
+ satisfies: "BigData.MlExperiment",
1000
+ offerType: "BigData.PaaS.AzureDatabricksMlflow",
1001
+ provider: "Azure",
1002
+ deliveryModel: "PaaS"
1003
+ });
1004
+ const GcpDatabricksMlflow = defineOffer({
1005
+ satisfies: "BigData.MlExperiment",
1006
+ offerType: "BigData.PaaS.GcpDatabricksMlflow",
1007
+ provider: "GCP",
1008
+ deliveryModel: "PaaS"
1009
+ });
1010
+ const CaaSMlflow = defineOffer({
1011
+ satisfies: "BigData.MlExperiment",
1012
+ offerType: "BigData.CaaS.CaaSMlflow",
1013
+ deliveryModel: "CaaS"
1014
+ });
1015
+ const AwsS3Datalake = defineOffer({
1016
+ satisfies: "BigData.Datalake",
1017
+ offerType: "BigData.PaaS.AwsS3Datalake",
1018
+ provider: "AWS",
1019
+ deliveryModel: "PaaS"
1020
+ });
1021
+ const AzureDatalake = defineOffer({
1022
+ satisfies: "BigData.Datalake",
1023
+ offerType: "BigData.PaaS.AzureDatalake",
1024
+ provider: "Azure",
1025
+ deliveryModel: "PaaS"
1026
+ });
1027
+ const GcpDatalake = defineOffer({
1028
+ satisfies: "BigData.Datalake",
1029
+ offerType: "BigData.PaaS.GcpDatalake",
1030
+ provider: "GCP",
1031
+ deliveryModel: "PaaS"
1032
+ });
1033
+ const AwsDatabricks = defineOffer({
1034
+ satisfies: "BigData.DistributedDataProcessing",
1035
+ offerType: "BigData.PaaS.AwsDatabricks",
1036
+ provider: "AWS",
1037
+ deliveryModel: "PaaS"
1038
+ });
1039
+ const AzureDatabricks = defineOffer({
1040
+ satisfies: "BigData.DistributedDataProcessing",
1041
+ offerType: "BigData.PaaS.AzureDatabricks",
1042
+ provider: "Azure",
1043
+ deliveryModel: "PaaS"
1044
+ });
1045
+ const GcpDatabricks = defineOffer({
1046
+ satisfies: "BigData.DistributedDataProcessing",
1047
+ offerType: "BigData.PaaS.GcpDatabricks",
1048
+ provider: "GCP",
1049
+ deliveryModel: "PaaS"
1050
+ });
1051
+
1052
+ //#endregion
1053
+ //#region src/model/offers/messaging.ts
1054
+ /**
1055
+ * offers/messaging.ts — Messaging domain Offers (Catalogue, Level 3).
1056
+ *
1057
+ * Concrete vendor-specific implementations that satisfy the abstract Messaging
1058
+ * Components in components/messaging.ts. Vendor knobs live in each offer's Cfg.
1059
+ * Vendor-neutral self-hosted offers (Kafka on any cluster) OMIT `provider`.
1060
+ */
1061
+ const AzureServiceBus = defineOffer({
1062
+ satisfies: "Messaging.Broker",
1063
+ offerType: "Messaging.PaaS.AzureServiceBus",
1064
+ provider: "Azure",
1065
+ deliveryModel: "PaaS"
1066
+ });
1067
+ const GcpPubSub = defineOffer({
1068
+ satisfies: "Messaging.Broker",
1069
+ offerType: "Messaging.PaaS.GcpPubSub",
1070
+ provider: "GCP",
1071
+ deliveryModel: "PaaS"
1072
+ });
1073
+ /** Vendor-neutral self-hosted Kafka — no `provider`. */
1074
+ const Kafka = defineOffer({
1075
+ satisfies: "Messaging.Broker",
1076
+ offerType: "Messaging.CaaS.Kafka",
1077
+ deliveryModel: "CaaS"
1078
+ });
1079
+ const AzureServiceBusTopic = defineOffer({
1080
+ satisfies: "Messaging.MessagingEntity",
1081
+ offerType: "Messaging.PaaS.AzureServiceBusTopic",
1082
+ provider: "Azure",
1083
+ deliveryModel: "PaaS"
1084
+ });
1085
+ const GcpPubSubTopic = defineOffer({
1086
+ satisfies: "Messaging.MessagingEntity",
1087
+ offerType: "Messaging.PaaS.GcpPubSubTopic",
1088
+ provider: "GCP",
1089
+ deliveryModel: "PaaS"
1090
+ });
1091
+ /** Vendor-neutral self-hosted Kafka topic — no `provider`. */
1092
+ const KafkaTopic = defineOffer({
1093
+ satisfies: "Messaging.MessagingEntity",
1094
+ offerType: "Messaging.CaaS.KafkaTopic",
1095
+ deliveryModel: "CaaS"
1096
+ });
1097
+
1098
+ //#endregion
1099
+ //#region src/model/offers/api_management.ts
1100
+ /**
1101
+ * offers/api_management.ts — APIManagement Offer catalogue (Level 3).
1102
+ *
1103
+ * Each offer declares which abstract Component it satisfies, its 3-part offer
1104
+ * type, its vendor (provider) and delivery model, and carries vendor knobs in
1105
+ * its config type. Vendor-neutral self-hosted offers (CaaS) OMIT `provider`.
1106
+ */
1107
+ const AwsCloudFront = defineOffer({
1108
+ satisfies: "APIManagement.ApiGateway",
1109
+ offerType: "APIManagement.PaaS.CloudFront",
1110
+ provider: "AWS",
1111
+ deliveryModel: "PaaS"
1112
+ });
1113
+ const AzureApiManagement = defineOffer({
1114
+ satisfies: "APIManagement.ApiGateway",
1115
+ offerType: "APIManagement.PaaS.ApiManagement",
1116
+ provider: "Azure",
1117
+ deliveryModel: "PaaS"
1118
+ });
1119
+ const GcpApiGateway = defineOffer({
1120
+ satisfies: "APIManagement.ApiGateway",
1121
+ offerType: "APIManagement.PaaS.GcpApiGateway",
1122
+ provider: "GCP",
1123
+ deliveryModel: "PaaS"
1124
+ });
1125
+ const Ambassador = defineOffer({
1126
+ satisfies: "APIManagement.ApiGateway",
1127
+ offerType: "APIManagement.CaaS.Ambassador",
1128
+ deliveryModel: "CaaS"
1129
+ });
1130
+ const Traefik = defineOffer({
1131
+ satisfies: "APIManagement.ApiGateway",
1132
+ offerType: "APIManagement.CaaS.Traefik",
1133
+ deliveryModel: "CaaS"
1134
+ });
1135
+
1136
+ //#endregion
1137
+ //#region src/model/offers/observability.ts
1138
+ /**
1139
+ * offers/observability.ts — Observability domain Offers (Catalogue, Level 3).
1140
+ *
1141
+ * Concrete implementations declaring which abstract Observability Component each
1142
+ * satisfies. Vendor knobs live in each offer's config only. These are all
1143
+ * vendor-neutral self-hosted CaaS offers (Prometheus/Jaeger/Elastic on any
1144
+ * cluster), so they omit `provider`.
1145
+ */
1146
+ const Prometheus = defineOffer({
1147
+ satisfies: "Observability.Monitoring",
1148
+ offerType: "Observability.CaaS.Prometheus",
1149
+ deliveryModel: "CaaS"
1150
+ });
1151
+ const Jaeger = defineOffer({
1152
+ satisfies: "Observability.Tracing",
1153
+ offerType: "Observability.CaaS.Jaeger",
1154
+ deliveryModel: "CaaS"
1155
+ });
1156
+ const ObservabilityElastic = defineOffer({
1157
+ satisfies: "Observability.Logging",
1158
+ offerType: "Observability.CaaS.Elastic",
1159
+ deliveryModel: "CaaS"
1160
+ });
1161
+
1162
+ //#endregion
1163
+ //#region src/model/offers/security.ts
1164
+ /**
1165
+ * offers/security.ts — Security domain Offers (Catalogue, Level 3).
1166
+ *
1167
+ * Concrete implementations declaring which abstract Security Component each
1168
+ * satisfies. Vendor knobs live in each offer's config only. Vendor-neutral
1169
+ * self-hosted offers (e.g. Ocelot / Keycloak on any cluster) omit `provider`.
1170
+ */
1171
+ const Ocelot = defineOffer({
1172
+ satisfies: "Security.ServiceMesh",
1173
+ offerType: "Security.CaaS.Ocelot",
1174
+ deliveryModel: "CaaS"
1175
+ });
1176
+ const Cognito = defineOffer({
1177
+ satisfies: "Security.IdentityProvider",
1178
+ offerType: "Security.PaaS.Cognito",
1179
+ provider: "AWS",
1180
+ deliveryModel: "PaaS"
1181
+ });
1182
+ const Keycloak = defineOffer({
1183
+ satisfies: "Security.IdentityProvider",
1184
+ offerType: "Security.CaaS.Keycloak",
1185
+ deliveryModel: "CaaS"
1186
+ });
1187
+
1188
+ //#endregion
1189
+ //#region src/model/offers/custom_workloads.ts
1190
+ /**
1191
+ * offers/custom_workloads.ts — CustomWorkloads domain Offers (Catalogue, Level 3,
1192
+ * concrete).
1193
+ *
1194
+ * Each offer declares which Component it satisfies, its 3-part offer type, its
1195
+ * delivery model and (for cloud offers) its vendor. Vendor-neutral CaaS offers
1196
+ * OMIT `provider` — they run on any cluster and are identified by deliveryModel
1197
+ * + offerType. Vendor knobs live in each offer's config type.
1198
+ */
1199
+ const EcsService = defineOffer({
1200
+ satisfies: "CustomWorkloads.Workload",
1201
+ offerType: "CustomWorkloads.PaaS.EcsService",
1202
+ provider: "AWS",
1203
+ deliveryModel: "PaaS"
1204
+ });
1205
+ const CloudRun = defineOffer({
1206
+ satisfies: "CustomWorkloads.Workload",
1207
+ offerType: "CustomWorkloads.PaaS.CloudRun",
1208
+ provider: "GCP",
1209
+ deliveryModel: "PaaS"
1210
+ });
1211
+ const AzureContainerApp = defineOffer({
1212
+ satisfies: "CustomWorkloads.Workload",
1213
+ offerType: "CustomWorkloads.PaaS.AzureContainerApp",
1214
+ provider: "Azure",
1215
+ deliveryModel: "PaaS"
1216
+ });
1217
+ const OpenshiftWorkload = defineOffer({
1218
+ satisfies: "CustomWorkloads.Workload",
1219
+ offerType: "CustomWorkloads.CaaS.OpenshiftWorkload",
1220
+ provider: "RedHat",
1221
+ deliveryModel: "CaaS"
1222
+ });
1223
+ const K8sWorkload = defineOffer({
1224
+ satisfies: "CustomWorkloads.Workload",
1225
+ offerType: "CustomWorkloads.CaaS.K8sWorkload",
1226
+ deliveryModel: "CaaS"
1227
+ });
1228
+ const AwsLambda = defineOffer({
1229
+ satisfies: "CustomWorkloads.Function",
1230
+ offerType: "CustomWorkloads.FaaS.AwsLambda",
1231
+ provider: "AWS",
1232
+ deliveryModel: "FaaS"
1233
+ });
1234
+ const AzureFunction = defineOffer({
1235
+ satisfies: "CustomWorkloads.Function",
1236
+ offerType: "CustomWorkloads.FaaS.AzureFunction",
1237
+ provider: "Azure",
1238
+ deliveryModel: "FaaS"
1239
+ });
1240
+ const GcpFunction = defineOffer({
1241
+ satisfies: "CustomWorkloads.Function",
1242
+ offerType: "CustomWorkloads.FaaS.GcpFunction",
1243
+ provider: "GCP",
1244
+ deliveryModel: "FaaS"
1245
+ });
1246
+
1247
+ //#endregion
1248
+ export { Aks, Ambassador, ApiGateway, ArubaMySqlDbms, AwsCloudFront, AwsDatabricks, AwsDatabricksCluster, AwsDatabricksJob, AwsDatabricksMlflow, AwsLambda, AwsLb, AwsS3, AwsS3Datalake, AwsSecurityGroup, AwsSubnet, AwsVpc, AzureApiManagement, AzureBlob, AzureContainerApp, AzureDatabricks, AzureDatabricksCluster, AzureDatabricksJob, AzureDatabricksMlflow, AzureDatalake, AzureFunction, AzureLb, AzureNsg, AzurePostgresDatabase, AzurePostgresDbms, AzureServiceBus, AzureServiceBusTopic, AzureSubnet, AzureVm, AzureVnet, Broker, CaaSMlflow, CaaSSparkCluster, CaaSSparkJob, CloudRun, Cognito, ComputeCluster, ContainerPlatform, DataProcessingJob, Datalake, DistributedDataProcessing, Ec2Instance, EcsService, Eks, Function, GcpApiGateway, GcpDatabricks, GcpDatabricksCluster, GcpDatabricksJob, GcpDatabricksMlflow, GcpDatalake, GcpFirewall, GcpFunction, GcpGlb, GcpPostgresDatabase, GcpPostgresDbms, GcpPubSub, GcpPubSubTopic, GcpSubnet, GcpVm, GcpVpc, GcsBucket, Gke, HetznerFirewall, HetznerNetwork, HetznerServer, HetznerSubnet, IdentityProvider, Jaeger, K8sWorkload, Kafka, KafkaTopic, Keycloak, LoadBalancer, Logging, MessagingEntity, MinIO, MlExperiment, Monitoring, ObjectStorage, ObservabilityElastic, Ocelot, OciInstance, OciSecurityList, OciSubnet, OciVcn, OpenshiftPersistentVolume, OpenshiftSecurityGroup, OpenshiftService, OpenshiftVm, OpenshiftWorkload, Prometheus, RelationalDatabase, RelationalDbms, SecurityGroup, ServiceMesh, Subnet, Tracing, Traefik, VirtualMachine, VirtualNetwork, VspherePortGroup, VsphereVlan, VsphereVm, Workload, addDependency, createFractal, defineOffer, deploy, destroy, guardrail, newNode };