@bonginkan/maria-lite 6.3.1 → 7.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.
- package/README.md +29 -2
- package/dist/cli.cjs +318 -460
- package/dist/ext.cjs +1 -1
- package/origin/index.meta.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
MARIA-LITE (
|
|
1
|
+
MARIA-LITE (v7.0.0)
|
|
2
2
|
===================
|
|
3
3
|
|
|
4
4
|
MARIA-LITE is a lightweight, standalone CLI build of MARIA OS focused on a smaller runtime surface while preserving API compatibility with `@bonginkan/maria`.
|
|
@@ -43,7 +43,7 @@ Notes:
|
|
|
43
43
|
- Clone commands write under `artifacts/<role>-clone/` when `--apply` (or implicit apply is enabled).
|
|
44
44
|
|
|
45
45
|
## Version
|
|
46
|
-
This package is published as `
|
|
46
|
+
This package is published as `7.0.0`.
|
|
47
47
|
|
|
48
48
|
## Extensions (Enterprise)
|
|
49
49
|
|
|
@@ -126,6 +126,33 @@ Append creator-provided knowledge to common context:
|
|
|
126
126
|
|
|
127
127
|
## Release Notes
|
|
128
128
|
|
|
129
|
+
### v7.0.0 (2026/03)
|
|
130
|
+
|
|
131
|
+
#### Features
|
|
132
|
+
|
|
133
|
+
- /vup now also bumps desktop build metadata for app/exe releases.
|
|
134
|
+
- /vup output includes clearer post-apply steps to commit, tag, and push.
|
|
135
|
+
|
|
136
|
+
#### Bug fixes
|
|
137
|
+
|
|
138
|
+
- Updated bundled knowledge pack catalogs to reflect new and rebalanced entries.
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
### v6.3.2 (2026/03)
|
|
143
|
+
|
|
144
|
+
#### Features
|
|
145
|
+
|
|
146
|
+
- Improved /gcal Admin resource management (buildings & rooms) output and handling.
|
|
147
|
+
- Enhanced /resource-manager with clearer tables and create flows for buildings/resources.
|
|
148
|
+
|
|
149
|
+
#### Bug fixes
|
|
150
|
+
|
|
151
|
+
- More consistent Google Admin API error reporting across /gcal and /resource-manager.
|
|
152
|
+
- Improved floor parsing for building creation (numeric counts or comma-separated).
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
129
156
|
### v6.3.1 (2026/03)
|
|
130
157
|
|
|
131
158
|
#### Features
|
package/dist/cli.cjs
CHANGED
|
@@ -97578,7 +97578,7 @@ function resolvePackageJsonNearEntrypoint() {
|
|
|
97578
97578
|
}
|
|
97579
97579
|
function resolveMariaLiteVersionInfo() {
|
|
97580
97580
|
const fallbackName = EXPECTED_PKG_NAME;
|
|
97581
|
-
const fallbackVersion = String(process.env.MARIA_LITE_VERSION || "").trim() || "
|
|
97581
|
+
const fallbackVersion = String(process.env.MARIA_LITE_VERSION || "").trim() || "7.0.0";
|
|
97582
97582
|
const near = resolvePackageJsonNearEntrypoint();
|
|
97583
97583
|
if (near) {
|
|
97584
97584
|
const name = fallbackName;
|
|
@@ -101169,6 +101169,7 @@ This command requires the repo scripts.` };
|
|
|
101169
101169
|
lines.push(entryPreview);
|
|
101170
101170
|
lines.push("");
|
|
101171
101171
|
lines.push("Tip: run with --apply to write changes.");
|
|
101172
|
+
lines.push("After --apply, commit + tag + push to trigger Tauri desktop build.");
|
|
101172
101173
|
return {
|
|
101173
101174
|
text: lines.join("\n").trim(),
|
|
101174
101175
|
json: wantsJson ? {
|
|
@@ -101211,8 +101212,13 @@ This command requires the repo scripts.` };
|
|
|
101211
101212
|
if (nextDataVersion) outLines.push(`nextData=${nextDataVersion}`);
|
|
101212
101213
|
outLines.push(`npmLatest=${npmLatest}`);
|
|
101213
101214
|
outLines.push(`npmGitHead=${baseSha}`);
|
|
101214
|
-
const updatedFiles = ["src-lite/package.json", "src-lite/package-lock.json", "src-lite/shared/version.ts", "src-lite/README.md", "src-lite/maria-lite-data/package.json"];
|
|
101215
|
+
const updatedFiles = ["src-lite/package.json", "src-lite/package-lock.json", "src-lite/shared/version.ts", "src-lite/README.md", "src-lite/maria-lite-data/package.json", "src-lite/src-tauri/tauri.conf.json", "src-lite/src-tauri/Cargo.toml"];
|
|
101215
101216
|
outLines.push(`updated=${updatedFiles.join(", ")}`);
|
|
101217
|
+
outLines.push("");
|
|
101218
|
+
outLines.push("Next steps:");
|
|
101219
|
+
outLines.push(` git add -A && git commit -m "v${nextVersion}"`);
|
|
101220
|
+
outLines.push(` git tag v${nextVersion}`);
|
|
101221
|
+
outLines.push(` git push && git push --tags # \u2192 triggers Tauri desktop build`);
|
|
101216
101222
|
return {
|
|
101217
101223
|
text: outLines.join("\n").trim(),
|
|
101218
101224
|
json: wantsJson ? {
|
|
@@ -256284,6 +256290,161 @@ var init_phone_routes = __esm({
|
|
|
256284
256290
|
}
|
|
256285
256291
|
});
|
|
256286
256292
|
|
|
256293
|
+
// services/google/admin-resources.ts
|
|
256294
|
+
async function adminFetch(token, url, init) {
|
|
256295
|
+
const headers = {
|
|
256296
|
+
Authorization: `Bearer ${token}`,
|
|
256297
|
+
...init?.headers || {}
|
|
256298
|
+
};
|
|
256299
|
+
return fetch(url, { ...init, headers });
|
|
256300
|
+
}
|
|
256301
|
+
function slugify2(name, prefix) {
|
|
256302
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40) || `${prefix}-${Date.now()}`;
|
|
256303
|
+
}
|
|
256304
|
+
function parseFloorNames(raw) {
|
|
256305
|
+
const trimmed = raw.trim();
|
|
256306
|
+
if (!trimmed) return [];
|
|
256307
|
+
const n = Number(trimmed);
|
|
256308
|
+
if (!isNaN(n) && n > 0 && Number.isInteger(n)) {
|
|
256309
|
+
return Array.from({ length: n }, (_, i2) => String(i2 + 1));
|
|
256310
|
+
}
|
|
256311
|
+
return trimmed.split(",").map((f3) => f3.trim()).filter(Boolean);
|
|
256312
|
+
}
|
|
256313
|
+
function toBuilding(raw) {
|
|
256314
|
+
return {
|
|
256315
|
+
buildingId: String(raw.buildingId || ""),
|
|
256316
|
+
buildingName: String(raw.buildingName || ""),
|
|
256317
|
+
description: String(raw.description || ""),
|
|
256318
|
+
floorNames: Array.isArray(raw.floorNames) ? raw.floorNames.map(String) : []
|
|
256319
|
+
};
|
|
256320
|
+
}
|
|
256321
|
+
function toResource(raw) {
|
|
256322
|
+
return {
|
|
256323
|
+
resourceId: String(raw.resourceId || ""),
|
|
256324
|
+
resourceEmail: String(raw.resourceEmail || ""),
|
|
256325
|
+
resourceName: String(raw.resourceName || ""),
|
|
256326
|
+
resourceType: String(raw.resourceType || ""),
|
|
256327
|
+
capacity: Number(raw.capacity || 0),
|
|
256328
|
+
buildingId: String(raw.buildingId || ""),
|
|
256329
|
+
floorName: String(raw.floorName || ""),
|
|
256330
|
+
userVisibleDescription: String(raw.userVisibleDescription || ""),
|
|
256331
|
+
resourceDescription: String(raw.resourceDescription || ""),
|
|
256332
|
+
generatedResourceName: String(raw.generatedResourceName || "")
|
|
256333
|
+
};
|
|
256334
|
+
}
|
|
256335
|
+
async function parseErrorText(res) {
|
|
256336
|
+
return res.text().catch(() => "");
|
|
256337
|
+
}
|
|
256338
|
+
function apiError(status, errText) {
|
|
256339
|
+
if (status === 403) return { ok: false, error: "permission_denied", status };
|
|
256340
|
+
if (status === 404) return { ok: false, error: "not_found", status };
|
|
256341
|
+
return { ok: false, error: `Admin SDK: ${status} ${errText.slice(0, 200)}`, status };
|
|
256342
|
+
}
|
|
256343
|
+
async function listBuildingsRaw(token, signal) {
|
|
256344
|
+
const res = await adminFetch(token, `${ADMIN_RESOURCES_BASE}/buildings?maxResults=500`, signal ? { signal } : void 0);
|
|
256345
|
+
if (!res.ok) return apiError(res.status, await parseErrorText(res));
|
|
256346
|
+
const data = await res.json();
|
|
256347
|
+
const items = Array.isArray(data.buildings) ? data.buildings : [];
|
|
256348
|
+
return { ok: true, data: items.map(toBuilding) };
|
|
256349
|
+
}
|
|
256350
|
+
async function createBuildingRaw(token, params, signal) {
|
|
256351
|
+
const buildingId = params.buildingId || slugify2(params.name, "bld");
|
|
256352
|
+
const body = { buildingId, buildingName: params.name };
|
|
256353
|
+
if (params.description) body.description = params.description;
|
|
256354
|
+
if (params.floorNames) {
|
|
256355
|
+
body.floorNames = params.floorNames;
|
|
256356
|
+
} else if (params.floors) {
|
|
256357
|
+
body.floorNames = parseFloorNames(params.floors);
|
|
256358
|
+
}
|
|
256359
|
+
const res = await adminFetch(token, `${ADMIN_RESOURCES_BASE}/buildings`, {
|
|
256360
|
+
method: "POST",
|
|
256361
|
+
headers: { "Content-Type": "application/json" },
|
|
256362
|
+
body: JSON.stringify(body),
|
|
256363
|
+
...signal ? { signal } : {}
|
|
256364
|
+
});
|
|
256365
|
+
if (!res.ok) return apiError(res.status, await parseErrorText(res));
|
|
256366
|
+
return { ok: true, data: toBuilding(await res.json()) };
|
|
256367
|
+
}
|
|
256368
|
+
async function updateBuildingRaw(token, buildingId, body, signal) {
|
|
256369
|
+
const res = await adminFetch(
|
|
256370
|
+
token,
|
|
256371
|
+
`${ADMIN_RESOURCES_BASE}/buildings/${encodeURIComponent(buildingId)}`,
|
|
256372
|
+
{ method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), ...signal ? { signal } : {} }
|
|
256373
|
+
);
|
|
256374
|
+
if (!res.ok) return apiError(res.status, await parseErrorText(res));
|
|
256375
|
+
return { ok: true, data: toBuilding(await res.json()) };
|
|
256376
|
+
}
|
|
256377
|
+
async function listResourcesRaw(token, opts, signal) {
|
|
256378
|
+
let url = `${ADMIN_RESOURCES_BASE}/calendars?maxResults=500`;
|
|
256379
|
+
if (opts?.buildingId) {
|
|
256380
|
+
url += `&query=buildingId="${encodeURIComponent(opts.buildingId)}"`;
|
|
256381
|
+
}
|
|
256382
|
+
const res = await adminFetch(token, url, signal ? { signal } : void 0);
|
|
256383
|
+
if (!res.ok) return apiError(res.status, await parseErrorText(res));
|
|
256384
|
+
const data = await res.json();
|
|
256385
|
+
let items = Array.isArray(data.items) ? data.items : [];
|
|
256386
|
+
if (opts?.capacity && opts.capacity > 0) {
|
|
256387
|
+
items = items.filter((r2) => Number(r2.capacity || 0) >= opts.capacity);
|
|
256388
|
+
}
|
|
256389
|
+
return { ok: true, data: items.map(toResource) };
|
|
256390
|
+
}
|
|
256391
|
+
async function getResourceRaw(token, resourceId, signal) {
|
|
256392
|
+
const res = await adminFetch(
|
|
256393
|
+
token,
|
|
256394
|
+
`${ADMIN_RESOURCES_BASE}/calendars/${encodeURIComponent(resourceId)}`,
|
|
256395
|
+
signal ? { signal } : void 0
|
|
256396
|
+
);
|
|
256397
|
+
if (!res.ok) return apiError(res.status, await parseErrorText(res));
|
|
256398
|
+
return { ok: true, data: toResource(await res.json()) };
|
|
256399
|
+
}
|
|
256400
|
+
async function createResourceRaw(token, params, signal) {
|
|
256401
|
+
const body = {
|
|
256402
|
+
resourceName: params.name,
|
|
256403
|
+
resourceType: params.resourceType || "CONFERENCE_ROOM"
|
|
256404
|
+
};
|
|
256405
|
+
if (params.resourceId) body.resourceId = params.resourceId;
|
|
256406
|
+
if (params.buildingId) body.buildingId = params.buildingId;
|
|
256407
|
+
if (params.capacity) body.capacity = params.capacity;
|
|
256408
|
+
if (params.floorName) body.floorName = params.floorName;
|
|
256409
|
+
if (params.description) body.resourceDescription = params.description;
|
|
256410
|
+
const res = await adminFetch(token, `${ADMIN_RESOURCES_BASE}/calendars`, {
|
|
256411
|
+
method: "POST",
|
|
256412
|
+
headers: { "Content-Type": "application/json" },
|
|
256413
|
+
body: JSON.stringify(body),
|
|
256414
|
+
...signal ? { signal } : {}
|
|
256415
|
+
});
|
|
256416
|
+
if (!res.ok) return apiError(res.status, await parseErrorText(res));
|
|
256417
|
+
return { ok: true, data: toResource(await res.json()) };
|
|
256418
|
+
}
|
|
256419
|
+
async function updateResourceRaw(token, resourceId, body, signal) {
|
|
256420
|
+
const res = await adminFetch(
|
|
256421
|
+
token,
|
|
256422
|
+
`${ADMIN_RESOURCES_BASE}/calendars/${encodeURIComponent(resourceId)}`,
|
|
256423
|
+
{ method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), ...signal ? { signal } : {} }
|
|
256424
|
+
);
|
|
256425
|
+
if (!res.ok) return apiError(res.status, await parseErrorText(res));
|
|
256426
|
+
return { ok: true, data: toResource(await res.json()) };
|
|
256427
|
+
}
|
|
256428
|
+
async function fetchExistingBuildingIds(token, signal) {
|
|
256429
|
+
const ids = /* @__PURE__ */ new Set();
|
|
256430
|
+
try {
|
|
256431
|
+
const result = await listBuildingsRaw(token, signal);
|
|
256432
|
+
if (result.ok && result.data) {
|
|
256433
|
+
for (const b of result.data) {
|
|
256434
|
+
if (b.buildingId) ids.add(b.buildingId);
|
|
256435
|
+
}
|
|
256436
|
+
}
|
|
256437
|
+
} catch {
|
|
256438
|
+
}
|
|
256439
|
+
return ids;
|
|
256440
|
+
}
|
|
256441
|
+
var ADMIN_RESOURCES_BASE;
|
|
256442
|
+
var init_admin_resources = __esm({
|
|
256443
|
+
"services/google/admin-resources.ts"() {
|
|
256444
|
+
ADMIN_RESOURCES_BASE = "https://admin.googleapis.com/admin/directory/v1/customer/my_customer/resources";
|
|
256445
|
+
}
|
|
256446
|
+
});
|
|
256447
|
+
|
|
256287
256448
|
// services/desktop/routes/calendar-api-routes.ts
|
|
256288
256449
|
async function getToken2() {
|
|
256289
256450
|
const mgr = new GoogleOAuthManager();
|
|
@@ -256293,13 +256454,6 @@ function notConnected2(res) {
|
|
|
256293
256454
|
respondJson2(res, 200, { ok: false, error: "not_connected" });
|
|
256294
256455
|
return true;
|
|
256295
256456
|
}
|
|
256296
|
-
async function gFetch2(token, url, init) {
|
|
256297
|
-
const headers = {
|
|
256298
|
-
Authorization: `Bearer ${token}`,
|
|
256299
|
-
...init?.headers || {}
|
|
256300
|
-
};
|
|
256301
|
-
return fetch(url, { ...init, headers });
|
|
256302
|
-
}
|
|
256303
256457
|
function resolveProjectId2() {
|
|
256304
256458
|
return process.env.GCLOUD_PROJECT || process.env.GOOGLE_CLOUD_PROJECT || process.env.FIREBASE_PROJECT_ID || process.env.GCP_PROJECT_ID || "";
|
|
256305
256459
|
}
|
|
@@ -256357,28 +256511,9 @@ function buildRrule(type2, count, until) {
|
|
|
256357
256511
|
return rule;
|
|
256358
256512
|
}
|
|
256359
256513
|
async function fetchResources(token, buildingId, minCapacity) {
|
|
256360
|
-
|
|
256361
|
-
if (
|
|
256362
|
-
|
|
256363
|
-
}
|
|
256364
|
-
const apiRes = await gFetch2(token, url);
|
|
256365
|
-
if (!apiRes.ok) return [];
|
|
256366
|
-
const data = await apiRes.json();
|
|
256367
|
-
const items = Array.isArray(data.items) ? data.items : [];
|
|
256368
|
-
const resources = items.map((item) => ({
|
|
256369
|
-
resourceId: String(item.resourceId || ""),
|
|
256370
|
-
resourceEmail: String(item.resourceEmail || ""),
|
|
256371
|
-
resourceName: String(item.resourceName || ""),
|
|
256372
|
-
resourceType: String(item.resourceType || ""),
|
|
256373
|
-
capacity: Number(item.capacity || 0),
|
|
256374
|
-
buildingId: String(item.buildingId || ""),
|
|
256375
|
-
floorName: String(item.floorName || ""),
|
|
256376
|
-
userVisibleDescription: String(item.userVisibleDescription || "")
|
|
256377
|
-
}));
|
|
256378
|
-
if (minCapacity != null && minCapacity > 0) {
|
|
256379
|
-
return resources.filter((r2) => r2.capacity >= minCapacity);
|
|
256380
|
-
}
|
|
256381
|
-
return resources;
|
|
256514
|
+
const result = await listResourcesRaw(token, { buildingId, capacity: minCapacity });
|
|
256515
|
+
if (!result.ok || !result.data) return [];
|
|
256516
|
+
return result.data;
|
|
256382
256517
|
}
|
|
256383
256518
|
function findSlots(params) {
|
|
256384
256519
|
const {
|
|
@@ -256538,19 +256673,9 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256538
256673
|
if (method === "GET" && pathname === "/api/calendar/buildings") {
|
|
256539
256674
|
const token = await getToken2();
|
|
256540
256675
|
if (!token) return notConnected2(res);
|
|
256541
|
-
const
|
|
256542
|
-
if (!
|
|
256543
|
-
|
|
256544
|
-
}
|
|
256545
|
-
const data = await apiRes.json();
|
|
256546
|
-
const items = Array.isArray(data.buildings) ? data.buildings : [];
|
|
256547
|
-
const buildings = items.map((b) => ({
|
|
256548
|
-
buildingId: String(b.buildingId || ""),
|
|
256549
|
-
buildingName: String(b.buildingName || ""),
|
|
256550
|
-
description: String(b.description || ""),
|
|
256551
|
-
floorNames: Array.isArray(b.floorNames) ? b.floorNames : []
|
|
256552
|
-
}));
|
|
256553
|
-
return respondJson2(res, 200, { ok: true, buildings }), true;
|
|
256676
|
+
const result = await listBuildingsRaw(token);
|
|
256677
|
+
if (!result.ok) return respondJson2(res, 200, { ok: false, error: result.error }), true;
|
|
256678
|
+
return respondJson2(res, 200, { ok: true, buildings: result.data }), true;
|
|
256554
256679
|
}
|
|
256555
256680
|
if (method === "POST" && pathname === "/api/calendar/buildings") {
|
|
256556
256681
|
const token = await getToken2();
|
|
@@ -256559,44 +256684,21 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256559
256684
|
if (!reqBody) return respondJson2(res, 400, { ok: false, error: "Request body is required" }), true;
|
|
256560
256685
|
const buildingName = String(reqBody.buildingName || "").trim();
|
|
256561
256686
|
if (!buildingName) return respondJson2(res, 400, { ok: false, error: "buildingName is required" }), true;
|
|
256562
|
-
const buildingId = String(reqBody.buildingId || "").trim() || buildingName
|
|
256563
|
-
const
|
|
256564
|
-
|
|
256565
|
-
|
|
256566
|
-
|
|
256567
|
-
|
|
256568
|
-
|
|
256569
|
-
|
|
256570
|
-
|
|
256571
|
-
if (!isNaN(n) && n > 0 && Number.isInteger(n)) {
|
|
256572
|
-
body.floorNames = Array.from({ length: n }, (_, i2) => String(i2 + 1));
|
|
256573
|
-
} else {
|
|
256574
|
-
body.floorNames = raw.split(",").map((f3) => f3.trim()).filter(Boolean);
|
|
256575
|
-
}
|
|
256576
|
-
}
|
|
256577
|
-
}
|
|
256578
|
-
const apiRes = await gFetch2(token, `${ADMIN_RESOURCES_BASE}/buildings`, {
|
|
256579
|
-
method: "POST",
|
|
256580
|
-
headers: { "Content-Type": "application/json" },
|
|
256581
|
-
body: JSON.stringify(body)
|
|
256687
|
+
const buildingId = String(reqBody.buildingId || "").trim() || slugify2(buildingName, "bld");
|
|
256688
|
+
const floorNames = reqBody.floorNames ? Array.isArray(reqBody.floorNames) ? reqBody.floorNames.map(String) : void 0 : void 0;
|
|
256689
|
+
const floors = !floorNames && reqBody.floorNames ? String(reqBody.floorNames).trim() : void 0;
|
|
256690
|
+
const result = await createBuildingRaw(token, {
|
|
256691
|
+
name: buildingName,
|
|
256692
|
+
buildingId,
|
|
256693
|
+
description: reqBody.description ? String(reqBody.description).trim() : void 0,
|
|
256694
|
+
floorNames: floorNames || void 0,
|
|
256695
|
+
floors: floors || void 0
|
|
256582
256696
|
});
|
|
256583
|
-
if (!
|
|
256584
|
-
|
|
256585
|
-
|
|
256586
|
-
return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256587
|
-
}
|
|
256588
|
-
return respondJson2(res, 200, { ok: false, error: `Admin SDK: ${apiRes.status} ${errText}` }), true;
|
|
256697
|
+
if (!result.ok) {
|
|
256698
|
+
if (result.status === 403) return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256699
|
+
return respondJson2(res, 200, { ok: false, error: result.error }), true;
|
|
256589
256700
|
}
|
|
256590
|
-
|
|
256591
|
-
return respondJson2(res, 200, {
|
|
256592
|
-
ok: true,
|
|
256593
|
-
building: {
|
|
256594
|
-
buildingId: String(created.buildingId || ""),
|
|
256595
|
-
buildingName: String(created.buildingName || ""),
|
|
256596
|
-
description: String(created.description || ""),
|
|
256597
|
-
floorNames: Array.isArray(created.floorNames) ? created.floorNames : []
|
|
256598
|
-
}
|
|
256599
|
-
}), true;
|
|
256701
|
+
return respondJson2(res, 200, { ok: true, building: result.data }), true;
|
|
256600
256702
|
}
|
|
256601
256703
|
if (method === "POST" && pathname === "/api/calendar/resources") {
|
|
256602
256704
|
const token = await getToken2();
|
|
@@ -256605,41 +256707,21 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256605
256707
|
if (!reqBody) return respondJson2(res, 400, { ok: false, error: "Request body is required" }), true;
|
|
256606
256708
|
const resourceName = String(reqBody.resourceName || "").trim();
|
|
256607
256709
|
if (!resourceName) return respondJson2(res, 400, { ok: false, error: "resourceName is required" }), true;
|
|
256608
|
-
const resourceId = String(reqBody.resourceId || "").trim() || resourceName
|
|
256609
|
-
const
|
|
256710
|
+
const resourceId = String(reqBody.resourceId || "").trim() || slugify2(resourceName, "res");
|
|
256711
|
+
const result = await createResourceRaw(token, {
|
|
256712
|
+
name: resourceName,
|
|
256610
256713
|
resourceId,
|
|
256611
|
-
|
|
256612
|
-
|
|
256613
|
-
|
|
256614
|
-
|
|
256615
|
-
|
|
256616
|
-
if (reqBody.floorName) body.floorName = String(reqBody.floorName).trim();
|
|
256617
|
-
if (reqBody.resourceDescription) body.resourceDescription = String(reqBody.resourceDescription).trim();
|
|
256618
|
-
const apiRes = await gFetch2(token, `${ADMIN_RESOURCES_BASE}/calendars`, {
|
|
256619
|
-
method: "POST",
|
|
256620
|
-
headers: { "Content-Type": "application/json" },
|
|
256621
|
-
body: JSON.stringify(body)
|
|
256714
|
+
buildingId: reqBody.buildingId ? String(reqBody.buildingId).trim() : void 0,
|
|
256715
|
+
capacity: reqBody.capacity ? Math.max(0, Number(reqBody.capacity) || 0) : void 0,
|
|
256716
|
+
resourceType: String(reqBody.resourceType || "CONFERENCE_ROOM").trim(),
|
|
256717
|
+
floorName: reqBody.floorName ? String(reqBody.floorName).trim() : void 0,
|
|
256718
|
+
description: reqBody.resourceDescription ? String(reqBody.resourceDescription).trim() : void 0
|
|
256622
256719
|
});
|
|
256623
|
-
if (!
|
|
256624
|
-
|
|
256625
|
-
|
|
256626
|
-
return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256627
|
-
}
|
|
256628
|
-
return respondJson2(res, 200, { ok: false, error: `Admin SDK: ${apiRes.status} ${errText}` }), true;
|
|
256720
|
+
if (!result.ok) {
|
|
256721
|
+
if (result.status === 403) return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256722
|
+
return respondJson2(res, 200, { ok: false, error: result.error }), true;
|
|
256629
256723
|
}
|
|
256630
|
-
|
|
256631
|
-
return respondJson2(res, 200, {
|
|
256632
|
-
ok: true,
|
|
256633
|
-
resource: {
|
|
256634
|
-
resourceId: String(created.resourceId || ""),
|
|
256635
|
-
resourceEmail: String(created.resourceEmail || ""),
|
|
256636
|
-
resourceName: String(created.resourceName || ""),
|
|
256637
|
-
capacity: Number(created.capacity || 0),
|
|
256638
|
-
buildingId: String(created.buildingId || ""),
|
|
256639
|
-
resourceType: String(created.resourceType || ""),
|
|
256640
|
-
floorName: String(created.floorName || "")
|
|
256641
|
-
}
|
|
256642
|
-
}), true;
|
|
256724
|
+
return respondJson2(res, 200, { ok: true, resource: result.data }), true;
|
|
256643
256725
|
}
|
|
256644
256726
|
if (method === "PATCH" && pathname.startsWith("/api/calendar/buildings/")) {
|
|
256645
256727
|
const buildingId = decodeURIComponent(pathname.slice("/api/calendar/buildings/".length));
|
|
@@ -256667,31 +256749,13 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256667
256749
|
if (Object.keys(body).length === 0) {
|
|
256668
256750
|
return respondJson2(res, 400, { ok: false, error: "No fields to update" }), true;
|
|
256669
256751
|
}
|
|
256670
|
-
const
|
|
256671
|
-
|
|
256672
|
-
|
|
256673
|
-
|
|
256674
|
-
|
|
256675
|
-
if (!apiRes.ok) {
|
|
256676
|
-
const errText = await apiRes.text().catch(() => "");
|
|
256677
|
-
if (apiRes.status === 403) {
|
|
256678
|
-
return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256679
|
-
}
|
|
256680
|
-
if (apiRes.status === 404) {
|
|
256681
|
-
return respondJson2(res, 404, { ok: false, error: "Building not found" }), true;
|
|
256682
|
-
}
|
|
256683
|
-
return respondJson2(res, 200, { ok: false, error: `Admin SDK: ${apiRes.status} ${errText}` }), true;
|
|
256752
|
+
const result = await updateBuildingRaw(token, buildingId, body);
|
|
256753
|
+
if (!result.ok) {
|
|
256754
|
+
if (result.status === 403) return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256755
|
+
if (result.status === 404) return respondJson2(res, 404, { ok: false, error: "Building not found" }), true;
|
|
256756
|
+
return respondJson2(res, 200, { ok: false, error: result.error }), true;
|
|
256684
256757
|
}
|
|
256685
|
-
|
|
256686
|
-
return respondJson2(res, 200, {
|
|
256687
|
-
ok: true,
|
|
256688
|
-
building: {
|
|
256689
|
-
buildingId: String(updated.buildingId || ""),
|
|
256690
|
-
buildingName: String(updated.buildingName || ""),
|
|
256691
|
-
description: String(updated.description || ""),
|
|
256692
|
-
floorNames: Array.isArray(updated.floorNames) ? updated.floorNames : []
|
|
256693
|
-
}
|
|
256694
|
-
}), true;
|
|
256758
|
+
return respondJson2(res, 200, { ok: true, building: result.data }), true;
|
|
256695
256759
|
}
|
|
256696
256760
|
if (method === "PATCH" && pathname.startsWith("/api/calendar/resources/")) {
|
|
256697
256761
|
const resourceId = decodeURIComponent(pathname.slice("/api/calendar/resources/".length));
|
|
@@ -256710,34 +256774,13 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256710
256774
|
if (Object.keys(body).length === 0) {
|
|
256711
256775
|
return respondJson2(res, 400, { ok: false, error: "No fields to update" }), true;
|
|
256712
256776
|
}
|
|
256713
|
-
const
|
|
256714
|
-
|
|
256715
|
-
|
|
256716
|
-
|
|
256717
|
-
|
|
256718
|
-
if (!apiRes.ok) {
|
|
256719
|
-
const errText = await apiRes.text().catch(() => "");
|
|
256720
|
-
if (apiRes.status === 403) {
|
|
256721
|
-
return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256722
|
-
}
|
|
256723
|
-
if (apiRes.status === 404) {
|
|
256724
|
-
return respondJson2(res, 404, { ok: false, error: "Resource not found" }), true;
|
|
256725
|
-
}
|
|
256726
|
-
return respondJson2(res, 200, { ok: false, error: `Admin SDK: ${apiRes.status} ${errText}` }), true;
|
|
256777
|
+
const result = await updateResourceRaw(token, resourceId, body);
|
|
256778
|
+
if (!result.ok) {
|
|
256779
|
+
if (result.status === 403) return respondJson2(res, 403, { ok: false, error: "permission_denied", message: "Google Workspace admin privileges required" }), true;
|
|
256780
|
+
if (result.status === 404) return respondJson2(res, 404, { ok: false, error: "Resource not found" }), true;
|
|
256781
|
+
return respondJson2(res, 200, { ok: false, error: result.error }), true;
|
|
256727
256782
|
}
|
|
256728
|
-
|
|
256729
|
-
return respondJson2(res, 200, {
|
|
256730
|
-
ok: true,
|
|
256731
|
-
resource: {
|
|
256732
|
-
resourceId: String(updated.resourceId || ""),
|
|
256733
|
-
resourceEmail: String(updated.resourceEmail || ""),
|
|
256734
|
-
resourceName: String(updated.resourceName || ""),
|
|
256735
|
-
capacity: Number(updated.capacity || 0),
|
|
256736
|
-
buildingId: String(updated.buildingId || ""),
|
|
256737
|
-
resourceType: String(updated.resourceType || ""),
|
|
256738
|
-
floorName: String(updated.floorName || "")
|
|
256739
|
-
}
|
|
256740
|
-
}), true;
|
|
256783
|
+
return respondJson2(res, 200, { ok: true, resource: result.data }), true;
|
|
256741
256784
|
}
|
|
256742
256785
|
if (method === "POST" && pathname === "/api/calendar/slots") {
|
|
256743
256786
|
const token = await getToken2();
|
|
@@ -256788,7 +256831,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256788
256831
|
timeZone: tz,
|
|
256789
256832
|
items: allTargets.map((e2) => ({ id: e2 }))
|
|
256790
256833
|
};
|
|
256791
|
-
const fbRes = await
|
|
256834
|
+
const fbRes = await adminFetch(token, `${CALENDAR_API_BASE}/freeBusy`, {
|
|
256792
256835
|
method: "POST",
|
|
256793
256836
|
headers: { "Content-Type": "application/json" },
|
|
256794
256837
|
body: JSON.stringify(fbBody)
|
|
@@ -256864,7 +256907,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256864
256907
|
timeZone: tz,
|
|
256865
256908
|
items: targets.map((e2) => ({ id: e2 }))
|
|
256866
256909
|
};
|
|
256867
|
-
const fbRes = await
|
|
256910
|
+
const fbRes = await adminFetch(token, `${CALENDAR_API_BASE}/freeBusy`, {
|
|
256868
256911
|
method: "POST",
|
|
256869
256912
|
headers: { "Content-Type": "application/json" },
|
|
256870
256913
|
body: JSON.stringify(fbBody)
|
|
@@ -256926,7 +256969,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256926
256969
|
timeZone: DEFAULT_TIMEZONE,
|
|
256927
256970
|
items: [{ id: calendarId }]
|
|
256928
256971
|
};
|
|
256929
|
-
const fbRes = await
|
|
256972
|
+
const fbRes = await adminFetch(token, `${CALENDAR_API_BASE}/freeBusy`, {
|
|
256930
256973
|
method: "POST",
|
|
256931
256974
|
headers: { "Content-Type": "application/json" },
|
|
256932
256975
|
body: JSON.stringify(fbBody)
|
|
@@ -256968,7 +257011,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
256968
257011
|
if (rrule) {
|
|
256969
257012
|
eventBody.recurrence = [rrule];
|
|
256970
257013
|
}
|
|
256971
|
-
const createRes = await
|
|
257014
|
+
const createRes = await adminFetch(
|
|
256972
257015
|
token,
|
|
256973
257016
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events`,
|
|
256974
257017
|
{
|
|
@@ -257043,7 +257086,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257043
257086
|
const msg = err instanceof Error ? err.message : String(err);
|
|
257044
257087
|
if (calendarEventId) {
|
|
257045
257088
|
try {
|
|
257046
|
-
await
|
|
257089
|
+
await adminFetch(
|
|
257047
257090
|
token,
|
|
257048
257091
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(calendarEventId)}`,
|
|
257049
257092
|
{ method: "DELETE" }
|
|
@@ -257100,7 +257143,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257100
257143
|
if (!token) return notConnected2(res);
|
|
257101
257144
|
const calendarId = String(data.resourceCalendarId || "") || "primary";
|
|
257102
257145
|
const eventId = String(data.calendarEventId);
|
|
257103
|
-
const instancesRes = await
|
|
257146
|
+
const instancesRes = await adminFetch(
|
|
257104
257147
|
token,
|
|
257105
257148
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(eventId)}/instances?maxResults=50`
|
|
257106
257149
|
);
|
|
@@ -257150,7 +257193,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257150
257193
|
}
|
|
257151
257194
|
const upsertToken = await getToken2();
|
|
257152
257195
|
if (!upsertToken) return notConnected2(res);
|
|
257153
|
-
const eventRes = await
|
|
257196
|
+
const eventRes = await adminFetch(
|
|
257154
257197
|
upsertToken,
|
|
257155
257198
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarIdForUpsert)}/events/${encodeURIComponent(gcalEventId)}`
|
|
257156
257199
|
);
|
|
@@ -257203,7 +257246,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257203
257246
|
timeZone: DEFAULT_TIMEZONE,
|
|
257204
257247
|
items: [{ id: calendarId }]
|
|
257205
257248
|
};
|
|
257206
|
-
const fbRes = await
|
|
257249
|
+
const fbRes = await adminFetch(token, `${CALENDAR_API_BASE}/freeBusy`, {
|
|
257207
257250
|
method: "POST",
|
|
257208
257251
|
headers: { "Content-Type": "application/json" },
|
|
257209
257252
|
body: JSON.stringify(fbBody)
|
|
@@ -257250,7 +257293,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257250
257293
|
if (resourceEmail && resourceEmail !== String(data.resourceCalendarId || "")) {
|
|
257251
257294
|
patchBody.attendees = [{ email: resourceEmail, resource: true }];
|
|
257252
257295
|
}
|
|
257253
|
-
const patchRes = await
|
|
257296
|
+
const patchRes = await adminFetch(
|
|
257254
257297
|
token,
|
|
257255
257298
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(calendarEventId)}`,
|
|
257256
257299
|
{ method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(patchBody) }
|
|
@@ -257303,7 +257346,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257303
257346
|
}
|
|
257304
257347
|
const upsertToken = await getToken2();
|
|
257305
257348
|
if (!upsertToken) return notConnected2(res);
|
|
257306
|
-
const eventRes = await
|
|
257349
|
+
const eventRes = await adminFetch(
|
|
257307
257350
|
upsertToken,
|
|
257308
257351
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(gcalCalendarId)}/events/${encodeURIComponent(gcalEventId)}`
|
|
257309
257352
|
);
|
|
@@ -257355,7 +257398,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257355
257398
|
}
|
|
257356
257399
|
if (token) {
|
|
257357
257400
|
try {
|
|
257358
|
-
await
|
|
257401
|
+
await adminFetch(
|
|
257359
257402
|
token,
|
|
257360
257403
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(instanceEventId)}`,
|
|
257361
257404
|
{ method: "DELETE" }
|
|
@@ -257379,7 +257422,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257379
257422
|
}
|
|
257380
257423
|
if (token && calendarEventId) {
|
|
257381
257424
|
try {
|
|
257382
|
-
const instanceRes = await
|
|
257425
|
+
const instanceRes = await adminFetch(
|
|
257383
257426
|
token,
|
|
257384
257427
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(instanceEventId)}`
|
|
257385
257428
|
);
|
|
@@ -257390,7 +257433,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257390
257433
|
const cutoffDate = new Date(instanceStart);
|
|
257391
257434
|
cutoffDate.setDate(cutoffDate.getDate() - 1);
|
|
257392
257435
|
const untilStr = cutoffDate.toISOString().replace(/[-:]/g, "").split(".")[0] + "Z";
|
|
257393
|
-
const parentRes = await
|
|
257436
|
+
const parentRes = await adminFetch(
|
|
257394
257437
|
token,
|
|
257395
257438
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(calendarEventId)}`
|
|
257396
257439
|
);
|
|
@@ -257404,7 +257447,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257404
257447
|
);
|
|
257405
257448
|
return [...parts, `UNTIL=${untilStr}`].join(";");
|
|
257406
257449
|
});
|
|
257407
|
-
await
|
|
257450
|
+
await adminFetch(
|
|
257408
257451
|
token,
|
|
257409
257452
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(calendarEventId)}`,
|
|
257410
257453
|
{
|
|
@@ -257436,7 +257479,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257436
257479
|
} else {
|
|
257437
257480
|
if (calendarEventId && token) {
|
|
257438
257481
|
try {
|
|
257439
|
-
await
|
|
257482
|
+
await adminFetch(
|
|
257440
257483
|
token,
|
|
257441
257484
|
`${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events/${encodeURIComponent(calendarEventId)}`,
|
|
257442
257485
|
{ method: "DELETE" }
|
|
@@ -257581,7 +257624,7 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257581
257624
|
try {
|
|
257582
257625
|
const calendarFetches = Array.from(byCalendar.keys()).map(async (calendarId) => {
|
|
257583
257626
|
const eventsUrl = `${CALENDAR_API_BASE}/calendars/${encodeURIComponent(calendarId)}/events?timeMin=${encodeURIComponent(timeMin)}&timeMax=${encodeURIComponent(timeMax)}&singleEvents=true&orderBy=startTime&maxResults=250`;
|
|
257584
|
-
const eventsRes = await
|
|
257627
|
+
const eventsRes = await adminFetch(token, eventsUrl);
|
|
257585
257628
|
if (!eventsRes.ok) {
|
|
257586
257629
|
console.warn(
|
|
257587
257630
|
`GCal events.list failed for calendar ${calendarId}: ${eventsRes.status}`
|
|
@@ -257748,13 +257791,13 @@ async function handleCalendarApiRoute(method, pathname, req, res) {
|
|
|
257748
257791
|
}
|
|
257749
257792
|
return false;
|
|
257750
257793
|
}
|
|
257751
|
-
var
|
|
257794
|
+
var CALENDAR_API_BASE, DEFAULT_WORK_START_HOUR, DEFAULT_WORK_END_HOUR, DEFAULT_DURATION_MINUTES, DEFAULT_RESERVATION_LIMIT, SLOT_STEP_MS, DEFAULT_BUFFER_MINUTES, TOP_SLOT_COUNT, DEFAULT_TIMEZONE, _firestoreInstance2, _firestoreInitPromise2, VALID_RECURRENCE_TYPES;
|
|
257752
257795
|
var init_calendar_api_routes = __esm({
|
|
257753
257796
|
"services/desktop/routes/calendar-api-routes.ts"() {
|
|
257754
257797
|
init_desktop_server_helpers();
|
|
257755
257798
|
init_google_oauth();
|
|
257756
257799
|
init_date_tz();
|
|
257757
|
-
|
|
257800
|
+
init_admin_resources();
|
|
257758
257801
|
CALENDAR_API_BASE = "https://www.googleapis.com/calendar/v3";
|
|
257759
257802
|
DEFAULT_WORK_START_HOUR = 9;
|
|
257760
257803
|
DEFAULT_WORK_END_HOUR = 18;
|
|
@@ -263703,12 +263746,8 @@ async function findMeetingSlots(token, required, optional, durationMin, dateFrom
|
|
|
263703
263746
|
if (extra?.resourceId) {
|
|
263704
263747
|
resourceCalendarIds = [extra.resourceId];
|
|
263705
263748
|
try {
|
|
263706
|
-
const adminBaseUrl = "https://admin.googleapis.com/admin/directory/v1/customer/my_customer/resources/calendars";
|
|
263707
263749
|
const qParams = new URLSearchParams({ maxResults: "5", query: `resourceEmail="${extra.resourceId}"` });
|
|
263708
|
-
const rRes = await
|
|
263709
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
263710
|
-
...signal ? { signal } : {}
|
|
263711
|
-
});
|
|
263750
|
+
const rRes = await adminFetch(token, `${ADMIN_RESOURCES_BASE}/calendars?${qParams}`, signal ? { signal } : void 0);
|
|
263712
263751
|
if (rRes.ok) {
|
|
263713
263752
|
const rData = await rRes.json();
|
|
263714
263753
|
const items = Array.isArray(rData.items) ? rData.items : [];
|
|
@@ -263722,25 +263761,12 @@ async function findMeetingSlots(token, required, optional, durationMin, dateFrom
|
|
|
263722
263761
|
}
|
|
263723
263762
|
} else if (extra?.buildingId || extra?.capacity) {
|
|
263724
263763
|
try {
|
|
263725
|
-
const
|
|
263726
|
-
|
|
263727
|
-
|
|
263728
|
-
|
|
263729
|
-
|
|
263730
|
-
|
|
263731
|
-
});
|
|
263732
|
-
if (rRes.ok) {
|
|
263733
|
-
const rData = await rRes.json();
|
|
263734
|
-
const items = Array.isArray(rData.items) ? rData.items : [];
|
|
263735
|
-
const filtered = items.filter((r2) => {
|
|
263736
|
-
if (extra?.capacity && typeof r2.capacity === "number" && r2.capacity < extra.capacity) return false;
|
|
263737
|
-
return true;
|
|
263738
|
-
});
|
|
263739
|
-
resourceCalendarIds = filtered.map((r2) => String(r2.resourceEmail || "")).filter(Boolean);
|
|
263740
|
-
for (const r2 of items) {
|
|
263741
|
-
const email = String(r2.resourceEmail || "");
|
|
263742
|
-
const name = String(r2.resourceName || r2.generatedResourceName || "");
|
|
263743
|
-
if (email && name) resourceNameMap[email] = name;
|
|
263764
|
+
const result = await listResourcesRaw(token, { buildingId: extra?.buildingId, capacity: extra?.capacity }, signal);
|
|
263765
|
+
if (result.ok && result.data) {
|
|
263766
|
+
resourceCalendarIds = result.data.map((r2) => r2.resourceEmail).filter(Boolean);
|
|
263767
|
+
for (const r2 of result.data) {
|
|
263768
|
+
const name = r2.resourceName || r2.generatedResourceName || "";
|
|
263769
|
+
if (r2.resourceEmail && name) resourceNameMap[r2.resourceEmail] = name;
|
|
263744
263770
|
}
|
|
263745
263771
|
}
|
|
263746
263772
|
} catch {
|
|
@@ -264122,46 +264148,17 @@ function formatImportSummary(results, totalRecords, isDryRun) {
|
|
|
264122
264148
|
}
|
|
264123
264149
|
return lines;
|
|
264124
264150
|
}
|
|
264125
|
-
async function
|
|
264126
|
-
const
|
|
264127
|
-
|
|
264128
|
-
|
|
264129
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
264130
|
-
...signal ? { signal } : {}
|
|
264131
|
-
});
|
|
264132
|
-
if (res.ok) {
|
|
264133
|
-
const data = await res.json();
|
|
264134
|
-
const buildings = Array.isArray(data.buildings) ? data.buildings : [];
|
|
264135
|
-
for (const b of buildings) {
|
|
264136
|
-
if (typeof b.buildingId === "string" && b.buildingId) {
|
|
264137
|
-
ids.add(b.buildingId);
|
|
264138
|
-
}
|
|
264139
|
-
}
|
|
264140
|
-
}
|
|
264141
|
-
} catch {
|
|
264142
|
-
}
|
|
264143
|
-
return ids;
|
|
264144
|
-
}
|
|
264145
|
-
async function listResources(token, buildingId, signal) {
|
|
264146
|
-
const params = new URLSearchParams({ maxResults: "200" });
|
|
264147
|
-
if (buildingId) params.set("query", `buildingId="${buildingId}"`);
|
|
264148
|
-
const res = await fetch(`${ADMIN_RESOURCES_BASE2}/calendars?${params}`, {
|
|
264149
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
264150
|
-
...signal ? { signal } : {}
|
|
264151
|
-
});
|
|
264152
|
-
if (!res.ok) {
|
|
264153
|
-
const err = await res.text().catch(() => "");
|
|
264154
|
-
return { text: `Admin API error: ${res.status} ${err.slice(0, 200)}`, json: { ok: false, error: res.status } };
|
|
264155
|
-
}
|
|
264156
|
-
const data = await res.json();
|
|
264157
|
-
const items = Array.isArray(data.items) ? data.items : [];
|
|
264151
|
+
async function fmtListResources(token, buildingId, signal) {
|
|
264152
|
+
const result = await listResourcesRaw(token, { buildingId }, signal);
|
|
264153
|
+
if (!result.ok) return { text: `Admin API error: ${result.error}`, json: { ok: false, error: result.error } };
|
|
264154
|
+
const items = result.data;
|
|
264158
264155
|
if (items.length === 0) {
|
|
264159
264156
|
const filter = buildingId ? ` (building: ${buildingId})` : "";
|
|
264160
264157
|
return { text: `No resource calendars found${filter}.`, json: { ok: true, resources: [] } };
|
|
264161
264158
|
}
|
|
264162
264159
|
const lines = [`${items.length} resource calendar(s):`, ""];
|
|
264163
264160
|
for (const r2 of items) {
|
|
264164
|
-
const cap =
|
|
264161
|
+
const cap = r2.capacity ? ` (capacity: ${r2.capacity})` : "";
|
|
264165
264162
|
const bld = r2.buildingId ? ` [building: ${r2.buildingId}]` : "";
|
|
264166
264163
|
lines.push(` ${r2.resourceName || r2.generatedResourceName || "Unnamed"}${cap}${bld}`);
|
|
264167
264164
|
lines.push(` ID: ${r2.resourceId}`);
|
|
@@ -264172,22 +264169,16 @@ async function listResources(token, buildingId, signal) {
|
|
|
264172
264169
|
}
|
|
264173
264170
|
return { text: lines.join("\n"), json: { ok: true, resources: items } };
|
|
264174
264171
|
}
|
|
264175
|
-
async function
|
|
264176
|
-
const
|
|
264177
|
-
|
|
264178
|
-
|
|
264179
|
-
});
|
|
264180
|
-
if (!res.ok) {
|
|
264181
|
-
const err = await res.text().catch(() => "");
|
|
264182
|
-
return { text: `Admin API error: ${res.status} ${err.slice(0, 200)}`, json: { ok: false, error: res.status } };
|
|
264183
|
-
}
|
|
264184
|
-
const r2 = await res.json();
|
|
264172
|
+
async function fmtGetResource(token, resourceId, signal) {
|
|
264173
|
+
const result = await getResourceRaw(token, resourceId, signal);
|
|
264174
|
+
if (!result.ok) return { text: `Admin API error: ${result.error}`, json: { ok: false, error: result.error } };
|
|
264175
|
+
const r2 = result.data;
|
|
264185
264176
|
const lines = [
|
|
264186
264177
|
`Resource: ${r2.resourceName || r2.generatedResourceName || "Unnamed"}`,
|
|
264187
264178
|
` ID: ${r2.resourceId}`,
|
|
264188
264179
|
` Email: ${r2.resourceEmail || "N/A"}`,
|
|
264189
264180
|
` Type: ${r2.resourceType || "N/A"}`,
|
|
264190
|
-
|
|
264181
|
+
r2.capacity ? ` Capacity: ${r2.capacity}` : "",
|
|
264191
264182
|
r2.buildingId ? ` Building: ${r2.buildingId}` : "",
|
|
264192
264183
|
r2.floorName ? ` Floor: ${r2.floorName}` : "",
|
|
264193
264184
|
r2.resourceDescription ? ` Description: ${r2.resourceDescription}` : "",
|
|
@@ -264195,26 +264186,10 @@ async function getResource(token, resourceId, signal) {
|
|
|
264195
264186
|
].filter(Boolean);
|
|
264196
264187
|
return { text: lines.join("\n"), json: { ok: true, resource: r2 } };
|
|
264197
264188
|
}
|
|
264198
|
-
async function
|
|
264199
|
-
const
|
|
264200
|
-
|
|
264201
|
-
|
|
264202
|
-
};
|
|
264203
|
-
if (params.buildingId) body.buildingId = params.buildingId;
|
|
264204
|
-
if (params.capacity) body.capacity = params.capacity;
|
|
264205
|
-
if (params.floorName) body.floorName = params.floorName;
|
|
264206
|
-
if (params.description) body.resourceDescription = params.description;
|
|
264207
|
-
const res = await fetch(`${ADMIN_RESOURCES_BASE2}/calendars`, {
|
|
264208
|
-
method: "POST",
|
|
264209
|
-
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
264210
|
-
body: JSON.stringify(body),
|
|
264211
|
-
...signal ? { signal } : {}
|
|
264212
|
-
});
|
|
264213
|
-
if (!res.ok) {
|
|
264214
|
-
const err = await res.text().catch(() => "");
|
|
264215
|
-
return { text: `Admin API create error: ${res.status} ${err.slice(0, 200)}`, json: { ok: false, error: res.status } };
|
|
264216
|
-
}
|
|
264217
|
-
const r2 = await res.json();
|
|
264189
|
+
async function fmtCreateResource(token, params, signal) {
|
|
264190
|
+
const result = await createResourceRaw(token, params, signal);
|
|
264191
|
+
if (!result.ok) return { text: `Admin API create error: ${result.error}`, json: { ok: false, error: result.error } };
|
|
264192
|
+
const r2 = result.data;
|
|
264218
264193
|
return {
|
|
264219
264194
|
text: `Created resource: "${r2.resourceName}" (id=${r2.resourceId}, email=${r2.resourceEmail})`,
|
|
264220
264195
|
json: { ok: true, created: true, resource: r2 }
|
|
@@ -264295,9 +264270,9 @@ async function bulkImportResources(token, filePath4, signal, dryRun = false) {
|
|
|
264295
264270
|
if (rec.floor || rec.floorName) body.floorName = rec.floor || rec.floorName;
|
|
264296
264271
|
if (rec.description || rec.resourceDescription) body.resourceDescription = rec.description || rec.resourceDescription;
|
|
264297
264272
|
try {
|
|
264298
|
-
const createRes = await
|
|
264273
|
+
const createRes = await adminFetch(token, `${ADMIN_RESOURCES_BASE}/calendars`, {
|
|
264299
264274
|
method: "POST",
|
|
264300
|
-
headers: {
|
|
264275
|
+
headers: { "Content-Type": "application/json" },
|
|
264301
264276
|
body: JSON.stringify(body),
|
|
264302
264277
|
...signal ? { signal } : {}
|
|
264303
264278
|
});
|
|
@@ -264325,54 +264300,25 @@ async function bulkImportResources(token, filePath4, signal, dryRun = false) {
|
|
|
264325
264300
|
}
|
|
264326
264301
|
};
|
|
264327
264302
|
}
|
|
264328
|
-
async function
|
|
264329
|
-
const
|
|
264330
|
-
|
|
264331
|
-
|
|
264332
|
-
});
|
|
264333
|
-
if (!res.ok) {
|
|
264334
|
-
const err = await res.text().catch(() => "");
|
|
264335
|
-
return { text: `Admin API error: ${res.status} ${err.slice(0, 200)}`, json: { ok: false, error: res.status } };
|
|
264336
|
-
}
|
|
264337
|
-
const data = await res.json();
|
|
264338
|
-
const buildings = Array.isArray(data.buildings) ? data.buildings : [];
|
|
264303
|
+
async function fmtListBuildings(token, signal) {
|
|
264304
|
+
const result = await listBuildingsRaw(token, signal);
|
|
264305
|
+
if (!result.ok) return { text: `Admin API error: ${result.error}`, json: { ok: false, error: result.error } };
|
|
264306
|
+
const buildings = result.data;
|
|
264339
264307
|
if (buildings.length === 0) return { text: "No buildings found.", json: { ok: true, buildings: [] } };
|
|
264340
264308
|
const lines = [`${buildings.length} building(s):`, ""];
|
|
264341
264309
|
for (const b of buildings) {
|
|
264342
264310
|
lines.push(` ${b.buildingName || "Unnamed"}`);
|
|
264343
264311
|
lines.push(` ID: ${b.buildingId}`);
|
|
264344
264312
|
if (b.description) lines.push(` Description: ${b.description}`);
|
|
264345
|
-
if (
|
|
264313
|
+
if (b.floorNames.length) lines.push(` Floors: ${b.floorNames.join(", ")}`);
|
|
264346
264314
|
lines.push("");
|
|
264347
264315
|
}
|
|
264348
264316
|
return { text: lines.join("\n"), json: { ok: true, buildings } };
|
|
264349
264317
|
}
|
|
264350
|
-
async function
|
|
264351
|
-
const
|
|
264352
|
-
|
|
264353
|
-
|
|
264354
|
-
buildingName: params.name
|
|
264355
|
-
};
|
|
264356
|
-
if (params.description) body.description = params.description;
|
|
264357
|
-
if (params.floors) {
|
|
264358
|
-
const n = Number(params.floors);
|
|
264359
|
-
if (n > 0) {
|
|
264360
|
-
body.floorNames = Array.from({ length: n }, (_, i2) => String(i2 + 1));
|
|
264361
|
-
} else {
|
|
264362
|
-
body.floorNames = params.floors.split(",").map((f3) => f3.trim()).filter(Boolean);
|
|
264363
|
-
}
|
|
264364
|
-
}
|
|
264365
|
-
const res = await fetch(`${ADMIN_RESOURCES_BASE2}/buildings`, {
|
|
264366
|
-
method: "POST",
|
|
264367
|
-
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
264368
|
-
body: JSON.stringify(body),
|
|
264369
|
-
...signal ? { signal } : {}
|
|
264370
|
-
});
|
|
264371
|
-
if (!res.ok) {
|
|
264372
|
-
const err = await res.text().catch(() => "");
|
|
264373
|
-
return { text: `Admin API create error: ${res.status} ${err.slice(0, 200)}`, json: { ok: false, error: res.status } };
|
|
264374
|
-
}
|
|
264375
|
-
const b = await res.json();
|
|
264318
|
+
async function fmtCreateBuilding(token, params, signal) {
|
|
264319
|
+
const result = await createBuildingRaw(token, params, signal);
|
|
264320
|
+
if (!result.ok) return { text: `Admin API create error: ${result.error}`, json: { ok: false, error: result.error } };
|
|
264321
|
+
const b = result.data;
|
|
264376
264322
|
return {
|
|
264377
264323
|
text: `Created building: "${b.buildingName}" (id=${b.buildingId})`,
|
|
264378
264324
|
json: { ok: true, created: true, building: b }
|
|
@@ -264441,18 +264387,16 @@ async function bulkImportBuildings(token, filePath4, signal, dryRun = false) {
|
|
|
264441
264387
|
const rec = records[i2];
|
|
264442
264388
|
const row = i2 + 2;
|
|
264443
264389
|
const name = rec.name || rec.buildingName || "";
|
|
264444
|
-
const bldId = (rec.id || rec.buildingId || name
|
|
264390
|
+
const bldId = slugify2(rec.id || rec.buildingId || name, "bld");
|
|
264445
264391
|
const body = { buildingId: bldId, buildingName: name };
|
|
264446
264392
|
if (rec.description) body.description = rec.description;
|
|
264447
264393
|
if (rec.floors || rec.floorNames) {
|
|
264448
|
-
|
|
264449
|
-
const n = Number(f3);
|
|
264450
|
-
body.floorNames = n > 0 ? Array.from({ length: n }, (_, i22) => String(i22 + 1)) : f3.split(",").map((s2) => s2.trim()).filter(Boolean);
|
|
264394
|
+
body.floorNames = parseFloorNames(rec.floors || rec.floorNames);
|
|
264451
264395
|
}
|
|
264452
264396
|
try {
|
|
264453
|
-
const createRes = await
|
|
264397
|
+
const createRes = await adminFetch(token, `${ADMIN_RESOURCES_BASE}/buildings`, {
|
|
264454
264398
|
method: "POST",
|
|
264455
|
-
headers: {
|
|
264399
|
+
headers: { "Content-Type": "application/json" },
|
|
264456
264400
|
body: JSON.stringify(body),
|
|
264457
264401
|
...signal ? { signal } : {}
|
|
264458
264402
|
});
|
|
@@ -264529,12 +264473,13 @@ async function checkAvailability(token, targets, datetime, durationMinutes, sign
|
|
|
264529
264473
|
function createGcalField() {
|
|
264530
264474
|
return { commandId: "gcal", worker: new GcalWorker(), checker: new AlwaysPassChecker11() };
|
|
264531
264475
|
}
|
|
264532
|
-
var GcalWorker,
|
|
264476
|
+
var GcalWorker, EMAIL_REGEX, AlwaysPassChecker11;
|
|
264533
264477
|
var init_gcal_field = __esm({
|
|
264534
264478
|
"commands/google/gcal.field.ts"() {
|
|
264535
264479
|
init_base2();
|
|
264536
264480
|
init_google_oauth();
|
|
264537
264481
|
init_date_tz();
|
|
264482
|
+
init_admin_resources();
|
|
264538
264483
|
GcalWorker = class extends LiteWorkerAgent {
|
|
264539
264484
|
commandId = "gcal";
|
|
264540
264485
|
help = {
|
|
@@ -264642,17 +264587,17 @@ var init_gcal_field = __esm({
|
|
|
264642
264587
|
const resSub = (ctx.parsed.args?.[1] || "list").toLowerCase();
|
|
264643
264588
|
if (resSub === "list") {
|
|
264644
264589
|
const buildingId = String(ctx.parsed.options.building || "").trim() || void 0;
|
|
264645
|
-
return await
|
|
264590
|
+
return await fmtListResources(token, buildingId, ctx.abortSignal);
|
|
264646
264591
|
}
|
|
264647
264592
|
if (resSub === "get") {
|
|
264648
264593
|
const resourceId = String(ctx.parsed.args?.[2] || ctx.parsed.options.id || "").trim();
|
|
264649
264594
|
if (!resourceId) return { text: "gcal resources get: resourceId is required" };
|
|
264650
|
-
return await
|
|
264595
|
+
return await fmtGetResource(token, resourceId, ctx.abortSignal);
|
|
264651
264596
|
}
|
|
264652
264597
|
if (resSub === "create") {
|
|
264653
264598
|
const name = String(ctx.parsed.options.name || "").trim();
|
|
264654
264599
|
if (!name) return { text: "gcal resources create: --name is required" };
|
|
264655
|
-
return await
|
|
264600
|
+
return await fmtCreateResource(token, {
|
|
264656
264601
|
name,
|
|
264657
264602
|
buildingId: String(ctx.parsed.options.building || "").trim() || void 0,
|
|
264658
264603
|
capacity: Number(ctx.parsed.options.capacity || "0") || void 0,
|
|
@@ -264672,12 +264617,12 @@ var init_gcal_field = __esm({
|
|
|
264672
264617
|
if (sub === "buildings") {
|
|
264673
264618
|
const bldSub = (ctx.parsed.args?.[1] || "list").toLowerCase();
|
|
264674
264619
|
if (bldSub === "list") {
|
|
264675
|
-
return await
|
|
264620
|
+
return await fmtListBuildings(token, ctx.abortSignal);
|
|
264676
264621
|
}
|
|
264677
264622
|
if (bldSub === "create") {
|
|
264678
264623
|
const name = String(ctx.parsed.options.name || "").trim();
|
|
264679
264624
|
if (!name) return { text: "gcal buildings create: --name is required" };
|
|
264680
|
-
return await
|
|
264625
|
+
return await fmtCreateBuilding(token, {
|
|
264681
264626
|
name,
|
|
264682
264627
|
floors: String(ctx.parsed.options.floors || "").trim() || void 0,
|
|
264683
264628
|
description: String(ctx.parsed.options.description || "").trim() || void 0
|
|
@@ -264706,7 +264651,6 @@ var init_gcal_field = __esm({
|
|
|
264706
264651
|
}
|
|
264707
264652
|
];
|
|
264708
264653
|
};
|
|
264709
|
-
ADMIN_RESOURCES_BASE2 = "https://admin.googleapis.com/admin/directory/v1/customer/my_customer/resources";
|
|
264710
264654
|
EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
264711
264655
|
AlwaysPassChecker11 = class extends LiteCheckerAgent {
|
|
264712
264656
|
commandId = "gcal";
|
|
@@ -293291,152 +293235,38 @@ var init_phone_init_field = __esm({
|
|
|
293291
293235
|
});
|
|
293292
293236
|
|
|
293293
293237
|
// commands/resource-manager.field.ts
|
|
293294
|
-
|
|
293295
|
-
return fetch(url, {
|
|
293296
|
-
...opts,
|
|
293297
|
-
headers: { Authorization: `Bearer ${token}`, ...opts?.headers || {} }
|
|
293298
|
-
});
|
|
293299
|
-
}
|
|
293300
|
-
async function listBuildings2(token, _signal) {
|
|
293301
|
-
const res = await gFetch3(token, `${ADMIN_RESOURCES_BASE3}/buildings?maxResults=500`);
|
|
293302
|
-
if (!res.ok) {
|
|
293303
|
-
return { text: `Resource Manager: Admin SDK error ${res.status}`, json: { ok: false, error: `Admin SDK: ${res.status}` } };
|
|
293304
|
-
}
|
|
293305
|
-
const data = await res.json();
|
|
293306
|
-
const items = Array.isArray(data.buildings) ? data.buildings : [];
|
|
293307
|
-
if (items.length === 0) {
|
|
293308
|
-
return { text: "No buildings found.", json: { ok: true, buildings: [] } };
|
|
293309
|
-
}
|
|
293238
|
+
function formatBuildingsTable(items) {
|
|
293310
293239
|
const lines = ["## Buildings", ""];
|
|
293311
293240
|
lines.push("| ID | Name | Floors | Description |");
|
|
293312
293241
|
lines.push("|---|---|---|---|");
|
|
293313
293242
|
for (const b of items) {
|
|
293314
|
-
const floors =
|
|
293315
|
-
lines.push(`| ${b.buildingId
|
|
293243
|
+
const floors = b.floorNames.join(", ");
|
|
293244
|
+
lines.push(`| ${b.buildingId} | ${b.buildingName} | ${floors} | ${b.description} |`);
|
|
293316
293245
|
}
|
|
293317
293246
|
lines.push("", `Total: ${items.length} building(s)`);
|
|
293318
|
-
return
|
|
293247
|
+
return lines.join("\n");
|
|
293319
293248
|
}
|
|
293320
|
-
|
|
293321
|
-
let url = `${ADMIN_RESOURCES_BASE3}/calendars?maxResults=500`;
|
|
293322
|
-
const res = await gFetch3(token, url);
|
|
293323
|
-
if (!res.ok) {
|
|
293324
|
-
return { text: `Resource Manager: Admin SDK error ${res.status}`, json: { ok: false, error: `Admin SDK: ${res.status}` } };
|
|
293325
|
-
}
|
|
293326
|
-
const data = await res.json();
|
|
293327
|
-
let items = Array.isArray(data.items) ? data.items : [];
|
|
293328
|
-
if (buildingId) items = items.filter((r2) => String(r2.buildingId || "") === buildingId);
|
|
293329
|
-
if (capacity) items = items.filter((r2) => Number(r2.capacity || 0) >= capacity);
|
|
293330
|
-
if (items.length === 0) {
|
|
293331
|
-
return { text: "No resources found.", json: { ok: true, resources: [] } };
|
|
293332
|
-
}
|
|
293249
|
+
function formatResourcesTable(items) {
|
|
293333
293250
|
const lines = ["## Calendar Resources", ""];
|
|
293334
293251
|
lines.push("| Name | Building | Capacity | Type | Floor | Email |");
|
|
293335
293252
|
lines.push("|---|---|---|---|---|---|");
|
|
293336
293253
|
for (const r2 of items) {
|
|
293337
|
-
lines.push(`| ${r2.resourceName
|
|
293254
|
+
lines.push(`| ${r2.resourceName} | ${r2.buildingId} | ${r2.capacity || ""} | ${r2.resourceType} | ${r2.floorName} | ${r2.resourceEmail} |`);
|
|
293338
293255
|
}
|
|
293339
293256
|
lines.push("", `Total: ${items.length} resource(s)`);
|
|
293340
|
-
return
|
|
293341
|
-
}
|
|
293342
|
-
async function createBuilding2(token, name, floorsRaw, description, _signal) {
|
|
293343
|
-
const buildingId = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40) || `bld-${Date.now()}`;
|
|
293344
|
-
const body = { buildingId, buildingName: name };
|
|
293345
|
-
if (description) body.description = description;
|
|
293346
|
-
if (floorsRaw) {
|
|
293347
|
-
const n = Number(floorsRaw);
|
|
293348
|
-
if (!isNaN(n) && n > 0 && Number.isInteger(n)) {
|
|
293349
|
-
body.floorNames = Array.from({ length: n }, (_, i2) => String(i2 + 1));
|
|
293350
|
-
} else {
|
|
293351
|
-
body.floorNames = floorsRaw.split(",").map((f3) => f3.trim()).filter(Boolean);
|
|
293352
|
-
}
|
|
293353
|
-
}
|
|
293354
|
-
const res = await gFetch3(token, `${ADMIN_RESOURCES_BASE3}/buildings`, {
|
|
293355
|
-
method: "POST",
|
|
293356
|
-
headers: { "Content-Type": "application/json" },
|
|
293357
|
-
body: JSON.stringify(body)
|
|
293358
|
-
});
|
|
293359
|
-
if (!res.ok) {
|
|
293360
|
-
const errText = await res.text().catch(() => "");
|
|
293361
|
-
if (res.status === 403) return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293362
|
-
return { text: `Failed to create building: ${res.status} ${errText}`, json: { ok: false, error: `Admin SDK: ${res.status}` } };
|
|
293363
|
-
}
|
|
293364
|
-
const created = await res.json();
|
|
293365
|
-
return {
|
|
293366
|
-
text: `Building created: ${created.buildingName} (${created.buildingId})`,
|
|
293367
|
-
json: { ok: true, building: created }
|
|
293368
|
-
};
|
|
293369
|
-
}
|
|
293370
|
-
async function createResource2(token, opts, _signal) {
|
|
293371
|
-
const resourceId = opts.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40) || `res-${Date.now()}`;
|
|
293372
|
-
const body = { resourceId, resourceName: opts.name, resourceType: opts.resourceType };
|
|
293373
|
-
if (opts.buildingId) body.buildingId = opts.buildingId;
|
|
293374
|
-
if (opts.capacity) body.capacity = opts.capacity;
|
|
293375
|
-
if (opts.floorName) body.floorName = opts.floorName;
|
|
293376
|
-
if (opts.description) body.resourceDescription = opts.description;
|
|
293377
|
-
const res = await gFetch3(token, `${ADMIN_RESOURCES_BASE3}/calendars`, {
|
|
293378
|
-
method: "POST",
|
|
293379
|
-
headers: { "Content-Type": "application/json" },
|
|
293380
|
-
body: JSON.stringify(body)
|
|
293381
|
-
});
|
|
293382
|
-
if (!res.ok) {
|
|
293383
|
-
const errText = await res.text().catch(() => "");
|
|
293384
|
-
if (res.status === 403) return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293385
|
-
return { text: `Failed to create resource: ${res.status} ${errText}`, json: { ok: false, error: `Admin SDK: ${res.status}` } };
|
|
293386
|
-
}
|
|
293387
|
-
const created = await res.json();
|
|
293388
|
-
return {
|
|
293389
|
-
text: `Resource created: ${created.resourceName} (${created.resourceEmail})`,
|
|
293390
|
-
json: { ok: true, resource: created }
|
|
293391
|
-
};
|
|
293392
|
-
}
|
|
293393
|
-
async function updateBuilding(token, buildingId, body, _signal) {
|
|
293394
|
-
const res = await gFetch3(token, `${ADMIN_RESOURCES_BASE3}/buildings/${encodeURIComponent(buildingId)}`, {
|
|
293395
|
-
method: "PATCH",
|
|
293396
|
-
headers: { "Content-Type": "application/json" },
|
|
293397
|
-
body: JSON.stringify(body)
|
|
293398
|
-
});
|
|
293399
|
-
if (!res.ok) {
|
|
293400
|
-
const errText = await res.text().catch(() => "");
|
|
293401
|
-
if (res.status === 403) return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293402
|
-
if (res.status === 404) return { text: `Building "${buildingId}" not found.`, json: { ok: false, error: "not_found" } };
|
|
293403
|
-
return { text: `Failed to update building: ${res.status} ${errText}`, json: { ok: false, error: `Admin SDK: ${res.status}` } };
|
|
293404
|
-
}
|
|
293405
|
-
const updated = await res.json();
|
|
293406
|
-
return {
|
|
293407
|
-
text: `Building updated: ${updated.buildingName} (${updated.buildingId})`,
|
|
293408
|
-
json: { ok: true, building: updated }
|
|
293409
|
-
};
|
|
293410
|
-
}
|
|
293411
|
-
async function updateResource(token, resourceId, body, _signal) {
|
|
293412
|
-
const res = await gFetch3(token, `${ADMIN_RESOURCES_BASE3}/calendars/${encodeURIComponent(resourceId)}`, {
|
|
293413
|
-
method: "PATCH",
|
|
293414
|
-
headers: { "Content-Type": "application/json" },
|
|
293415
|
-
body: JSON.stringify(body)
|
|
293416
|
-
});
|
|
293417
|
-
if (!res.ok) {
|
|
293418
|
-
const errText = await res.text().catch(() => "");
|
|
293419
|
-
if (res.status === 403) return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293420
|
-
if (res.status === 404) return { text: `Resource "${resourceId}" not found.`, json: { ok: false, error: "not_found" } };
|
|
293421
|
-
return { text: `Failed to update resource: ${res.status} ${errText}`, json: { ok: false, error: `Admin SDK: ${res.status}` } };
|
|
293422
|
-
}
|
|
293423
|
-
const updated = await res.json();
|
|
293424
|
-
return {
|
|
293425
|
-
text: `Resource updated: ${updated.resourceName} (${updated.resourceEmail})`,
|
|
293426
|
-
json: { ok: true, resource: updated }
|
|
293427
|
-
};
|
|
293257
|
+
return lines.join("\n");
|
|
293428
293258
|
}
|
|
293429
293259
|
function createResourceManagerField() {
|
|
293430
293260
|
const worker = new ResourceManagerWorker();
|
|
293431
293261
|
const checker = new ResourceManagerChecker();
|
|
293432
293262
|
return { worker, checker };
|
|
293433
293263
|
}
|
|
293434
|
-
var
|
|
293264
|
+
var ResourceManagerWorker, ResourceManagerChecker;
|
|
293435
293265
|
var init_resource_manager_field = __esm({
|
|
293436
293266
|
"commands/resource-manager.field.ts"() {
|
|
293437
293267
|
init_base2();
|
|
293438
293268
|
init_google_oauth();
|
|
293439
|
-
|
|
293269
|
+
init_admin_resources();
|
|
293440
293270
|
ResourceManagerWorker = class extends LiteWorkerAgent {
|
|
293441
293271
|
commandId = "resource-manager";
|
|
293442
293272
|
help = {
|
|
@@ -293460,20 +293290,34 @@ var init_resource_manager_field = __esm({
|
|
|
293460
293290
|
}
|
|
293461
293291
|
const sub = (ctx.parsed.subcommand || ctx.parsed.args?.[0] || "buildings").toLowerCase();
|
|
293462
293292
|
if (sub === "buildings" || sub === "list-buildings") {
|
|
293463
|
-
|
|
293293
|
+
const result = await listBuildingsRaw(token, ctx.abortSignal);
|
|
293294
|
+
if (!result.ok) return { text: `Resource Manager: ${result.error}`, json: { ok: false, error: result.error } };
|
|
293295
|
+
const items = result.data;
|
|
293296
|
+
if (items.length === 0) return { text: "No buildings found.", json: { ok: true, buildings: [] } };
|
|
293297
|
+
return { text: formatBuildingsTable(items), json: { ok: true, buildings: items } };
|
|
293464
293298
|
}
|
|
293465
293299
|
if (sub === "resources" || sub === "list-resources") {
|
|
293466
293300
|
const buildingId = String(ctx.parsed.options.building || ctx.parsed.options.buildingId || "").trim() || void 0;
|
|
293467
293301
|
const capacityRaw = String(ctx.parsed.options.capacity || "").trim();
|
|
293468
293302
|
const capacity = capacityRaw ? Math.max(0, Number(capacityRaw) || 0) : void 0;
|
|
293469
|
-
|
|
293303
|
+
const result = await listResourcesRaw(token, { buildingId, capacity }, ctx.abortSignal);
|
|
293304
|
+
if (!result.ok) return { text: `Resource Manager: ${result.error}`, json: { ok: false, error: result.error } };
|
|
293305
|
+
const items = result.data;
|
|
293306
|
+
if (items.length === 0) return { text: "No resources found.", json: { ok: true, resources: [] } };
|
|
293307
|
+
return { text: formatResourcesTable(items), json: { ok: true, resources: items } };
|
|
293470
293308
|
}
|
|
293471
293309
|
if (sub === "create-building") {
|
|
293472
293310
|
const name = String(ctx.parsed.options.name || ctx.parsed.prompt || "").trim();
|
|
293473
293311
|
if (!name) return { text: "resource-manager create-building: --name is required" };
|
|
293474
293312
|
const floorsRaw = String(ctx.parsed.options.floors || "").trim();
|
|
293475
293313
|
const description = String(ctx.parsed.options.description || "").trim() || void 0;
|
|
293476
|
-
|
|
293314
|
+
const result = await createBuildingRaw(token, { name, floors: floorsRaw || void 0, description }, ctx.abortSignal);
|
|
293315
|
+
if (!result.ok) {
|
|
293316
|
+
if (result.error === "permission_denied") return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293317
|
+
return { text: `Failed to create building: ${result.error}`, json: { ok: false, error: result.error } };
|
|
293318
|
+
}
|
|
293319
|
+
const b = result.data;
|
|
293320
|
+
return { text: `Building created: ${b.buildingName} (${b.buildingId})`, json: { ok: true, building: b } };
|
|
293477
293321
|
}
|
|
293478
293322
|
if (sub === "create-resource") {
|
|
293479
293323
|
const name = String(ctx.parsed.options.name || ctx.parsed.prompt || "").trim();
|
|
@@ -293483,7 +293327,14 @@ var init_resource_manager_field = __esm({
|
|
|
293483
293327
|
const resourceType = String(ctx.parsed.options.type || "CONFERENCE_ROOM").trim();
|
|
293484
293328
|
const floorName = String(ctx.parsed.options.floor || "").trim() || void 0;
|
|
293485
293329
|
const description = String(ctx.parsed.options.description || "").trim() || void 0;
|
|
293486
|
-
|
|
293330
|
+
const resourceId = slugify2(name, "res");
|
|
293331
|
+
const result = await createResourceRaw(token, { name, resourceId, buildingId, capacity, resourceType, floorName, description }, ctx.abortSignal);
|
|
293332
|
+
if (!result.ok) {
|
|
293333
|
+
if (result.error === "permission_denied") return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293334
|
+
return { text: `Failed to create resource: ${result.error}`, json: { ok: false, error: result.error } };
|
|
293335
|
+
}
|
|
293336
|
+
const r2 = result.data;
|
|
293337
|
+
return { text: `Resource created: ${r2.resourceName} (${r2.resourceEmail})`, json: { ok: true, resource: r2 } };
|
|
293487
293338
|
}
|
|
293488
293339
|
if (sub === "update-building") {
|
|
293489
293340
|
const id = String(ctx.parsed.options.id || "").trim();
|
|
@@ -293492,18 +293343,18 @@ var init_resource_manager_field = __esm({
|
|
|
293492
293343
|
const name = String(ctx.parsed.options.name || "").trim();
|
|
293493
293344
|
if (name) body.buildingName = name;
|
|
293494
293345
|
const floorsRaw = String(ctx.parsed.options.floors || "").trim();
|
|
293495
|
-
if (floorsRaw)
|
|
293496
|
-
const n = Number(floorsRaw);
|
|
293497
|
-
if (!isNaN(n) && n > 0 && Number.isInteger(n)) {
|
|
293498
|
-
body.floorNames = Array.from({ length: n }, (_, i2) => String(i2 + 1));
|
|
293499
|
-
} else {
|
|
293500
|
-
body.floorNames = floorsRaw.split(",").map((f3) => f3.trim()).filter(Boolean);
|
|
293501
|
-
}
|
|
293502
|
-
}
|
|
293346
|
+
if (floorsRaw) body.floorNames = parseFloorNames(floorsRaw);
|
|
293503
293347
|
const description = String(ctx.parsed.options.description || "").trim();
|
|
293504
293348
|
if (description) body.description = description;
|
|
293505
293349
|
if (Object.keys(body).length === 0) return { text: "resource-manager update-building: at least one field to update is required (--name, --floors, --description)" };
|
|
293506
|
-
|
|
293350
|
+
const result = await updateBuildingRaw(token, id, body, ctx.abortSignal);
|
|
293351
|
+
if (!result.ok) {
|
|
293352
|
+
if (result.error === "permission_denied") return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293353
|
+
if (result.error === "not_found") return { text: `Building "${id}" not found.`, json: { ok: false, error: "not_found" } };
|
|
293354
|
+
return { text: `Failed to update building: ${result.error}`, json: { ok: false, error: result.error } };
|
|
293355
|
+
}
|
|
293356
|
+
const b = result.data;
|
|
293357
|
+
return { text: `Building updated: ${b.buildingName} (${b.buildingId})`, json: { ok: true, building: b } };
|
|
293507
293358
|
}
|
|
293508
293359
|
if (sub === "update-resource") {
|
|
293509
293360
|
const id = String(ctx.parsed.options.id || "").trim();
|
|
@@ -293522,7 +293373,14 @@ var init_resource_manager_field = __esm({
|
|
|
293522
293373
|
const description = String(ctx.parsed.options.description || "").trim();
|
|
293523
293374
|
if (description) body.resourceDescription = description;
|
|
293524
293375
|
if (Object.keys(body).length === 0) return { text: "resource-manager update-resource: at least one field to update is required" };
|
|
293525
|
-
|
|
293376
|
+
const result = await updateResourceRaw(token, id, body, ctx.abortSignal);
|
|
293377
|
+
if (!result.ok) {
|
|
293378
|
+
if (result.error === "permission_denied") return { text: "Permission denied: Google Workspace admin privileges required.", json: { ok: false, error: "permission_denied" } };
|
|
293379
|
+
if (result.error === "not_found") return { text: `Resource "${id}" not found.`, json: { ok: false, error: "not_found" } };
|
|
293380
|
+
return { text: `Failed to update resource: ${result.error}`, json: { ok: false, error: result.error } };
|
|
293381
|
+
}
|
|
293382
|
+
const r2 = result.data;
|
|
293383
|
+
return { text: `Resource updated: ${r2.resourceName} (${r2.resourceEmail})`, json: { ok: true, resource: r2 } };
|
|
293526
293384
|
}
|
|
293527
293385
|
return { text: `resource-manager: unknown subcommand "${sub}". Use buildings, resources, create-building, create-resource, update-building, or update-resource.` };
|
|
293528
293386
|
}
|
package/dist/ext.cjs
CHANGED
|
@@ -98004,7 +98004,7 @@ function resolvePackageJsonNearEntrypoint() {
|
|
|
98004
98004
|
}
|
|
98005
98005
|
function resolveMariaLiteVersionInfo() {
|
|
98006
98006
|
const fallbackName = EXPECTED_PKG_NAME;
|
|
98007
|
-
const fallbackVersion = String(process.env.MARIA_LITE_VERSION || "").trim() || "
|
|
98007
|
+
const fallbackVersion = String(process.env.MARIA_LITE_VERSION || "").trim() || "7.0.0";
|
|
98008
98008
|
const near = resolvePackageJsonNearEntrypoint();
|
|
98009
98009
|
if (near) {
|
|
98010
98010
|
const name = fallbackName;
|
package/origin/index.meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"buildTimestamp":"2026-03-
|
|
1
|
+
{"buildTimestamp":"2026-03-03T22:07:03.940Z","fileCount":952,"indexJsonlRelPath":"src-lite/origin/index.jsonl","schemaVersion":"maria_lite_origin_index_meta_v1","sourceDir":"src-lite/origin","textExtractedCount":952}
|