@happyvertical/smrt-sites 0.37.1 → 0.37.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,411 +1,389 @@
1
- import { ObjectRegistry, foreignKey, smrt, SmrtObject, SmrtCollection } from "@happyvertical/smrt-core";
2
- import { tenantId, TenantScoped } from "@happyvertical/smrt-tenancy";
3
- ObjectRegistry.registerPackageManifest(
4
- new URL("./manifest.json", import.meta.url)
5
- );
1
+ import { ObjectRegistry, SmrtCollection, SmrtObject, foreignKey, smrt } from "@happyvertical/smrt-core";
2
+ import { TenantScoped, tenantId } from "@happyvertical/smrt-tenancy";
3
+ //#region src/__smrt-register__.ts
4
+ ObjectRegistry.registerPackageManifest(new URL("./manifest.json", "" + import.meta.url));
5
+ //#endregion
6
+ //#region src/models/SiteAgentBinding.ts
6
7
  var __defProp$1 = Object.defineProperty;
7
8
  var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
8
9
  var __decorateClass$1 = (decorators, target, key, kind) => {
9
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
10
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
11
- if (decorator = decorators[i])
12
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
13
- if (kind && result) __defProp$1(target, key, result);
14
- return result;
10
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
11
+ for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
12
+ if (kind && result) __defProp$1(target, key, result);
13
+ return result;
15
14
  };
16
- let SiteAgentBinding = class extends SmrtObject {
17
- tenantId = "";
18
- siteId = "";
19
- /** Agent class name, e.g. "Praeco" */
20
- agentClass = "";
21
- /** Whether this agent is enabled for the site */
22
- enabled = true;
23
- /** Per-site agent configuration overrides (JSON) */
24
- config = null;
25
- /** Sort priority (higher = first) */
26
- priority = 0;
27
- constructor(options = {}) {
28
- super(options);
29
- if (options.tenantId !== void 0) this.tenantId = options.tenantId;
30
- if (options.siteId !== void 0) this.siteId = options.siteId;
31
- if (options.agentClass !== void 0) this.agentClass = options.agentClass;
32
- if (options.enabled !== void 0) this.enabled = options.enabled;
33
- if (options.priority !== void 0) this.priority = options.priority;
34
- if (options.config !== void 0) {
35
- if (typeof options.config === "string") {
36
- try {
37
- this.config = JSON.parse(options.config);
38
- } catch {
39
- this.config = null;
40
- }
41
- } else {
42
- this.config = options.config;
43
- }
44
- }
45
- }
15
+ var SiteAgentBinding = class extends SmrtObject {
16
+ tenantId = "";
17
+ siteId = "";
18
+ /** Agent class name, e.g. "Praeco" */
19
+ agentClass = "";
20
+ /** Whether this agent is enabled for the site */
21
+ enabled = true;
22
+ /** Per-site agent configuration overrides (JSON) */
23
+ config = null;
24
+ /** Sort priority (higher = first) */
25
+ priority = 0;
26
+ constructor(options = {}) {
27
+ super(options);
28
+ if (options.tenantId !== void 0) this.tenantId = options.tenantId;
29
+ if (options.siteId !== void 0) this.siteId = options.siteId;
30
+ if (options.agentClass !== void 0) this.agentClass = options.agentClass;
31
+ if (options.enabled !== void 0) this.enabled = options.enabled;
32
+ if (options.priority !== void 0) this.priority = options.priority;
33
+ if (options.config !== void 0) if (typeof options.config === "string") try {
34
+ this.config = JSON.parse(options.config);
35
+ } catch {
36
+ this.config = null;
37
+ }
38
+ else this.config = options.config;
39
+ }
46
40
  };
47
- __decorateClass$1([
48
- tenantId()
49
- ], SiteAgentBinding.prototype, "tenantId", 2);
50
- __decorateClass$1([
51
- foreignKey("Site")
52
- ], SiteAgentBinding.prototype, "siteId", 2);
53
- SiteAgentBinding = __decorateClass$1([
54
- TenantScoped({ mode: "required" }),
55
- smrt({
56
- tableName: "site_agent_bindings",
57
- api: { include: ["list", "get", "create", "update", "delete"] },
58
- cli: { include: ["list", "get"] },
59
- mcp: { include: ["list", "get"] },
60
- conflictColumns: ["site_id", "agent_class"]
61
- })
62
- ], SiteAgentBinding);
63
- class SiteAgentBindingCollection extends SmrtCollection {
64
- static _itemClass = SiteAgentBinding;
65
- /**
66
- * Find all agent bindings for a site
67
- */
68
- async findBySite(siteId) {
69
- return this.list({ where: { siteId } });
70
- }
71
- /**
72
- * Find all sites using a specific agent class
73
- */
74
- async findByAgent(agentClass) {
75
- return this.list({ where: { agentClass } });
76
- }
77
- /**
78
- * Find enabled bindings for a site, ordered by priority descending
79
- */
80
- async findEnabled(siteId) {
81
- const bindings = await this.list({
82
- where: { siteId, enabled: true }
83
- });
84
- return bindings.sort((a, b) => b.priority - a.priority);
85
- }
86
- /**
87
- * Find a specific site-agent binding
88
- */
89
- async findBySiteAndAgent(siteId, agentClass) {
90
- const results = await this.list({
91
- where: { siteId, agentClass }
92
- });
93
- return results[0] ?? null;
94
- }
95
- }
41
+ __decorateClass$1([tenantId()], SiteAgentBinding.prototype, "tenantId", 2);
42
+ __decorateClass$1([foreignKey("Site")], SiteAgentBinding.prototype, "siteId", 2);
43
+ SiteAgentBinding = __decorateClass$1([TenantScoped({ mode: "required" }), smrt({
44
+ tableName: "site_agent_bindings",
45
+ api: { include: [
46
+ "list",
47
+ "get",
48
+ "create",
49
+ "update",
50
+ "delete"
51
+ ] },
52
+ cli: { include: ["list", "get"] },
53
+ mcp: { include: ["list", "get"] },
54
+ conflictColumns: ["site_id", "agent_class"]
55
+ })], SiteAgentBinding);
56
+ //#endregion
57
+ //#region src/collections/SiteAgentBindingCollection.ts
58
+ var SiteAgentBindingCollection = class extends SmrtCollection {
59
+ static _itemClass = SiteAgentBinding;
60
+ /**
61
+ * Find all agent bindings for a site
62
+ */
63
+ async findBySite(siteId) {
64
+ return this.list({ where: { siteId } });
65
+ }
66
+ /**
67
+ * Find all sites using a specific agent class
68
+ */
69
+ async findByAgent(agentClass) {
70
+ return this.list({ where: { agentClass } });
71
+ }
72
+ /**
73
+ * Find enabled bindings for a site, ordered by priority descending
74
+ */
75
+ async findEnabled(siteId) {
76
+ return (await this.list({ where: {
77
+ siteId,
78
+ enabled: true
79
+ } })).sort((a, b) => b.priority - a.priority);
80
+ }
81
+ /**
82
+ * Find a specific site-agent binding
83
+ */
84
+ async findBySiteAndAgent(siteId, agentClass) {
85
+ return (await this.list({ where: {
86
+ siteId,
87
+ agentClass
88
+ } }))[0] ?? null;
89
+ }
90
+ };
91
+ //#endregion
92
+ //#region src/models/Site.ts
96
93
  var __defProp = Object.defineProperty;
97
94
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
98
95
  var __decorateClass = (decorators, target, key, kind) => {
99
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
100
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
101
- if (decorator = decorators[i])
102
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
103
- if (kind && result) __defProp(target, key, result);
104
- return result;
96
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
97
+ for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
98
+ if (kind && result) __defProp(target, key, result);
99
+ return result;
100
+ };
101
+ var Site = class extends SmrtObject {
102
+ tenantId = "";
103
+ /** Display name, e.g. "Bentley Alberta" */
104
+ name = "";
105
+ /** Primary domain, e.g. "bentleyalberta.com" */
106
+ domain = "";
107
+ /** Lifecycle status */
108
+ status = "draft";
109
+ /** Pricing/feature tier */
110
+ tier = "free";
111
+ /** Site-specific database connection URL */
112
+ databaseUrl = "";
113
+ /** Database type: sqlite, postgres, libsql */
114
+ databaseType = "";
115
+ /** Theme, branding, navigation settings (JSON) */
116
+ portalConfig = "";
117
+ /** Git repository URL */
118
+ repositoryUrl = "";
119
+ /** Starter template name */
120
+ templateName = "";
121
+ /** Infrastructure provisioning status */
122
+ provisioningStatus = "";
123
+ /** When provisioning completed */
124
+ provisionedAt = null;
125
+ /** Last provisioning error message */
126
+ provisioningError = "";
127
+ /** Extensible key-value metadata (JSON) */
128
+ metadata = "";
129
+ createdAt = /* @__PURE__ */ new Date();
130
+ updatedAt = /* @__PURE__ */ new Date();
131
+ constructor(options = {}) {
132
+ super(options);
133
+ if (options.tenantId !== void 0) this.tenantId = options.tenantId;
134
+ if (options.name !== void 0) this.name = options.name;
135
+ if (options.domain !== void 0) this.domain = options.domain;
136
+ if (options.status !== void 0) this.status = options.status;
137
+ if (options.tier !== void 0) this.tier = options.tier;
138
+ if (options.databaseUrl !== void 0) this.databaseUrl = options.databaseUrl;
139
+ if (options.databaseType !== void 0) this.databaseType = options.databaseType;
140
+ if (options.repositoryUrl !== void 0) this.repositoryUrl = options.repositoryUrl;
141
+ if (options.templateName !== void 0) this.templateName = options.templateName;
142
+ if (options.provisioningStatus !== void 0) this.provisioningStatus = options.provisioningStatus;
143
+ if (options.provisionedAt !== void 0) this.provisionedAt = options.provisionedAt;
144
+ if (options.provisioningError !== void 0) this.provisioningError = options.provisioningError;
145
+ if (options.portalConfig !== void 0) if (typeof options.portalConfig === "string") this.portalConfig = options.portalConfig;
146
+ else this.portalConfig = JSON.stringify(options.portalConfig);
147
+ if (options.metadata !== void 0) if (typeof options.metadata === "string") this.metadata = options.metadata;
148
+ else this.metadata = JSON.stringify(options.metadata);
149
+ if (options.createdAt) this.createdAt = options.createdAt;
150
+ if (options.updatedAt) this.updatedAt = options.updatedAt;
151
+ }
152
+ /**
153
+ * Check if the site is active
154
+ */
155
+ isActive() {
156
+ return this.status === "active";
157
+ }
158
+ /**
159
+ * Check if the site is provisioned and ready
160
+ */
161
+ isReady() {
162
+ return this.provisioningStatus === "ready";
163
+ }
164
+ /**
165
+ * Get portal config as parsed object
166
+ */
167
+ getPortalConfig() {
168
+ if (!this.portalConfig) return {};
169
+ try {
170
+ return JSON.parse(this.portalConfig);
171
+ } catch {
172
+ return {};
173
+ }
174
+ }
175
+ /**
176
+ * Set portal config from object
177
+ */
178
+ setPortalConfig(config) {
179
+ this.portalConfig = JSON.stringify(config);
180
+ }
181
+ /**
182
+ * Get metadata as parsed object
183
+ */
184
+ getMetadata() {
185
+ if (!this.metadata) return {};
186
+ try {
187
+ return JSON.parse(this.metadata);
188
+ } catch {
189
+ return {};
190
+ }
191
+ }
192
+ /**
193
+ * Set metadata from object
194
+ */
195
+ setMetadata(data) {
196
+ this.metadata = JSON.stringify(data);
197
+ }
198
+ /**
199
+ * Update metadata by merging with existing values
200
+ */
201
+ updateMetadata(updates) {
202
+ const current = this.getMetadata();
203
+ this.setMetadata({
204
+ ...current,
205
+ ...updates
206
+ });
207
+ }
105
208
  };
106
- let Site = class extends SmrtObject {
107
- tenantId = "";
108
- /** Display name, e.g. "Bentley Alberta" */
109
- name = "";
110
- /** Primary domain, e.g. "bentleyalberta.com" */
111
- domain = "";
112
- /** Lifecycle status */
113
- status = "draft";
114
- /** Pricing/feature tier */
115
- tier = "free";
116
- /** Site-specific database connection URL */
117
- databaseUrl = "";
118
- /** Database type: sqlite, postgres, libsql */
119
- databaseType = "";
120
- /** Theme, branding, navigation settings (JSON) */
121
- portalConfig = "";
122
- /** Git repository URL */
123
- repositoryUrl = "";
124
- /** Starter template name */
125
- templateName = "";
126
- /** Infrastructure provisioning status */
127
- provisioningStatus = "";
128
- /** When provisioning completed */
129
- provisionedAt = null;
130
- /** Last provisioning error message */
131
- provisioningError = "";
132
- /** Extensible key-value metadata (JSON) */
133
- metadata = "";
134
- createdAt = /* @__PURE__ */ new Date();
135
- updatedAt = /* @__PURE__ */ new Date();
136
- constructor(options = {}) {
137
- super(options);
138
- if (options.tenantId !== void 0) this.tenantId = options.tenantId;
139
- if (options.name !== void 0) this.name = options.name;
140
- if (options.domain !== void 0) this.domain = options.domain;
141
- if (options.status !== void 0) this.status = options.status;
142
- if (options.tier !== void 0) this.tier = options.tier;
143
- if (options.databaseUrl !== void 0)
144
- this.databaseUrl = options.databaseUrl;
145
- if (options.databaseType !== void 0)
146
- this.databaseType = options.databaseType;
147
- if (options.repositoryUrl !== void 0)
148
- this.repositoryUrl = options.repositoryUrl;
149
- if (options.templateName !== void 0)
150
- this.templateName = options.templateName;
151
- if (options.provisioningStatus !== void 0)
152
- this.provisioningStatus = options.provisioningStatus;
153
- if (options.provisionedAt !== void 0)
154
- this.provisionedAt = options.provisionedAt;
155
- if (options.provisioningError !== void 0)
156
- this.provisioningError = options.provisioningError;
157
- if (options.portalConfig !== void 0) {
158
- if (typeof options.portalConfig === "string") {
159
- this.portalConfig = options.portalConfig;
160
- } else {
161
- this.portalConfig = JSON.stringify(options.portalConfig);
162
- }
163
- }
164
- if (options.metadata !== void 0) {
165
- if (typeof options.metadata === "string") {
166
- this.metadata = options.metadata;
167
- } else {
168
- this.metadata = JSON.stringify(options.metadata);
169
- }
170
- }
171
- if (options.createdAt) this.createdAt = options.createdAt;
172
- if (options.updatedAt) this.updatedAt = options.updatedAt;
173
- }
174
- /**
175
- * Check if the site is active
176
- */
177
- isActive() {
178
- return this.status === "active";
179
- }
180
- /**
181
- * Check if the site is provisioned and ready
182
- */
183
- isReady() {
184
- return this.provisioningStatus === "ready";
185
- }
186
- /**
187
- * Get portal config as parsed object
188
- */
189
- getPortalConfig() {
190
- if (!this.portalConfig) return {};
191
- try {
192
- return JSON.parse(this.portalConfig);
193
- } catch {
194
- return {};
195
- }
196
- }
197
- /**
198
- * Set portal config from object
199
- */
200
- setPortalConfig(config) {
201
- this.portalConfig = JSON.stringify(config);
202
- }
203
- /**
204
- * Get metadata as parsed object
205
- */
206
- getMetadata() {
207
- if (!this.metadata) return {};
208
- try {
209
- return JSON.parse(this.metadata);
210
- } catch {
211
- return {};
212
- }
213
- }
214
- /**
215
- * Set metadata from object
216
- */
217
- setMetadata(data) {
218
- this.metadata = JSON.stringify(data);
219
- }
220
- /**
221
- * Update metadata by merging with existing values
222
- */
223
- updateMetadata(updates) {
224
- const current = this.getMetadata();
225
- this.setMetadata({ ...current, ...updates });
226
- }
209
+ __decorateClass([tenantId()], Site.prototype, "tenantId", 2);
210
+ Site = __decorateClass([TenantScoped({ mode: "required" }), smrt({
211
+ tableName: "sites",
212
+ api: { include: [
213
+ "list",
214
+ "get",
215
+ "create",
216
+ "update",
217
+ "delete"
218
+ ] },
219
+ mcp: { include: [
220
+ "list",
221
+ "get",
222
+ "create",
223
+ "update"
224
+ ] },
225
+ cli: true,
226
+ conflictColumns: ["tenant_id", "domain"]
227
+ })], Site);
228
+ //#endregion
229
+ //#region src/collections/SiteCollection.ts
230
+ var SiteCollection = class extends SmrtCollection {
231
+ static _itemClass = Site;
232
+ /**
233
+ * Find a site by its primary domain
234
+ */
235
+ async findByDomain(domain) {
236
+ return (await this.list({ where: { domain } }))[0] ?? null;
237
+ }
238
+ /**
239
+ * Find all sites belonging to a tenant
240
+ */
241
+ async findByTenant(tenantId) {
242
+ return this.list({ where: { tenantId } });
243
+ }
244
+ /**
245
+ * Find sites by lifecycle status
246
+ */
247
+ async findByStatus(status) {
248
+ return this.list({ where: { status } });
249
+ }
250
+ /**
251
+ * Find all active sites
252
+ */
253
+ async findActive() {
254
+ return this.findByStatus("active");
255
+ }
227
256
  };
228
- __decorateClass([
229
- tenantId()
230
- ], Site.prototype, "tenantId", 2);
231
- Site = __decorateClass([
232
- TenantScoped({ mode: "required" }),
233
- smrt({
234
- tableName: "sites",
235
- api: { include: ["list", "get", "create", "update", "delete"] },
236
- mcp: { include: ["list", "get", "create", "update"] },
237
- cli: true,
238
- conflictColumns: ["tenant_id", "domain"]
239
- })
240
- ], Site);
241
- class SiteCollection extends SmrtCollection {
242
- static _itemClass = Site;
243
- /**
244
- * Find a site by its primary domain
245
- */
246
- async findByDomain(domain) {
247
- const results = await this.list({ where: { domain } });
248
- return results[0] ?? null;
249
- }
250
- /**
251
- * Find all sites belonging to a tenant
252
- */
253
- async findByTenant(tenantId2) {
254
- return this.list({ where: { tenantId: tenantId2 } });
255
- }
256
- /**
257
- * Find sites by lifecycle status
258
- */
259
- async findByStatus(status) {
260
- return this.list({ where: { status } });
261
- }
262
- /**
263
- * Find all active sites
264
- */
265
- async findActive() {
266
- return this.findByStatus("active");
267
- }
268
- }
269
- class SiteService {
270
- sites;
271
- bindings;
272
- constructor(options) {
273
- this.sites = options.sites;
274
- this.bindings = options.bindings;
275
- }
276
- /**
277
- * Create a new site in draft status
278
- */
279
- async createSite(tenantId2, data) {
280
- const site = await this.sites.create({
281
- tenantId: tenantId2,
282
- name: data.name,
283
- domain: data.domain,
284
- status: "draft",
285
- tier: data.tier ?? "free",
286
- databaseUrl: data.databaseUrl ?? "",
287
- databaseType: data.databaseType ?? "",
288
- portalConfig: JSON.stringify(data.portalConfig ?? {}),
289
- repositoryUrl: data.repositoryUrl ?? "",
290
- templateName: data.templateName ?? "",
291
- provisioningStatus: "pending",
292
- metadata: JSON.stringify(data.metadata ?? {})
293
- });
294
- await site.save();
295
- return site;
296
- }
297
- /**
298
- * Activate a site validates required fields then sets status to active
299
- */
300
- async activateSite(siteId) {
301
- const site = await this.requireSite(siteId);
302
- if (!site.name) {
303
- throw new Error("Cannot activate site: name is required");
304
- }
305
- if (!site.domain) {
306
- throw new Error("Cannot activate site: domain is required");
307
- }
308
- site.status = "active";
309
- site.updatedAt = /* @__PURE__ */ new Date();
310
- await site.save();
311
- return site;
312
- }
313
- /**
314
- * Suspend a site
315
- */
316
- async suspendSite(siteId) {
317
- const site = await this.requireSite(siteId);
318
- site.status = "suspended";
319
- site.updatedAt = /* @__PURE__ */ new Date();
320
- await site.save();
321
- return site;
322
- }
323
- /**
324
- * Archive a site
325
- */
326
- async archiveSite(siteId) {
327
- const site = await this.requireSite(siteId);
328
- site.status = "archived";
329
- site.updatedAt = /* @__PURE__ */ new Date();
330
- await site.save();
331
- return site;
332
- }
333
- /**
334
- * Mark site as provisioned and ready
335
- */
336
- async markProvisioned(siteId) {
337
- const site = await this.requireSite(siteId);
338
- site.provisioningStatus = "ready";
339
- site.provisionedAt = /* @__PURE__ */ new Date();
340
- site.provisioningError = "";
341
- site.updatedAt = /* @__PURE__ */ new Date();
342
- await site.save();
343
- return site;
344
- }
345
- /**
346
- * Mark site provisioning as failed
347
- */
348
- async markProvisioningFailed(siteId, error) {
349
- const site = await this.requireSite(siteId);
350
- site.provisioningStatus = "failed";
351
- site.provisioningError = error;
352
- site.updatedAt = /* @__PURE__ */ new Date();
353
- await site.save();
354
- return site;
355
- }
356
- /**
357
- * Bind an agent to a site
358
- */
359
- async bindAgent(siteId, agentClass, config) {
360
- const site = await this.requireSite(siteId);
361
- const existing = await this.bindings.findBySiteAndAgent(siteId, agentClass);
362
- if (existing) {
363
- existing.enabled = true;
364
- if (config !== void 0) existing.config = config;
365
- await existing.save();
366
- return existing;
367
- }
368
- const binding = await this.bindings.create({
369
- tenantId: site.tenantId,
370
- siteId,
371
- agentClass,
372
- enabled: true,
373
- config: config ?? null
374
- });
375
- await binding.save();
376
- return binding;
377
- }
378
- /**
379
- * Unbind an agent from a site
380
- */
381
- async unbindAgent(siteId, agentClass) {
382
- const binding = await this.bindings.findBySiteAndAgent(siteId, agentClass);
383
- if (binding) {
384
- await binding.delete();
385
- }
386
- }
387
- /**
388
- * Get all enabled agent bindings for a site
389
- */
390
- async getEnabledAgents(siteId) {
391
- return this.bindings.findEnabled(siteId);
392
- }
393
- /**
394
- * Load a site by ID, throwing if not found
395
- */
396
- async requireSite(siteId) {
397
- const site = await this.sites.get({ id: siteId });
398
- if (!site) {
399
- throw new Error(`Site '${siteId}' not found`);
400
- }
401
- return site;
402
- }
403
- }
404
- export {
405
- Site,
406
- SiteAgentBinding,
407
- SiteAgentBindingCollection,
408
- SiteCollection,
409
- SiteService
257
+ //#endregion
258
+ //#region src/services/SiteService.ts
259
+ var SiteService = class {
260
+ sites;
261
+ bindings;
262
+ constructor(options) {
263
+ this.sites = options.sites;
264
+ this.bindings = options.bindings;
265
+ }
266
+ /**
267
+ * Create a new site in draft status
268
+ */
269
+ async createSite(tenantId, data) {
270
+ const site = await this.sites.create({
271
+ tenantId,
272
+ name: data.name,
273
+ domain: data.domain,
274
+ status: "draft",
275
+ tier: data.tier ?? "free",
276
+ databaseUrl: data.databaseUrl ?? "",
277
+ databaseType: data.databaseType ?? "",
278
+ portalConfig: JSON.stringify(data.portalConfig ?? {}),
279
+ repositoryUrl: data.repositoryUrl ?? "",
280
+ templateName: data.templateName ?? "",
281
+ provisioningStatus: "pending",
282
+ metadata: JSON.stringify(data.metadata ?? {})
283
+ });
284
+ await site.save();
285
+ return site;
286
+ }
287
+ /**
288
+ * Activate a site — validates required fields then sets status to active
289
+ */
290
+ async activateSite(siteId) {
291
+ const site = await this.requireSite(siteId);
292
+ if (!site.name) throw new Error("Cannot activate site: name is required");
293
+ if (!site.domain) throw new Error("Cannot activate site: domain is required");
294
+ site.status = "active";
295
+ site.updatedAt = /* @__PURE__ */ new Date();
296
+ await site.save();
297
+ return site;
298
+ }
299
+ /**
300
+ * Suspend a site
301
+ */
302
+ async suspendSite(siteId) {
303
+ const site = await this.requireSite(siteId);
304
+ site.status = "suspended";
305
+ site.updatedAt = /* @__PURE__ */ new Date();
306
+ await site.save();
307
+ return site;
308
+ }
309
+ /**
310
+ * Archive a site
311
+ */
312
+ async archiveSite(siteId) {
313
+ const site = await this.requireSite(siteId);
314
+ site.status = "archived";
315
+ site.updatedAt = /* @__PURE__ */ new Date();
316
+ await site.save();
317
+ return site;
318
+ }
319
+ /**
320
+ * Mark site as provisioned and ready
321
+ */
322
+ async markProvisioned(siteId) {
323
+ const site = await this.requireSite(siteId);
324
+ site.provisioningStatus = "ready";
325
+ site.provisionedAt = /* @__PURE__ */ new Date();
326
+ site.provisioningError = "";
327
+ site.updatedAt = /* @__PURE__ */ new Date();
328
+ await site.save();
329
+ return site;
330
+ }
331
+ /**
332
+ * Mark site provisioning as failed
333
+ */
334
+ async markProvisioningFailed(siteId, error) {
335
+ const site = await this.requireSite(siteId);
336
+ site.provisioningStatus = "failed";
337
+ site.provisioningError = error;
338
+ site.updatedAt = /* @__PURE__ */ new Date();
339
+ await site.save();
340
+ return site;
341
+ }
342
+ /**
343
+ * Bind an agent to a site
344
+ */
345
+ async bindAgent(siteId, agentClass, config) {
346
+ const site = await this.requireSite(siteId);
347
+ const existing = await this.bindings.findBySiteAndAgent(siteId, agentClass);
348
+ if (existing) {
349
+ existing.enabled = true;
350
+ if (config !== void 0) existing.config = config;
351
+ await existing.save();
352
+ return existing;
353
+ }
354
+ const binding = await this.bindings.create({
355
+ tenantId: site.tenantId,
356
+ siteId,
357
+ agentClass,
358
+ enabled: true,
359
+ config: config ?? null
360
+ });
361
+ await binding.save();
362
+ return binding;
363
+ }
364
+ /**
365
+ * Unbind an agent from a site
366
+ */
367
+ async unbindAgent(siteId, agentClass) {
368
+ const binding = await this.bindings.findBySiteAndAgent(siteId, agentClass);
369
+ if (binding) await binding.delete();
370
+ }
371
+ /**
372
+ * Get all enabled agent bindings for a site
373
+ */
374
+ async getEnabledAgents(siteId) {
375
+ return this.bindings.findEnabled(siteId);
376
+ }
377
+ /**
378
+ * Load a site by ID, throwing if not found
379
+ */
380
+ async requireSite(siteId) {
381
+ const site = await this.sites.get({ id: siteId });
382
+ if (!site) throw new Error(`Site '${siteId}' not found`);
383
+ return site;
384
+ }
410
385
  };
411
- //# sourceMappingURL=index.js.map
386
+ //#endregion
387
+ export { Site, SiteAgentBinding, SiteAgentBindingCollection, SiteCollection, SiteService };
388
+
389
+ //# sourceMappingURL=index.js.map