@camstack/addon-google-services 0.2.41 → 0.2.43
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/CHANGELOG.md +12 -0
- package/dist/google-services.addon.js +288 -582
- package/dist/google-services.addon.mjs +289 -583
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
|
-
//#region ../types/dist/event-category-
|
|
6
|
+
//#region ../types/dist/event-category-78tcBemo.mjs
|
|
7
7
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
8
8
|
EventCategory["SystemBoot"] = "system.boot";
|
|
9
9
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -124,6 +124,23 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
124
124
|
*/
|
|
125
125
|
EventCategory["AddonLoadRecovered"] = "addon.load-recovered";
|
|
126
126
|
/**
|
|
127
|
+
* An addon is RUNNING although its installed package is below what the
|
|
128
|
+
* running server requires (`camstack.requires.addons` of the server, or the
|
|
129
|
+
* addon's own `requires.server`). Raised once per streak by the unsupported-
|
|
130
|
+
* addon tracker, on the hub and on agents; AlertCenter turns it into one
|
|
131
|
+
* operator alert per node and package. The addon is never held back for it.
|
|
132
|
+
*
|
|
133
|
+
* Payload: `{ packageName, addonId, nodeId, installedVersion, requiredMinimum, serverVersion, unmet }`.
|
|
134
|
+
*/
|
|
135
|
+
EventCategory["AddonUnsupportedVersion"] = "addon.unsupported-version";
|
|
136
|
+
/**
|
|
137
|
+
* The package of an {@link AddonUnsupportedVersion} alert reached a supported
|
|
138
|
+
* version, or is no longer installed on the node. AlertCenter dismisses the matching alert.
|
|
139
|
+
*
|
|
140
|
+
* Payload: `{ packageName, addonId, nodeId }`.
|
|
141
|
+
*/
|
|
142
|
+
EventCategory["AddonUnsupportedResolved"] = "addon.unsupported-resolved";
|
|
143
|
+
/**
|
|
127
144
|
* Monitor scheduled the next retry for a failed addon. Transient —
|
|
128
145
|
* surfaced to the UI for live-updating the "next retry in Ns"
|
|
129
146
|
* countdown on the Addons page row, NOT persisted as an alert.
|
|
@@ -234,7 +251,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
234
251
|
EventCategory["ProcessRestarted"] = "process.restarted";
|
|
235
252
|
/**
|
|
236
253
|
* The SET of storage locations changed — one was created, edited, enabled,
|
|
237
|
-
* disabled or deleted through
|
|
254
|
+
* disabled or deleted through the location instances or the forced-delete action.
|
|
238
255
|
*
|
|
239
256
|
* Telemetry, not a transaction (D8/D11): every consumer that re-resolves on
|
|
240
257
|
* it must also converge on its own periodic path, because a dropped event
|
|
@@ -5985,7 +6002,7 @@ var ZodIssueCode = {
|
|
|
5985
6002
|
var ZodFirstPartyTypeKind;
|
|
5986
6003
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5987
6004
|
//#endregion
|
|
5988
|
-
//#region ../types/dist/sleep-
|
|
6005
|
+
//#region ../types/dist/sleep-AEnTN3b4.mjs
|
|
5989
6006
|
/**
|
|
5990
6007
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5991
6008
|
* window to float samples (D455).
|
|
@@ -6694,10 +6711,33 @@ function integrationRowsApiOver(api) {
|
|
|
6694
6711
|
};
|
|
6695
6712
|
}
|
|
6696
6713
|
var PREFIX = "records/";
|
|
6714
|
+
/**
|
|
6715
|
+
* Cross-realm brand. An addon bundles its own copy of this module (D15) while
|
|
6716
|
+
* `ctx.records` is the HOST's door, so an error thrown by the host is an
|
|
6717
|
+
* instance of the host's classes, not of the addon's. The brand plus the code
|
|
6718
|
+
* make `instanceof` answer by identity of the failure, not of the copy.
|
|
6719
|
+
*/
|
|
6720
|
+
var RECORDS_ERROR_BRAND = Symbol.for("camstack.records-error");
|
|
6721
|
+
function carriesBrand(value) {
|
|
6722
|
+
return typeof value === "object" && value !== null && Reflect.get(value, RECORDS_ERROR_BRAND) === true;
|
|
6723
|
+
}
|
|
6697
6724
|
/** The base of every records failure. `detail` is the human part of the message. */
|
|
6698
6725
|
var RecordsError = class extends Error {
|
|
6726
|
+
/** The code a subclass stands for; the base stands for every code. */
|
|
6727
|
+
static code = void 0;
|
|
6728
|
+
/**
|
|
6729
|
+
* `instanceof` across copies of this module: any branded error is a
|
|
6730
|
+
* `RecordsError`, and is an instance of a subclass only when its code is the
|
|
6731
|
+
* subclass's code. Same-copy answers are unchanged.
|
|
6732
|
+
*/
|
|
6733
|
+
static [Symbol.hasInstance](value) {
|
|
6734
|
+
if (Function.prototype[Symbol.hasInstance].call(this, value)) return true;
|
|
6735
|
+
if (!carriesBrand(value)) return false;
|
|
6736
|
+
return this.code === void 0 || value.code === this.code;
|
|
6737
|
+
}
|
|
6699
6738
|
code;
|
|
6700
6739
|
detail;
|
|
6740
|
+
[RECORDS_ERROR_BRAND] = true;
|
|
6701
6741
|
constructor(code, detail) {
|
|
6702
6742
|
super(`${PREFIX}${code}: ${detail}`);
|
|
6703
6743
|
this.name = "RecordsError";
|
|
@@ -6706,22 +6746,25 @@ var RecordsError = class extends Error {
|
|
|
6706
6746
|
}
|
|
6707
6747
|
};
|
|
6708
6748
|
/** The keychain could not store or serve a value: explicit, never an empty string. */
|
|
6709
|
-
var RecordSecretUnavailableError = class extends RecordsError {
|
|
6749
|
+
var RecordSecretUnavailableError = class RecordSecretUnavailableError extends RecordsError {
|
|
6750
|
+
static code = "secret-unavailable";
|
|
6710
6751
|
constructor(detail) {
|
|
6711
|
-
super(
|
|
6752
|
+
super(RecordSecretUnavailableError.code, detail);
|
|
6712
6753
|
this.name = "RecordSecretUnavailableError";
|
|
6713
6754
|
}
|
|
6714
6755
|
};
|
|
6715
|
-
var InvalidRecordError = class extends RecordsError {
|
|
6756
|
+
var InvalidRecordError = class InvalidRecordError extends RecordsError {
|
|
6757
|
+
static code = "invalid-record";
|
|
6716
6758
|
constructor(detail) {
|
|
6717
|
-
super(
|
|
6759
|
+
super(InvalidRecordError.code, detail);
|
|
6718
6760
|
this.name = "InvalidRecordError";
|
|
6719
6761
|
}
|
|
6720
6762
|
};
|
|
6721
6763
|
/** A kind declaration the engine refuses (non-additive change, bad shape, wrong file). */
|
|
6722
|
-
var DeclarationRefusedError = class extends RecordsError {
|
|
6764
|
+
var DeclarationRefusedError = class DeclarationRefusedError extends RecordsError {
|
|
6765
|
+
static code = "declaration-refused";
|
|
6723
6766
|
constructor(detail) {
|
|
6724
|
-
super(
|
|
6767
|
+
super(DeclarationRefusedError.code, detail);
|
|
6725
6768
|
this.name = "DeclarationRefusedError";
|
|
6726
6769
|
}
|
|
6727
6770
|
};
|
|
@@ -7208,17 +7251,35 @@ var RecordIntegrationInstances = class {
|
|
|
7208
7251
|
...kind !== void 0 ? { kind } : {}
|
|
7209
7252
|
});
|
|
7210
7253
|
if (minted === void 0) throw new Error("createInstance needs an id: this provider does not mint one");
|
|
7254
|
+
const initial = this.hooks.initialBody(name, kind);
|
|
7255
|
+
const patch = this.patchOf(values ?? {});
|
|
7256
|
+
if (Object.keys(patch).length > 0) Object.assign(patch, await this.hooks.validateWrite?.({
|
|
7257
|
+
kind,
|
|
7258
|
+
body: {
|
|
7259
|
+
...initial,
|
|
7260
|
+
...patch
|
|
7261
|
+
}
|
|
7262
|
+
}));
|
|
7211
7263
|
await this.handle.put({
|
|
7212
7264
|
id: minted,
|
|
7213
|
-
data:
|
|
7265
|
+
data: initial
|
|
7214
7266
|
}, { ifRev: 0 });
|
|
7215
|
-
const patch = this.patchOf(values ?? {});
|
|
7216
7267
|
if (Object.keys(patch).length > 0) await this.handle.patch(minted, patch);
|
|
7217
7268
|
await this.hooks.onChanged?.(minted, "created");
|
|
7218
7269
|
return { id: minted };
|
|
7219
7270
|
};
|
|
7220
7271
|
updateInstance = async ({ id, name, values }) => {
|
|
7221
7272
|
const patch = this.patchOf(values);
|
|
7273
|
+
if (this.hooks.validateWrite !== void 0 && Object.keys(patch).length > 0) {
|
|
7274
|
+
const stored = await this.handle.get(id);
|
|
7275
|
+
if (stored !== null) Object.assign(patch, await this.hooks.validateWrite({
|
|
7276
|
+
kind: void 0,
|
|
7277
|
+
body: {
|
|
7278
|
+
...stored.data,
|
|
7279
|
+
...patch
|
|
7280
|
+
}
|
|
7281
|
+
}));
|
|
7282
|
+
}
|
|
7222
7283
|
if (name !== void 0) patch[this.nameField] = name;
|
|
7223
7284
|
await this.handle.patch(id, patch);
|
|
7224
7285
|
await this.hooks.onChanged?.(id, "updated");
|
|
@@ -10560,7 +10621,6 @@ var CAP_NAMES = Object.freeze([
|
|
|
10560
10621
|
"notifier",
|
|
10561
10622
|
"numeric-sensor",
|
|
10562
10623
|
"oauth-integration",
|
|
10563
|
-
"oidc-connections",
|
|
10564
10624
|
"osd",
|
|
10565
10625
|
"osd-manager",
|
|
10566
10626
|
"pet-feeder",
|
|
@@ -12452,8 +12512,7 @@ Object.freeze({
|
|
|
12452
12512
|
"device-provider": { "reloadDevice": 18e4 },
|
|
12453
12513
|
"llm": {
|
|
12454
12514
|
"generate": 6e5,
|
|
12455
|
-
"generateVision": 6e5
|
|
12456
|
-
"testProfile": 6e5
|
|
12515
|
+
"generateVision": 6e5
|
|
12457
12516
|
},
|
|
12458
12517
|
"llm-runtime": {
|
|
12459
12518
|
"complete": 6e5,
|
|
@@ -14078,17 +14137,18 @@ function composeInstanceKinds(parts, base) {
|
|
|
14078
14137
|
* message to what the kind supports — callers never special-case a service.
|
|
14079
14138
|
*
|
|
14080
14139
|
* DESIGN DECISIONS (locked):
|
|
14081
|
-
* -
|
|
14082
|
-
*
|
|
14083
|
-
*
|
|
14084
|
-
*
|
|
14085
|
-
*
|
|
14086
|
-
*
|
|
14087
|
-
*
|
|
14088
|
-
*
|
|
14089
|
-
*
|
|
14090
|
-
* routable. `send` / `testTarget` /
|
|
14091
|
-
* `
|
|
14140
|
+
* - A target is an INSTANCE of this function cap (epic #440, step 6): the
|
|
14141
|
+
* providers serve their targets as `integration-instances` records, one
|
|
14142
|
+
* record kind per target kind, and the admin lists, adds, edits, switches
|
|
14143
|
+
* and deletes them through that cap. This cap keeps what an instance cannot
|
|
14144
|
+
* say: the kind catalogue (`listTargetKinds`: capabilities, delivery
|
|
14145
|
+
* parameters, brand icon), dispatch (`send`, `testTarget`) and the form
|
|
14146
|
+
* helpers (`discoverTargets`, `probeTargetConfig`).
|
|
14147
|
+
* - `listTargetKinds` / `discoverTargets` return arrays → the generated
|
|
14148
|
+
* cap-mount auto-`concatCollection`-fans them across every registered
|
|
14149
|
+
* provider so one catalog is routable. `send` / `testTarget` /
|
|
14150
|
+
* `probeTargetConfig` route to ONE provider by the `addonId` the generated
|
|
14151
|
+
* collection router extracts from the call input.
|
|
14092
14152
|
* - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
|
|
14093
14153
|
* transformer) + UDS MsgPack both round-trip typed arrays — already used by
|
|
14094
14154
|
* `storage` / `storage-provider` / `recording` caps over the same path. No
|
|
@@ -14333,7 +14393,7 @@ var TargetKindCapsSchema = object({
|
|
|
14333
14393
|
* the union is large and not meant for runtime validation here; the exported
|
|
14334
14394
|
* `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
|
|
14335
14395
|
*/
|
|
14336
|
-
var ConfigSchemaPassthrough$
|
|
14396
|
+
var ConfigSchemaPassthrough$3 = unknown();
|
|
14337
14397
|
var TargetKindSchema = object({
|
|
14338
14398
|
kind: string(),
|
|
14339
14399
|
label: string(),
|
|
@@ -14370,7 +14430,7 @@ var TargetKindSchema = object({
|
|
|
14370
14430
|
* its raster path, which is the safe default for an unknown image.
|
|
14371
14431
|
*/
|
|
14372
14432
|
iconMediaType: string().optional(),
|
|
14373
|
-
configSchema: ConfigSchemaPassthrough$
|
|
14433
|
+
configSchema: ConfigSchemaPassthrough$3,
|
|
14374
14434
|
/**
|
|
14375
14435
|
* The config keys that decide WHERE this kind's secrets are sent (server,
|
|
14376
14436
|
* base URL, instance, chat, recipient). A save that changes any of them
|
|
@@ -14392,9 +14452,11 @@ var TargetKindSchema = object({
|
|
|
14392
14452
|
caps: TargetKindCapsSchema
|
|
14393
14453
|
});
|
|
14394
14454
|
/**
|
|
14395
|
-
* A
|
|
14396
|
-
*
|
|
14397
|
-
*
|
|
14455
|
+
* A target as a provider's own code sees it (the notification-center bridge, the
|
|
14456
|
+
* send path): the flat record body split into the name, the switch and the
|
|
14457
|
+
* kind's fields. `config` holds secrets; a reader that serves it to a client
|
|
14458
|
+
* REDACTS secret fields (a presence marker only) — never round-trip a stored
|
|
14459
|
+
* secret to the UI.
|
|
14398
14460
|
*/
|
|
14399
14461
|
var TargetSchema = object({
|
|
14400
14462
|
id: string(),
|
|
@@ -14437,13 +14499,13 @@ var ProbeTargetConfigResultSchema = object({
|
|
|
14437
14499
|
stateInstance: string().optional(),
|
|
14438
14500
|
error: string().optional()
|
|
14439
14501
|
});
|
|
14440
|
-
method(object({}), array(TargetKindSchema)), method(object({
|
|
14502
|
+
method(object({}), array(TargetKindSchema)), method(object({
|
|
14441
14503
|
kind: string(),
|
|
14442
14504
|
config: record(string(), unknown()).optional(),
|
|
14443
14505
|
/**
|
|
14444
14506
|
* When editing / duplicating, the blank password field never round-trips
|
|
14445
14507
|
* the stored token. Pass the source target id so the provider can restore
|
|
14446
|
-
* secrets server-side before dialling
|
|
14508
|
+
* secrets server-side before dialling.
|
|
14447
14509
|
*/
|
|
14448
14510
|
targetId: string().optional()
|
|
14449
14511
|
}), array(DiscoveredTargetSchema), { auth: "admin" }), method(object({
|
|
@@ -14466,27 +14528,6 @@ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSche
|
|
|
14466
14528
|
}), TestResultSchema, {
|
|
14467
14529
|
kind: "mutation",
|
|
14468
14530
|
auth: "admin"
|
|
14469
|
-
}), method(object({
|
|
14470
|
-
target: TargetSchema,
|
|
14471
|
-
/**
|
|
14472
|
-
* Duplicate flow: create a NEW target id while copying secrets from an
|
|
14473
|
-
* existing row. The UI never holds the stored token; blank / redacted
|
|
14474
|
-
* password fields are restored from this source (D634 still applies if
|
|
14475
|
-
* destinations diverge without a re-typed secret).
|
|
14476
|
-
*/
|
|
14477
|
-
cloneSecretsFrom: string().optional()
|
|
14478
|
-
}), TargetSchema, {
|
|
14479
|
-
kind: "mutation",
|
|
14480
|
-
auth: "admin"
|
|
14481
|
-
}), method(object({ targetId: string() }), _void(), {
|
|
14482
|
-
kind: "mutation",
|
|
14483
|
-
auth: "admin"
|
|
14484
|
-
}), method(object({
|
|
14485
|
-
targetId: string(),
|
|
14486
|
-
enabled: boolean()
|
|
14487
|
-
}), _void(), {
|
|
14488
|
-
kind: "mutation",
|
|
14489
|
-
auth: "admin"
|
|
14490
14531
|
});
|
|
14491
14532
|
looseObject({
|
|
14492
14533
|
name: string().min(1),
|
|
@@ -22754,7 +22795,6 @@ var SYSTEM_CAP_VOCABULARY = {
|
|
|
22754
22795
|
"notification-output": system("notification delivery — reached through notifier devices and rules"),
|
|
22755
22796
|
"notification-rules": system("notification rules — authored on their own page"),
|
|
22756
22797
|
"oauth-integration": system(IDENTITY),
|
|
22757
|
-
"oidc-connections": system(IDENTITY),
|
|
22758
22798
|
"osd-manager": system(PIPELINE),
|
|
22759
22799
|
"pipeline-executor": system(PIPELINE),
|
|
22760
22800
|
"pipeline-orchestrator": system(PIPELINE),
|
|
@@ -54489,7 +54529,7 @@ method(_void(), array(IntegrationWithStateSchema)), method(object({ id: string()
|
|
|
54489
54529
|
* or the redaction token KEEPS the stored secret; `{ $secretClear: true }`
|
|
54490
54530
|
* clears it.
|
|
54491
54531
|
*/
|
|
54492
|
-
var ConfigSchemaPassthrough$
|
|
54532
|
+
var ConfigSchemaPassthrough$2 = custom();
|
|
54493
54533
|
var IntegrationInstanceIdSchema = string().min(1);
|
|
54494
54534
|
var IntegrationInstanceModeSchema = _enum(["single", "multiple"]);
|
|
54495
54535
|
/**
|
|
@@ -54535,7 +54575,16 @@ var IntegrationInstanceKindSchema = object({
|
|
|
54535
54575
|
/** Relative hub path to start an interactive account link of an instance of this kind. */
|
|
54536
54576
|
connectPath: string().min(1).optional(),
|
|
54537
54577
|
/** Relative hub path to disconnect that account. */
|
|
54538
|
-
disconnectPath: string().min(1).optional()
|
|
54578
|
+
disconnectPath: string().min(1).optional(),
|
|
54579
|
+
/**
|
|
54580
|
+
* Parts of the edit dialog the flat form cannot draw (a node picker, a model source), named by a
|
|
54581
|
+
* GENERIC widget id the client maps to a component; a client that knows none of them shows none.
|
|
54582
|
+
* `connection` widgets write connection values, `model` widgets own the model choice.
|
|
54583
|
+
*/
|
|
54584
|
+
widgets: array(object({
|
|
54585
|
+
id: string().min(1),
|
|
54586
|
+
placement: _enum(["connection", "model"])
|
|
54587
|
+
})).optional()
|
|
54539
54588
|
});
|
|
54540
54589
|
/**
|
|
54541
54590
|
* How devices of an instance are found. `none`: the operator adds them by hand; `lan`: the addon
|
|
@@ -54640,7 +54689,7 @@ var integrationInstancesCapability = {
|
|
|
54640
54689
|
id: IntegrationInstanceIdSchema.nullable(),
|
|
54641
54690
|
/** The kind of the create form (`id: null`) of a provider with several. */
|
|
54642
54691
|
kind: string().min(1).optional()
|
|
54643
|
-
}), ConfigSchemaPassthrough$
|
|
54692
|
+
}), ConfigSchemaPassthrough$2, { auth: "admin" }),
|
|
54644
54693
|
listInstances: method(_void(), array(IntegrationInstanceSchema).readonly(), { auth: "admin" }),
|
|
54645
54694
|
getInstance: method(object({ id: IntegrationInstanceIdSchema }), IntegrationInstanceSchema.nullable(), { auth: "admin" }),
|
|
54646
54695
|
/**
|
|
@@ -55591,12 +55640,12 @@ var LlmModelInfoSchema = object({
|
|
|
55591
55640
|
});
|
|
55592
55641
|
/**
|
|
55593
55642
|
* The provider-specific part of a profile, validated by the provider that owns
|
|
55594
|
-
* the kind (
|
|
55643
|
+
* the kind (saving an instance refuses what it does not accept). A field its
|
|
55595
55644
|
* `connectionSchema` declares `type: 'password'` is a secret: it is held in the
|
|
55596
55645
|
* keychain, never in the row, and reads back as the redaction marker.
|
|
55597
55646
|
*/
|
|
55598
55647
|
var LlmProviderConfigSchema = record(string(), unknown());
|
|
55599
|
-
|
|
55648
|
+
object({
|
|
55600
55649
|
id: string(),
|
|
55601
55650
|
name: string(),
|
|
55602
55651
|
/** The provider-declared kind (`LlmProfileKindDescriptor.kind`). */
|
|
@@ -55690,8 +55739,8 @@ var LlmProviderWidgetSchema = object({
|
|
|
55690
55739
|
/** ConfigUISchema tree passed through untyped on the wire (the
|
|
55691
55740
|
* notification-output `ConfigSchemaPassthrough` precedent at
|
|
55692
55741
|
* notification-output.cap.ts:151); the exported TS type re-tightens it. */
|
|
55693
|
-
var ConfigSchemaPassthrough$
|
|
55694
|
-
|
|
55742
|
+
var ConfigSchemaPassthrough$1 = unknown();
|
|
55743
|
+
object({
|
|
55695
55744
|
kind: LlmProfileKindSchema,
|
|
55696
55745
|
label: string(),
|
|
55697
55746
|
/** A generic icon name (`cloud`, `plug`, `cpu`) — never a glyph or a logo. */
|
|
@@ -55699,9 +55748,9 @@ var LlmProfileKindDescriptorSchema = object({
|
|
|
55699
55748
|
/** Stamped by each provider so the concat-fanned catalog stays routable. */
|
|
55700
55749
|
addonId: string(),
|
|
55701
55750
|
/** The provider's own fields (`providerConfig`); `password` fields are keychain-held. */
|
|
55702
|
-
connectionSchema: ConfigSchemaPassthrough$
|
|
55751
|
+
connectionSchema: ConfigSchemaPassthrough$1,
|
|
55703
55752
|
/** Provider fields that belong under "Advanced" (extra headers, runtime tuning). */
|
|
55704
|
-
advancedSchema: ConfigSchemaPassthrough$
|
|
55753
|
+
advancedSchema: ConfigSchemaPassthrough$1.optional(),
|
|
55705
55754
|
/** The kind's defaults; a model from `listModels` may override any of them. */
|
|
55706
55755
|
features: LlmModelFeaturesSchema,
|
|
55707
55756
|
/** `false` = the provider stamps `supportsVision` itself (from what a node reports). */
|
|
@@ -55830,20 +55879,7 @@ method(LlmGenerateBaseInputSchema, LlmGenerateResultSchema, {
|
|
|
55830
55879
|
}), method(object({
|
|
55831
55880
|
addonId: string().optional(),
|
|
55832
55881
|
requestId: string()
|
|
55833
|
-
}), _void(), { kind: "mutation" }), method(
|
|
55834
|
-
kind: "mutation",
|
|
55835
|
-
auth: "admin"
|
|
55836
|
-
}), method(RawSecretMigrationInputSchema, RawSecretMigrationReportSchema, {
|
|
55837
|
-
kind: "mutation",
|
|
55838
|
-
auth: "admin"
|
|
55839
|
-
}), method(ProfileRefInputSchema, _void(), {
|
|
55840
|
-
kind: "mutation",
|
|
55841
|
-
auth: "admin"
|
|
55842
|
-
}), method(ProfileRefInputSchema, LlmGenerateResultSchema, {
|
|
55843
|
-
kind: "mutation",
|
|
55844
|
-
auth: "admin",
|
|
55845
|
-
timeoutMs: AI_CAP_TRANSPORT_TIMEOUT_MS
|
|
55846
|
-
}), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
55882
|
+
}), _void(), { kind: "mutation" }), method(LlmListModelsInputSchema, LlmListModelsResultSchema, {
|
|
55847
55883
|
kind: "mutation",
|
|
55848
55884
|
auth: "admin"
|
|
55849
55885
|
}), method(object({}), array(LlmDefaultSchema)), method(object({
|
|
@@ -56838,20 +56874,7 @@ method(_void(), MeshStatusSchema), method(object({
|
|
|
56838
56874
|
/** Optional hostname override the host should advertise once joined. */
|
|
56839
56875
|
hostname: string().optional() }), object({
|
|
56840
56876
|
/** Authentication URL the operator should open in a browser. */
|
|
56841
|
-
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }))
|
|
56842
|
-
/** Optional auth key — when provided, probes the key validity
|
|
56843
|
-
* against the provider's API. Omit when already joined to
|
|
56844
|
-
* just ping the daemon. */
|
|
56845
|
-
authKey: string().optional() }), object({
|
|
56846
|
-
ok: boolean(),
|
|
56847
|
-
/** Provider-side identifier resolved by the probe (tailnet
|
|
56848
|
-
* name for Tailscale, network id for ZeroTier, etc.). */
|
|
56849
|
-
tenant: string().optional(),
|
|
56850
|
-
/** Daemon binary version, when reachable. */
|
|
56851
|
-
daemonVersion: string().optional(),
|
|
56852
|
-
/** Human-readable error when `ok: false`. */
|
|
56853
|
-
error: string().optional()
|
|
56854
|
-
}), { kind: "mutation" });
|
|
56877
|
+
loginUrl: string() }), { kind: "mutation" }), method(_void(), object({ left: literal(true) }), { kind: "mutation" }), method(_void(), object({ loggedOut: literal(true) }), { kind: "mutation" }), method(_void(), object({ peers: array(MeshPeerSchema).readonly() }));
|
|
56855
56878
|
object({
|
|
56856
56879
|
value: number().nullable().meta(readingMeta("device", { label: "Total" })),
|
|
56857
56880
|
lastFetchedAt: number()
|
|
@@ -66509,61 +66532,6 @@ var OauthIntegrationDescriptorSchema = object({
|
|
|
66509
66532
|
});
|
|
66510
66533
|
method(_void(), OauthIntegrationDescriptorSchema, { auth: "admin" });
|
|
66511
66534
|
/**
|
|
66512
|
-
* `oidc-connections` — CRUD for IdP rows under `auth-oidc` (D828 sibling).
|
|
66513
|
-
*
|
|
66514
|
-
* One hub-only singleton (`auth-oidc`). The Settings UI is a DataTable +
|
|
66515
|
-
* ItemFormDialog; there is no `editable-array` in `globalSettingsSchema`.
|
|
66516
|
-
* Operator-chosen `id` is the URL slug (`/addon/auth-oidc/<id>/…`) and is
|
|
66517
|
-
* immutable after create.
|
|
66518
|
-
*/
|
|
66519
|
-
var ConfigSchemaPassthrough$1 = unknown();
|
|
66520
|
-
var OidcConnectionSchema = object({
|
|
66521
|
-
id: string().min(1),
|
|
66522
|
-
displayName: string(),
|
|
66523
|
-
icon: string(),
|
|
66524
|
-
issuerUrl: string(),
|
|
66525
|
-
clientId: string(),
|
|
66526
|
-
/** Client id + secret present — never the secret value. */
|
|
66527
|
-
configured: boolean(),
|
|
66528
|
-
/**
|
|
66529
|
-
* Values for the connection form schema. `clientSecret` is a keychain
|
|
66530
|
-
* {@link SecretFieldView} or `null` / `''`, never plaintext (D789).
|
|
66531
|
-
*/
|
|
66532
|
-
formValues: record(string(), unknown()).optional()
|
|
66533
|
-
});
|
|
66534
|
-
/**
|
|
66535
|
-
* Patch one connection. Omitted or empty `clientSecret` keeps the stored
|
|
66536
|
-
* secret (D787). `{ $secretClear: true }` clears it. `id` is never renamed.
|
|
66537
|
-
*/
|
|
66538
|
-
var OidcConnectionUpdateInputSchema = object({
|
|
66539
|
-
id: string().min(1),
|
|
66540
|
-
displayName: string().min(1),
|
|
66541
|
-
icon: string().optional(),
|
|
66542
|
-
issuerUrl: string().optional(),
|
|
66543
|
-
clientId: string().optional(),
|
|
66544
|
-
clientSecret: union([string(), object({ $secretClear: literal(true) })]).optional(),
|
|
66545
|
-
redirectUri: string().optional(),
|
|
66546
|
-
scopes: string().optional(),
|
|
66547
|
-
usernameClaim: _enum([
|
|
66548
|
-
"preferred_username",
|
|
66549
|
-
"email",
|
|
66550
|
-
"sub"
|
|
66551
|
-
]).optional()
|
|
66552
|
-
});
|
|
66553
|
-
method(object({}), ConfigSchemaPassthrough$1, { auth: "admin" }), method(object({}), array(OidcConnectionSchema).readonly(), { auth: "admin" }), method(object({
|
|
66554
|
-
id: string().min(1).regex(/^[a-z0-9][a-z0-9-]{0,63}$/, "id must be a lowercase slug"),
|
|
66555
|
-
displayName: string().min(1)
|
|
66556
|
-
}), object({ id: string() }), {
|
|
66557
|
-
kind: "mutation",
|
|
66558
|
-
auth: "admin"
|
|
66559
|
-
}), method(OidcConnectionUpdateInputSchema, object({ ok: literal(true) }), {
|
|
66560
|
-
kind: "mutation",
|
|
66561
|
-
auth: "admin"
|
|
66562
|
-
}), method(object({ id: string().min(1) }), object({ ok: literal(true) }), {
|
|
66563
|
-
kind: "mutation",
|
|
66564
|
-
auth: "admin"
|
|
66565
|
-
});
|
|
66566
|
-
/**
|
|
66567
66535
|
* Generic on-screen-display (video overlay) cap. Each camera exposes
|
|
66568
66536
|
* a firmware-defined list of overlays (channel name, timestamp,
|
|
66569
66537
|
* watermark, logo, …); the cap models them as a homogeneous array of
|
|
@@ -72749,21 +72717,6 @@ method(object({
|
|
|
72749
72717
|
*/
|
|
72750
72718
|
ttlSec: union([number().int().positive(), literal("never")]).optional()
|
|
72751
72719
|
}), object({ token: string() }), { auth: "admin" }), method(object({ token: string() }), SsoBridgeClaimsSchema.nullable(), { auth: "admin" });
|
|
72752
|
-
var ProviderListEntrySchema = discriminatedUnion("shouldSaveDiskSpace", [object({
|
|
72753
|
-
providerId: string().min(1),
|
|
72754
|
-
displayName: string().min(1),
|
|
72755
|
-
configSchema: unknown(),
|
|
72756
|
-
nodeLocal: boolean(),
|
|
72757
|
-
shouldSaveDiskSpace: literal(true),
|
|
72758
|
-
minFreePercent: number().min(0).max(100)
|
|
72759
|
-
}), object({
|
|
72760
|
-
providerId: string().min(1),
|
|
72761
|
-
displayName: string().min(1),
|
|
72762
|
-
configSchema: unknown(),
|
|
72763
|
-
nodeLocal: boolean(),
|
|
72764
|
-
shouldSaveDiskSpace: literal(false),
|
|
72765
|
-
minFreePercent: literal(null)
|
|
72766
|
-
})]);
|
|
72767
72720
|
method(object({
|
|
72768
72721
|
location: StorageLocationRefSchema,
|
|
72769
72722
|
relativePath: string()
|
|
@@ -72825,42 +72778,7 @@ method(object({
|
|
|
72825
72778
|
}), _instanceof(Uint8Array), { auth: "admin" }), method(object({ downloadId: string() }), _void(), {
|
|
72826
72779
|
kind: "mutation",
|
|
72827
72780
|
auth: "admin"
|
|
72828
|
-
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(
|
|
72829
|
-
createdAt: true,
|
|
72830
|
-
updatedAt: true
|
|
72831
|
-
}), StorageLocationSchema, {
|
|
72832
|
-
kind: "mutation",
|
|
72833
|
-
auth: "admin"
|
|
72834
|
-
}), method(object({
|
|
72835
|
-
id: string(),
|
|
72836
|
-
force: boolean().optional()
|
|
72837
|
-
}), _void(), {
|
|
72838
|
-
kind: "mutation",
|
|
72839
|
-
auth: "admin"
|
|
72840
|
-
}), method(_void(), array(StorageDrainProgressSchema).readonly()), method(object({ id: string() }), object({
|
|
72841
|
-
ok: boolean(),
|
|
72842
|
-
error: string().optional()
|
|
72843
|
-
}), { auth: "admin" }), method(_void(), array(ProviderListEntrySchema).readonly()), method(object({
|
|
72844
|
-
providerId: string(),
|
|
72845
|
-
/**
|
|
72846
|
-
* The location this config is an UNSAVED edit of, when there is one.
|
|
72847
|
-
*
|
|
72848
|
-
* `listLocations` replaces every declared secret with the redaction
|
|
72849
|
-
* sentinel, so the edit modal's form state holds the sentinel for any
|
|
72850
|
-
* credential the operator did not retype — and posting that here
|
|
72851
|
-
* without a way to resolve it makes the provider try to authenticate
|
|
72852
|
-
* as `__camstack_redacted__` and report the operator's own working
|
|
72853
|
-
* password as wrong. Given this id, the orchestrator restores each
|
|
72854
|
-
* sentinel from the stored config (same rule as `upsertLocation`)
|
|
72855
|
-
* before dispatching. Omitted by the "Add location" wizard, where
|
|
72856
|
-
* every value was typed just now and nothing is stored yet.
|
|
72857
|
-
*/
|
|
72858
|
-
locationId: string().optional(),
|
|
72859
|
-
config: record(string(), unknown())
|
|
72860
|
-
}), object({
|
|
72861
|
-
ok: boolean(),
|
|
72862
|
-
error: string().optional()
|
|
72863
|
-
}), { auth: "admin" });
|
|
72781
|
+
}), method(object({ type: StorageLocationTypeSchema.optional() }), array(StorageLocationSchema).readonly()), method(_void(), array(StorageLocationDeclarationSchema).readonly()), method(_void(), array(StorageDrainProgressSchema).readonly());
|
|
72864
72782
|
/** One table of the settings database. */
|
|
72865
72783
|
var StorageTableSchema = object({
|
|
72866
72784
|
/** The table's full name, e.g. `recorder:addon-settings` or `addon-device-settings`. */
|
|
@@ -80453,13 +80371,6 @@ Object.freeze({
|
|
|
80453
80371
|
access: "delete",
|
|
80454
80372
|
role: "admin"
|
|
80455
80373
|
},
|
|
80456
|
-
"llm.deleteProfile": {
|
|
80457
|
-
capName: "llm",
|
|
80458
|
-
capScope: "system",
|
|
80459
|
-
addonId: null,
|
|
80460
|
-
access: "delete",
|
|
80461
|
-
role: "admin"
|
|
80462
|
-
},
|
|
80463
80374
|
"llm.generate": {
|
|
80464
80375
|
capName: "llm",
|
|
80465
80376
|
capScope: "system",
|
|
@@ -80523,20 +80434,6 @@ Object.freeze({
|
|
|
80523
80434
|
access: "view",
|
|
80524
80435
|
role: "admin"
|
|
80525
80436
|
},
|
|
80526
|
-
"llm.listProfileKinds": {
|
|
80527
|
-
capName: "llm",
|
|
80528
|
-
capScope: "system",
|
|
80529
|
-
addonId: null,
|
|
80530
|
-
access: "view",
|
|
80531
|
-
role: "admin"
|
|
80532
|
-
},
|
|
80533
|
-
"llm.listProfiles": {
|
|
80534
|
-
capName: "llm",
|
|
80535
|
-
capScope: "system",
|
|
80536
|
-
addonId: null,
|
|
80537
|
-
access: "view",
|
|
80538
|
-
role: "admin"
|
|
80539
|
-
},
|
|
80540
80437
|
"llm.listRuntimeNodes": {
|
|
80541
80438
|
capName: "llm",
|
|
80542
80439
|
capScope: "system",
|
|
@@ -80544,13 +80441,6 @@ Object.freeze({
|
|
|
80544
80441
|
access: "view",
|
|
80545
80442
|
role: "admin"
|
|
80546
80443
|
},
|
|
80547
|
-
"llm.migrateRawSecrets": {
|
|
80548
|
-
capName: "llm",
|
|
80549
|
-
capScope: "system",
|
|
80550
|
-
addonId: null,
|
|
80551
|
-
access: "create",
|
|
80552
|
-
role: "admin"
|
|
80553
|
-
},
|
|
80554
80444
|
"llm.resolveModelRef": {
|
|
80555
80445
|
capName: "llm",
|
|
80556
80446
|
capScope: "system",
|
|
@@ -80579,20 +80469,6 @@ Object.freeze({
|
|
|
80579
80469
|
access: "create",
|
|
80580
80470
|
role: "admin"
|
|
80581
80471
|
},
|
|
80582
|
-
"llm.testProfile": {
|
|
80583
|
-
capName: "llm",
|
|
80584
|
-
capScope: "system",
|
|
80585
|
-
addonId: null,
|
|
80586
|
-
access: "create",
|
|
80587
|
-
role: "admin"
|
|
80588
|
-
},
|
|
80589
|
-
"llm.upsertProfile": {
|
|
80590
|
-
capName: "llm",
|
|
80591
|
-
capScope: "system",
|
|
80592
|
-
addonId: null,
|
|
80593
|
-
access: "create",
|
|
80594
|
-
role: "admin"
|
|
80595
|
-
},
|
|
80596
80472
|
"llmRuntime.appleAvailability": {
|
|
80597
80473
|
capName: "llm-runtime",
|
|
80598
80474
|
capScope: "system",
|
|
@@ -81097,13 +80973,6 @@ Object.freeze({
|
|
|
81097
80973
|
access: "create",
|
|
81098
80974
|
role: "admin"
|
|
81099
80975
|
},
|
|
81100
|
-
"meshNetwork.testConnection": {
|
|
81101
|
-
capName: "mesh-network",
|
|
81102
|
-
capScope: "system",
|
|
81103
|
-
addonId: null,
|
|
81104
|
-
access: "create",
|
|
81105
|
-
role: "admin"
|
|
81106
|
-
},
|
|
81107
80976
|
"meter.getStatus": {
|
|
81108
80977
|
capName: "meter",
|
|
81109
80978
|
capScope: "device",
|
|
@@ -81762,13 +81631,6 @@ Object.freeze({
|
|
|
81762
81631
|
access: "create",
|
|
81763
81632
|
role: "admin"
|
|
81764
81633
|
},
|
|
81765
|
-
"notificationOutput.deleteTarget": {
|
|
81766
|
-
capName: "notification-output",
|
|
81767
|
-
capScope: "system",
|
|
81768
|
-
addonId: null,
|
|
81769
|
-
access: "delete",
|
|
81770
|
-
role: "admin"
|
|
81771
|
-
},
|
|
81772
81634
|
"notificationOutput.discoverTargets": {
|
|
81773
81635
|
capName: "notification-output",
|
|
81774
81636
|
capScope: "system",
|
|
@@ -81776,13 +81638,6 @@ Object.freeze({
|
|
|
81776
81638
|
access: "view",
|
|
81777
81639
|
role: "admin"
|
|
81778
81640
|
},
|
|
81779
|
-
"notificationOutput.getTarget": {
|
|
81780
|
-
capName: "notification-output",
|
|
81781
|
-
capScope: "system",
|
|
81782
|
-
addonId: null,
|
|
81783
|
-
access: "view",
|
|
81784
|
-
role: "admin"
|
|
81785
|
-
},
|
|
81786
81641
|
"notificationOutput.listTargetKinds": {
|
|
81787
81642
|
capName: "notification-output",
|
|
81788
81643
|
capScope: "system",
|
|
@@ -81790,13 +81645,6 @@ Object.freeze({
|
|
|
81790
81645
|
access: "view",
|
|
81791
81646
|
role: "admin"
|
|
81792
81647
|
},
|
|
81793
|
-
"notificationOutput.listTargets": {
|
|
81794
|
-
capName: "notification-output",
|
|
81795
|
-
capScope: "system",
|
|
81796
|
-
addonId: null,
|
|
81797
|
-
access: "view",
|
|
81798
|
-
role: "admin"
|
|
81799
|
-
},
|
|
81800
81648
|
"notificationOutput.probeTargetConfig": {
|
|
81801
81649
|
capName: "notification-output",
|
|
81802
81650
|
capScope: "system",
|
|
@@ -81811,13 +81659,6 @@ Object.freeze({
|
|
|
81811
81659
|
access: "create",
|
|
81812
81660
|
role: "admin"
|
|
81813
81661
|
},
|
|
81814
|
-
"notificationOutput.setTargetEnabled": {
|
|
81815
|
-
capName: "notification-output",
|
|
81816
|
-
capScope: "system",
|
|
81817
|
-
addonId: null,
|
|
81818
|
-
access: "create",
|
|
81819
|
-
role: "admin"
|
|
81820
|
-
},
|
|
81821
81662
|
"notificationOutput.testTarget": {
|
|
81822
81663
|
capName: "notification-output",
|
|
81823
81664
|
capScope: "system",
|
|
@@ -81825,13 +81666,6 @@ Object.freeze({
|
|
|
81825
81666
|
access: "create",
|
|
81826
81667
|
role: "admin"
|
|
81827
81668
|
},
|
|
81828
|
-
"notificationOutput.upsertTarget": {
|
|
81829
|
-
capName: "notification-output",
|
|
81830
|
-
capScope: "system",
|
|
81831
|
-
addonId: null,
|
|
81832
|
-
access: "create",
|
|
81833
|
-
role: "admin"
|
|
81834
|
-
},
|
|
81835
81669
|
"notificationRules.activateAlarmProfile": {
|
|
81836
81670
|
capName: "notification-rules",
|
|
81837
81671
|
capScope: "system",
|
|
@@ -82091,41 +81925,6 @@ Object.freeze({
|
|
|
82091
81925
|
access: "view",
|
|
82092
81926
|
role: "admin"
|
|
82093
81927
|
},
|
|
82094
|
-
"oidcConnections.connectionFormSchema": {
|
|
82095
|
-
capName: "oidc-connections",
|
|
82096
|
-
capScope: "system",
|
|
82097
|
-
addonId: null,
|
|
82098
|
-
access: "view",
|
|
82099
|
-
role: "admin"
|
|
82100
|
-
},
|
|
82101
|
-
"oidcConnections.createConnection": {
|
|
82102
|
-
capName: "oidc-connections",
|
|
82103
|
-
capScope: "system",
|
|
82104
|
-
addonId: null,
|
|
82105
|
-
access: "create",
|
|
82106
|
-
role: "admin"
|
|
82107
|
-
},
|
|
82108
|
-
"oidcConnections.deleteConnection": {
|
|
82109
|
-
capName: "oidc-connections",
|
|
82110
|
-
capScope: "system",
|
|
82111
|
-
addonId: null,
|
|
82112
|
-
access: "delete",
|
|
82113
|
-
role: "admin"
|
|
82114
|
-
},
|
|
82115
|
-
"oidcConnections.listConnections": {
|
|
82116
|
-
capName: "oidc-connections",
|
|
82117
|
-
capScope: "system",
|
|
82118
|
-
addonId: null,
|
|
82119
|
-
access: "view",
|
|
82120
|
-
role: "admin"
|
|
82121
|
-
},
|
|
82122
|
-
"oidcConnections.updateConnection": {
|
|
82123
|
-
capName: "oidc-connections",
|
|
82124
|
-
capScope: "system",
|
|
82125
|
-
addonId: null,
|
|
82126
|
-
access: "create",
|
|
82127
|
-
role: "admin"
|
|
82128
|
-
},
|
|
82129
81928
|
"osd.getStatus": {
|
|
82130
81929
|
capName: "osd",
|
|
82131
81930
|
capScope: "device",
|
|
@@ -85157,13 +84956,6 @@ Object.freeze({
|
|
|
85157
84956
|
access: "delete",
|
|
85158
84957
|
role: "admin"
|
|
85159
84958
|
},
|
|
85160
|
-
"storage.deleteLocation": {
|
|
85161
|
-
capName: "storage",
|
|
85162
|
-
capScope: "system",
|
|
85163
|
-
addonId: null,
|
|
85164
|
-
access: "delete",
|
|
85165
|
-
role: "admin"
|
|
85166
|
-
},
|
|
85167
84959
|
"storage.endDownload": {
|
|
85168
84960
|
capName: "storage",
|
|
85169
84961
|
capScope: "system",
|
|
@@ -85220,13 +85012,6 @@ Object.freeze({
|
|
|
85220
85012
|
access: "view",
|
|
85221
85013
|
role: "admin"
|
|
85222
85014
|
},
|
|
85223
|
-
"storage.listProviders": {
|
|
85224
|
-
capName: "storage",
|
|
85225
|
-
capScope: "system",
|
|
85226
|
-
addonId: null,
|
|
85227
|
-
access: "view",
|
|
85228
|
-
role: "admin"
|
|
85229
|
-
},
|
|
85230
85015
|
"storage.read": {
|
|
85231
85016
|
capName: "storage",
|
|
85232
85017
|
capScope: "system",
|
|
@@ -85248,27 +85033,6 @@ Object.freeze({
|
|
|
85248
85033
|
access: "view",
|
|
85249
85034
|
role: "admin"
|
|
85250
85035
|
},
|
|
85251
|
-
"storage.testConfig": {
|
|
85252
|
-
capName: "storage",
|
|
85253
|
-
capScope: "system",
|
|
85254
|
-
addonId: null,
|
|
85255
|
-
access: "view",
|
|
85256
|
-
role: "admin"
|
|
85257
|
-
},
|
|
85258
|
-
"storage.testLocation": {
|
|
85259
|
-
capName: "storage",
|
|
85260
|
-
capScope: "system",
|
|
85261
|
-
addonId: null,
|
|
85262
|
-
access: "view",
|
|
85263
|
-
role: "admin"
|
|
85264
|
-
},
|
|
85265
|
-
"storage.upsertLocation": {
|
|
85266
|
-
capName: "storage",
|
|
85267
|
-
capScope: "system",
|
|
85268
|
-
addonId: null,
|
|
85269
|
-
access: "create",
|
|
85270
|
-
role: "admin"
|
|
85271
|
-
},
|
|
85272
85036
|
"storage.write": {
|
|
85273
85037
|
capName: "storage",
|
|
85274
85038
|
capScope: "system",
|
|
@@ -91821,222 +91585,6 @@ var GoogleBrokerRegistry = class {
|
|
|
91821
91585
|
}
|
|
91822
91586
|
};
|
|
91823
91587
|
//#endregion
|
|
91824
|
-
//#region src/google-settings-copy.ts
|
|
91825
|
-
/**
|
|
91826
|
-
* Operator-facing setup copy for Connectivity → Calendars / Email.
|
|
91827
|
-
* Keep Connect as a same-origin relative link so the admin session cookie
|
|
91828
|
-
* rides along (an absolute Public URL from a LAN admin tab drops the cookie).
|
|
91829
|
-
* Root-relative hrefs must survive `sanitizeInfoHtml` in ui-library.
|
|
91830
|
-
*/
|
|
91831
|
-
/** Enable APIs library in Google Cloud Console. */
|
|
91832
|
-
var GOOGLE_CONSOLE_APIS_URL = "https://console.cloud.google.com/apis/library";
|
|
91833
|
-
/** Create / manage OAuth Web clients. */
|
|
91834
|
-
var GOOGLE_CONSOLE_CREDENTIALS_URL = "https://console.cloud.google.com/apis/credentials";
|
|
91835
|
-
function redirectUriDisplay(publicOrigin) {
|
|
91836
|
-
if (publicOrigin === null || publicOrigin.length === 0) return `<public-hub>${OAUTH_CALLBACK_SUFFIX}`;
|
|
91837
|
-
return `${publicOrigin.replace(/\/$/, "")}${OAUTH_CALLBACK_SUFFIX}`;
|
|
91838
|
-
}
|
|
91839
|
-
function consoleLinksHtml$1() {
|
|
91840
|
-
return [
|
|
91841
|
-
`<a href="${GOOGLE_CONSOLE_APIS_URL}">API library</a>`,
|
|
91842
|
-
` · `,
|
|
91843
|
-
`<a href="${GOOGLE_CONSOLE_CREDENTIALS_URL}">Credentials</a>`
|
|
91844
|
-
].join("");
|
|
91845
|
-
}
|
|
91846
|
-
function introHtml(cap, publicOrigin) {
|
|
91847
|
-
const redirect = escapeHtml$1(redirectUriDisplay(publicOrigin));
|
|
91848
|
-
const console = consoleLinksHtml$1();
|
|
91849
|
-
if (cap === "smtp-provider") return [
|
|
91850
|
-
"<ol>",
|
|
91851
|
-
`<li>Open Google Cloud Console (${console}) and enable the <strong>Gmail API</strong> (and Calendar API if you also use Calendars).</li>`,
|
|
91852
|
-
"<li>Under Credentials, create an OAuth client of type <strong>Web application</strong>.</li>",
|
|
91853
|
-
`<li>Add this authorized redirect URI (Network → <strong>Public endpoint</strong>, not Internal): <code>${redirect}</code></li>`,
|
|
91854
|
-
"<li>Paste Client ID and Client secret below, then <strong>Save</strong>.</li>",
|
|
91855
|
-
`<li>Open <a href="${OAUTH_START_PATH}">Connect Google</a> while signed in as admin (same browser tab as this hub).</li>`,
|
|
91856
|
-
"<li>Set From address (connected account or a verified send-as). Turn this integration off with the page <strong>Enable</strong> toggle when you do not want Gmail send — Calendar can stay connected.</li>",
|
|
91857
|
-
"</ol>"
|
|
91858
|
-
].join("");
|
|
91859
|
-
if (cap === "calendar-source") return [
|
|
91860
|
-
"<ol>",
|
|
91861
|
-
`<li>Open Google Cloud Console (${console}) and enable the <strong>Google Calendar API</strong> (and Gmail API if you also use Email).</li>`,
|
|
91862
|
-
"<li>Under Credentials, create an OAuth client of type <strong>Web application</strong>.</li>",
|
|
91863
|
-
`<li>Add this authorized redirect URI (Network → <strong>Public endpoint</strong>, not Internal): <code>${redirect}</code></li>`,
|
|
91864
|
-
"<li>Paste Client ID and Client secret below, then <strong>Save</strong>.</li>",
|
|
91865
|
-
`<li>Open <a href="${OAUTH_START_PATH}">Connect Google</a> while signed in as admin (same browser tab as this hub).</li>`,
|
|
91866
|
-
"<li>Optionally restrict which calendars are exposed with the filter below.</li>",
|
|
91867
|
-
"</ol>"
|
|
91868
|
-
].join("");
|
|
91869
|
-
return [
|
|
91870
|
-
"<ol>",
|
|
91871
|
-
`<li>Open Google Cloud Console (${console}) and enable <strong>Google Calendar API</strong> and <strong>Gmail API</strong>.</li>`,
|
|
91872
|
-
"<li>Create a <strong>Web application</strong> OAuth client under Credentials.</li>",
|
|
91873
|
-
`<li>Register redirect URI: <code>${redirect}</code> (Network → Public endpoint).</li>`,
|
|
91874
|
-
`<li>Paste Client ID / secret, Save, then <a href="${OAUTH_START_PATH}">Connect Google</a>.</li>`,
|
|
91875
|
-
"<li>Calendars and Email share one Google account; use each page’s <strong>Enable</strong> toggle to turn a capability off without revoking OAuth.</li>",
|
|
91876
|
-
"</ol>"
|
|
91877
|
-
].join("");
|
|
91878
|
-
}
|
|
91879
|
-
function connectHtml(cap, publicOrigin) {
|
|
91880
|
-
const redirect = escapeHtml$1(redirectUriDisplay(publicOrigin));
|
|
91881
|
-
if (cap === "smtp-provider") return [
|
|
91882
|
-
`After Save, open <a href="${OAUTH_START_PATH}">Connect Google</a> in this hub (admin session required). `,
|
|
91883
|
-
"Connect requests <code>gmail.send</code> (and Calendar read for the Calendars page). ",
|
|
91884
|
-
`Google must list exactly: <code>${redirect}</code>. `,
|
|
91885
|
-
"If an older Connect predates Gmail send, revoke CamStack in Google Account → Security and Connect again. ",
|
|
91886
|
-
`Console: ${consoleLinksHtml$1()}.`
|
|
91887
|
-
].join("");
|
|
91888
|
-
if (cap === "calendar-source") return [
|
|
91889
|
-
`After Save, open <a href="${OAUTH_START_PATH}">Connect Google</a> in this hub (admin session required). `,
|
|
91890
|
-
"Connect requests <code>calendar.readonly</code> (and Gmail send for the Email page). ",
|
|
91891
|
-
`Google must list exactly: <code>${redirect}</code>. `,
|
|
91892
|
-
`Console: ${consoleLinksHtml$1()}.`
|
|
91893
|
-
].join("");
|
|
91894
|
-
return [
|
|
91895
|
-
`After Save, open <a href="${OAUTH_START_PATH}">Connect Google</a>. `,
|
|
91896
|
-
`Redirect URI registered in Google Cloud must be <code>${redirect}</code>. `,
|
|
91897
|
-
`Console: ${consoleLinksHtml$1()}.`
|
|
91898
|
-
].join("");
|
|
91899
|
-
}
|
|
91900
|
-
function escapeHtml$1(s) {
|
|
91901
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
91902
|
-
}
|
|
91903
|
-
//#endregion
|
|
91904
|
-
//#region src/google-broker-settings-schema.ts
|
|
91905
|
-
/**
|
|
91906
|
-
* Per-kind broker creation/edit form for kind=`google`.
|
|
91907
|
-
* Account linking (Sign in) is driven by the kind's `connectPath`
|
|
91908
|
-
* on the instances page — not a hard-coded Connect link in this form.
|
|
91909
|
-
*/
|
|
91910
|
-
function consoleLinksHtml() {
|
|
91911
|
-
return [
|
|
91912
|
-
`<a href="${GOOGLE_CONSOLE_APIS_URL}">API library</a>`,
|
|
91913
|
-
` · `,
|
|
91914
|
-
`<a href="${GOOGLE_CONSOLE_CREDENTIALS_URL}">Credentials</a>`
|
|
91915
|
-
].join("");
|
|
91916
|
-
}
|
|
91917
|
-
/** Setup steps shown on Add / Edit — includes Audience / Test users. */
|
|
91918
|
-
function googleBrokerSetupHtml(publicOrigin) {
|
|
91919
|
-
const redirect = escapeHtml(redirectUriDisplay(publicOrigin));
|
|
91920
|
-
return [
|
|
91921
|
-
"<ol>",
|
|
91922
|
-
`<li>Open Google Cloud Console (${consoleLinksHtml()}). Create a <strong>new project</strong> (or pick an existing one) from the project picker at the top.</li>`,
|
|
91923
|
-
"<li>In that project, enable <strong>Google Calendar API</strong> and/or <strong>Gmail API</strong> (API library).</li>",
|
|
91924
|
-
"<li>Open <strong>Google Auth Platform → Audience</strong> (or APIs & Services → OAuth consent screen → <strong>Audience</strong>). User type <strong>External</strong> + publishing status <strong>Testing</strong> is fine for a personal hub. Under <strong>Test users</strong>, add the Google account(s) that will Sign in — otherwise Google returns <code>403: access_denied</code>. (If you only see Branding / Data Access, open the <strong>Audience</strong> tab in the left sidebar of Google Auth Platform.) Publishing / verification is optional for a private hub.</li>",
|
|
91925
|
-
"<li>Under Credentials, create an OAuth client of type <strong>Web application</strong>.</li>",
|
|
91926
|
-
`<li>Add this authorized redirect URI (Network → <strong>Public endpoint</strong>, not Internal): <code>${redirect}</code></li>`,
|
|
91927
|
-
"<li>Paste Client ID and Client secret below. <strong>Test connection</strong> checks those with Google (not the account yet).</li>",
|
|
91928
|
-
"<li>Add the broker — the hub then opens Google sign-in in a popup to link the account (Calendar + Gmail). Use <strong>Sign in</strong> on the row if you skip or cancel.</li>",
|
|
91929
|
-
"</ol>"
|
|
91930
|
-
].join("");
|
|
91931
|
-
}
|
|
91932
|
-
function buildGoogleBrokerSettingsSchema(publicOrigin) {
|
|
91933
|
-
return { sections: [
|
|
91934
|
-
{
|
|
91935
|
-
id: "setup-intro",
|
|
91936
|
-
title: "Setup",
|
|
91937
|
-
titleKey: "google-services:googleBrokerSettings.s_setup-intro.title",
|
|
91938
|
-
description: "Google Cloud Console — register the hub redirect before Add / Sign in.",
|
|
91939
|
-
descriptionKey: "google-services:googleBrokerSettings.s_setup-intro.description",
|
|
91940
|
-
columns: 1,
|
|
91941
|
-
fields: [{
|
|
91942
|
-
type: "info",
|
|
91943
|
-
key: "_setupSteps",
|
|
91944
|
-
label: "Steps",
|
|
91945
|
-
labelKey: "google-services:googleBrokerSettings.s_setup-intro._setupSteps.label",
|
|
91946
|
-
format: "html",
|
|
91947
|
-
content: googleBrokerSetupHtml(publicOrigin)
|
|
91948
|
-
}]
|
|
91949
|
-
},
|
|
91950
|
-
{
|
|
91951
|
-
id: "google-oauth-client",
|
|
91952
|
-
title: "Google OAuth client",
|
|
91953
|
-
titleKey: "google-services:googleBrokerSettings.s_google-oauth-client.title",
|
|
91954
|
-
description: "Web application client from Google Cloud Console. The same Cloud project can be reused across Google brokers.",
|
|
91955
|
-
descriptionKey: "google-services:googleBrokerSettings.s_google-oauth-client.description",
|
|
91956
|
-
columns: 1,
|
|
91957
|
-
fields: [{
|
|
91958
|
-
type: "text",
|
|
91959
|
-
key: "clientId",
|
|
91960
|
-
label: "Client ID",
|
|
91961
|
-
labelKey: "google-services:googleBrokerSettings.s_google-oauth-client.clientId.label"
|
|
91962
|
-
}, {
|
|
91963
|
-
type: "password",
|
|
91964
|
-
key: "clientSecret",
|
|
91965
|
-
label: "Client secret",
|
|
91966
|
-
labelKey: "google-services:googleBrokerSettings.s_google-oauth-client.clientSecret.label",
|
|
91967
|
-
showToggle: true
|
|
91968
|
-
}]
|
|
91969
|
-
},
|
|
91970
|
-
{
|
|
91971
|
-
id: "gmail-send",
|
|
91972
|
-
title: "Gmail send",
|
|
91973
|
-
titleKey: "google-services:googleBrokerSettings.s_gmail-send.title",
|
|
91974
|
-
description: "From must be this connected account or a verified send-as. Disable Email on Connectivity to turn Gmail off without removing the broker.",
|
|
91975
|
-
descriptionKey: "google-services:googleBrokerSettings.s_gmail-send.description",
|
|
91976
|
-
columns: 1,
|
|
91977
|
-
fields: [{
|
|
91978
|
-
type: "text",
|
|
91979
|
-
key: "fromAddress",
|
|
91980
|
-
label: "From address",
|
|
91981
|
-
labelKey: "google-services:googleBrokerSettings.s_gmail-send.fromAddress.label",
|
|
91982
|
-
description: "Defaults to the connected Google account email when empty.",
|
|
91983
|
-
descriptionKey: "google-services:googleBrokerSettings.s_gmail-send.fromAddress.description"
|
|
91984
|
-
}, {
|
|
91985
|
-
type: "text",
|
|
91986
|
-
key: "fromName",
|
|
91987
|
-
label: "From display name (optional)",
|
|
91988
|
-
labelKey: "google-services:googleBrokerSettings.s_gmail-send.fromName.label"
|
|
91989
|
-
}]
|
|
91990
|
-
}
|
|
91991
|
-
] };
|
|
91992
|
-
}
|
|
91993
|
-
/** Connectivity Calendars / Email pages — the calendar import picker is on each broker. */
|
|
91994
|
-
function buildGoogleFeatureSettingsSchema(cap, publicOrigin) {
|
|
91995
|
-
const redirect = escapeHtml(redirectUriDisplay(publicOrigin));
|
|
91996
|
-
if (cap === "calendar-source") return { sections: [{
|
|
91997
|
-
id: "setup-intro",
|
|
91998
|
-
title: "Google brokers",
|
|
91999
|
-
titleKey: "google-services:googleFeatureSettings.s_setup-intro.title",
|
|
92000
|
-
columns: 1,
|
|
92001
|
-
fields: [{
|
|
92002
|
-
type: "info",
|
|
92003
|
-
key: "_setupSteps",
|
|
92004
|
-
label: "Setup",
|
|
92005
|
-
labelKey: "google-services:googleFeatureSettings.s_setup-intro._setupSteps.label",
|
|
92006
|
-
format: "html",
|
|
92007
|
-
content: [
|
|
92008
|
-
"<p>Link a Google account under Connectivity → <strong>Brokers</strong> ",
|
|
92009
|
-
"(Client ID / secret + Sign in), then add a calendar under Connectivity → <strong>Calendars</strong>. ",
|
|
92010
|
-
`OAuth redirect URI: <code>${redirect}</code>.</p>`
|
|
92011
|
-
].join("")
|
|
92012
|
-
}]
|
|
92013
|
-
}] };
|
|
92014
|
-
return { sections: [{
|
|
92015
|
-
id: "setup-intro",
|
|
92016
|
-
title: cap === "smtp-provider" ? "Gmail send uses Google brokers" : "Google brokers",
|
|
92017
|
-
columns: 1,
|
|
92018
|
-
fields: [{
|
|
92019
|
-
type: "info",
|
|
92020
|
-
key: "_setupSteps",
|
|
92021
|
-
label: "Setup",
|
|
92022
|
-
labelKey: "google-services:googleFeatureSettings._setupSteps.label",
|
|
92023
|
-
format: "html",
|
|
92024
|
-
content: cap === "smtp-provider" ? [
|
|
92025
|
-
"<p>Add or edit a <strong>Google</strong> broker under Connectivity → <strong>Brokers</strong> ",
|
|
92026
|
-
"(Client ID / secret + Sign in). From address and send-as live on that broker. ",
|
|
92027
|
-
`OAuth redirect URI: <code>${redirect}</code>.</p>`
|
|
92028
|
-
].join("") : [
|
|
92029
|
-
"<p>Add or edit a <strong>Google</strong> broker under Connectivity → <strong>Brokers</strong> ",
|
|
92030
|
-
"(Client ID / secret + Sign in). ",
|
|
92031
|
-
`OAuth redirect URI: <code>${redirect}</code>.</p>`
|
|
92032
|
-
].join("")
|
|
92033
|
-
}]
|
|
92034
|
-
}] };
|
|
92035
|
-
}
|
|
92036
|
-
function escapeHtml(s) {
|
|
92037
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
92038
|
-
}
|
|
92039
|
-
//#endregion
|
|
92040
91588
|
//#region src/google-calendar-source.ts
|
|
92041
91589
|
function parseGoogleInstant(value) {
|
|
92042
91590
|
const ms = Date.parse(value);
|
|
@@ -92557,6 +92105,179 @@ function buildGoogleCalendarInstances(records, deps) {
|
|
|
92557
92105
|
});
|
|
92558
92106
|
}
|
|
92559
92107
|
//#endregion
|
|
92108
|
+
//#region src/google-settings-copy.ts
|
|
92109
|
+
/**
|
|
92110
|
+
* Operator-facing setup copy for Connectivity → Calendars / Email.
|
|
92111
|
+
* Keep Connect as a same-origin relative link so the admin session cookie
|
|
92112
|
+
* rides along (an absolute Public URL from a LAN admin tab drops the cookie).
|
|
92113
|
+
* Root-relative hrefs must survive `sanitizeInfoHtml` in ui-library.
|
|
92114
|
+
*/
|
|
92115
|
+
/** Enable APIs library in Google Cloud Console. */
|
|
92116
|
+
var GOOGLE_CONSOLE_APIS_URL = "https://console.cloud.google.com/apis/library";
|
|
92117
|
+
/** Create / manage OAuth Web clients. */
|
|
92118
|
+
var GOOGLE_CONSOLE_CREDENTIALS_URL = "https://console.cloud.google.com/apis/credentials";
|
|
92119
|
+
function redirectUriDisplay(publicOrigin) {
|
|
92120
|
+
if (publicOrigin === null || publicOrigin.length === 0) return `<public-hub>${OAUTH_CALLBACK_SUFFIX}`;
|
|
92121
|
+
return `${publicOrigin.replace(/\/$/, "")}${OAUTH_CALLBACK_SUFFIX}`;
|
|
92122
|
+
}
|
|
92123
|
+
function consoleLinksHtml$1() {
|
|
92124
|
+
return [
|
|
92125
|
+
`<a href="${GOOGLE_CONSOLE_APIS_URL}">API library</a>`,
|
|
92126
|
+
` · `,
|
|
92127
|
+
`<a href="${GOOGLE_CONSOLE_CREDENTIALS_URL}">Credentials</a>`
|
|
92128
|
+
].join("");
|
|
92129
|
+
}
|
|
92130
|
+
function introHtml(cap, publicOrigin) {
|
|
92131
|
+
const redirect = escapeHtml$1(redirectUriDisplay(publicOrigin));
|
|
92132
|
+
const console = consoleLinksHtml$1();
|
|
92133
|
+
if (cap === "smtp-provider") return [
|
|
92134
|
+
"<ol>",
|
|
92135
|
+
`<li>Open Google Cloud Console (${console}) and enable the <strong>Gmail API</strong> (and Calendar API if you also use Calendars).</li>`,
|
|
92136
|
+
"<li>Under Credentials, create an OAuth client of type <strong>Web application</strong>.</li>",
|
|
92137
|
+
`<li>Add this authorized redirect URI (Network → <strong>Public endpoint</strong>, not Internal): <code>${redirect}</code></li>`,
|
|
92138
|
+
"<li>Paste Client ID and Client secret below, then <strong>Save</strong>.</li>",
|
|
92139
|
+
`<li>Open <a href="${OAUTH_START_PATH}">Connect Google</a> while signed in as admin (same browser tab as this hub).</li>`,
|
|
92140
|
+
"<li>Set From address (connected account or a verified send-as). Turn this integration off with the page <strong>Enable</strong> toggle when you do not want Gmail send — Calendar can stay connected.</li>",
|
|
92141
|
+
"</ol>"
|
|
92142
|
+
].join("");
|
|
92143
|
+
if (cap === "calendar-source") return [
|
|
92144
|
+
"<ol>",
|
|
92145
|
+
`<li>Open Google Cloud Console (${console}) and enable the <strong>Google Calendar API</strong> (and Gmail API if you also use Email).</li>`,
|
|
92146
|
+
"<li>Under Credentials, create an OAuth client of type <strong>Web application</strong>.</li>",
|
|
92147
|
+
`<li>Add this authorized redirect URI (Network → <strong>Public endpoint</strong>, not Internal): <code>${redirect}</code></li>`,
|
|
92148
|
+
"<li>Paste Client ID and Client secret below, then <strong>Save</strong>.</li>",
|
|
92149
|
+
`<li>Open <a href="${OAUTH_START_PATH}">Connect Google</a> while signed in as admin (same browser tab as this hub).</li>`,
|
|
92150
|
+
"<li>Optionally restrict which calendars are exposed with the filter below.</li>",
|
|
92151
|
+
"</ol>"
|
|
92152
|
+
].join("");
|
|
92153
|
+
return [
|
|
92154
|
+
"<ol>",
|
|
92155
|
+
`<li>Open Google Cloud Console (${console}) and enable <strong>Google Calendar API</strong> and <strong>Gmail API</strong>.</li>`,
|
|
92156
|
+
"<li>Create a <strong>Web application</strong> OAuth client under Credentials.</li>",
|
|
92157
|
+
`<li>Register redirect URI: <code>${redirect}</code> (Network → Public endpoint).</li>`,
|
|
92158
|
+
`<li>Paste Client ID / secret, Save, then <a href="${OAUTH_START_PATH}">Connect Google</a>.</li>`,
|
|
92159
|
+
"<li>Calendars and Email share one Google account; use each page’s <strong>Enable</strong> toggle to turn a capability off without revoking OAuth.</li>",
|
|
92160
|
+
"</ol>"
|
|
92161
|
+
].join("");
|
|
92162
|
+
}
|
|
92163
|
+
function connectHtml(cap, publicOrigin) {
|
|
92164
|
+
const redirect = escapeHtml$1(redirectUriDisplay(publicOrigin));
|
|
92165
|
+
if (cap === "smtp-provider") return [
|
|
92166
|
+
`After Save, open <a href="${OAUTH_START_PATH}">Connect Google</a> in this hub (admin session required). `,
|
|
92167
|
+
"Connect requests <code>gmail.send</code> (and Calendar read for the Calendars page). ",
|
|
92168
|
+
`Google must list exactly: <code>${redirect}</code>. `,
|
|
92169
|
+
"If an older Connect predates Gmail send, revoke CamStack in Google Account → Security and Connect again. ",
|
|
92170
|
+
`Console: ${consoleLinksHtml$1()}.`
|
|
92171
|
+
].join("");
|
|
92172
|
+
if (cap === "calendar-source") return [
|
|
92173
|
+
`After Save, open <a href="${OAUTH_START_PATH}">Connect Google</a> in this hub (admin session required). `,
|
|
92174
|
+
"Connect requests <code>calendar.readonly</code> (and Gmail send for the Email page). ",
|
|
92175
|
+
`Google must list exactly: <code>${redirect}</code>. `,
|
|
92176
|
+
`Console: ${consoleLinksHtml$1()}.`
|
|
92177
|
+
].join("");
|
|
92178
|
+
return [
|
|
92179
|
+
`After Save, open <a href="${OAUTH_START_PATH}">Connect Google</a>. `,
|
|
92180
|
+
`Redirect URI registered in Google Cloud must be <code>${redirect}</code>. `,
|
|
92181
|
+
`Console: ${consoleLinksHtml$1()}.`
|
|
92182
|
+
].join("");
|
|
92183
|
+
}
|
|
92184
|
+
function escapeHtml$1(s) {
|
|
92185
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
92186
|
+
}
|
|
92187
|
+
//#endregion
|
|
92188
|
+
//#region src/google-broker-settings-schema.ts
|
|
92189
|
+
/**
|
|
92190
|
+
* Per-kind broker creation/edit form for kind=`google`.
|
|
92191
|
+
* Account linking (Sign in) is driven by the kind's `connectPath`
|
|
92192
|
+
* on the instances page — not a hard-coded Connect link in this form.
|
|
92193
|
+
*/
|
|
92194
|
+
function consoleLinksHtml() {
|
|
92195
|
+
return [
|
|
92196
|
+
`<a href="${GOOGLE_CONSOLE_APIS_URL}">API library</a>`,
|
|
92197
|
+
` · `,
|
|
92198
|
+
`<a href="${GOOGLE_CONSOLE_CREDENTIALS_URL}">Credentials</a>`
|
|
92199
|
+
].join("");
|
|
92200
|
+
}
|
|
92201
|
+
/** Setup steps shown on Add / Edit — includes Audience / Test users. */
|
|
92202
|
+
function googleBrokerSetupHtml(publicOrigin) {
|
|
92203
|
+
const redirect = escapeHtml(redirectUriDisplay(publicOrigin));
|
|
92204
|
+
return [
|
|
92205
|
+
"<ol>",
|
|
92206
|
+
`<li>Open Google Cloud Console (${consoleLinksHtml()}). Create a <strong>new project</strong> (or pick an existing one) from the project picker at the top.</li>`,
|
|
92207
|
+
"<li>In that project, enable <strong>Google Calendar API</strong> and/or <strong>Gmail API</strong> (API library).</li>",
|
|
92208
|
+
"<li>Open <strong>Google Auth Platform → Audience</strong> (or APIs & Services → OAuth consent screen → <strong>Audience</strong>). User type <strong>External</strong> + publishing status <strong>Testing</strong> is fine for a personal hub. Under <strong>Test users</strong>, add the Google account(s) that will Sign in — otherwise Google returns <code>403: access_denied</code>. (If you only see Branding / Data Access, open the <strong>Audience</strong> tab in the left sidebar of Google Auth Platform.) Publishing / verification is optional for a private hub.</li>",
|
|
92209
|
+
"<li>Under Credentials, create an OAuth client of type <strong>Web application</strong>.</li>",
|
|
92210
|
+
`<li>Add this authorized redirect URI (Network → <strong>Public endpoint</strong>, not Internal): <code>${redirect}</code></li>`,
|
|
92211
|
+
"<li>Paste Client ID and Client secret below. <strong>Test connection</strong> checks those with Google (not the account yet).</li>",
|
|
92212
|
+
"<li>Add the broker — the hub then opens Google sign-in in a popup to link the account (Calendar + Gmail). Use <strong>Sign in</strong> on the row if you skip or cancel.</li>",
|
|
92213
|
+
"</ol>"
|
|
92214
|
+
].join("");
|
|
92215
|
+
}
|
|
92216
|
+
function buildGoogleBrokerSettingsSchema(publicOrigin) {
|
|
92217
|
+
return { sections: [
|
|
92218
|
+
{
|
|
92219
|
+
id: "setup-intro",
|
|
92220
|
+
title: "Setup",
|
|
92221
|
+
titleKey: "google-services:googleBrokerSettings.s_setup-intro.title",
|
|
92222
|
+
description: "Google Cloud Console — register the hub redirect before Add / Sign in.",
|
|
92223
|
+
descriptionKey: "google-services:googleBrokerSettings.s_setup-intro.description",
|
|
92224
|
+
columns: 1,
|
|
92225
|
+
fields: [{
|
|
92226
|
+
type: "info",
|
|
92227
|
+
key: "_setupSteps",
|
|
92228
|
+
label: "Steps",
|
|
92229
|
+
labelKey: "google-services:googleBrokerSettings.s_setup-intro._setupSteps.label",
|
|
92230
|
+
format: "html",
|
|
92231
|
+
content: googleBrokerSetupHtml(publicOrigin)
|
|
92232
|
+
}]
|
|
92233
|
+
},
|
|
92234
|
+
{
|
|
92235
|
+
id: "google-oauth-client",
|
|
92236
|
+
title: "Google OAuth client",
|
|
92237
|
+
titleKey: "google-services:googleBrokerSettings.s_google-oauth-client.title",
|
|
92238
|
+
description: "Web application client from Google Cloud Console. The same Cloud project can be reused across Google brokers.",
|
|
92239
|
+
descriptionKey: "google-services:googleBrokerSettings.s_google-oauth-client.description",
|
|
92240
|
+
columns: 1,
|
|
92241
|
+
fields: [{
|
|
92242
|
+
type: "text",
|
|
92243
|
+
key: "clientId",
|
|
92244
|
+
label: "Client ID",
|
|
92245
|
+
labelKey: "google-services:googleBrokerSettings.s_google-oauth-client.clientId.label"
|
|
92246
|
+
}, {
|
|
92247
|
+
type: "password",
|
|
92248
|
+
key: "clientSecret",
|
|
92249
|
+
label: "Client secret",
|
|
92250
|
+
labelKey: "google-services:googleBrokerSettings.s_google-oauth-client.clientSecret.label",
|
|
92251
|
+
showToggle: true
|
|
92252
|
+
}]
|
|
92253
|
+
},
|
|
92254
|
+
{
|
|
92255
|
+
id: "gmail-send",
|
|
92256
|
+
title: "Gmail send",
|
|
92257
|
+
titleKey: "google-services:googleBrokerSettings.s_gmail-send.title",
|
|
92258
|
+
description: "From must be this connected account or a verified send-as. Disable Email on Connectivity to turn Gmail off without removing the broker.",
|
|
92259
|
+
descriptionKey: "google-services:googleBrokerSettings.s_gmail-send.description",
|
|
92260
|
+
columns: 1,
|
|
92261
|
+
fields: [{
|
|
92262
|
+
type: "text",
|
|
92263
|
+
key: "fromAddress",
|
|
92264
|
+
label: "From address",
|
|
92265
|
+
labelKey: "google-services:googleBrokerSettings.s_gmail-send.fromAddress.label",
|
|
92266
|
+
description: "Defaults to the connected Google account email when empty.",
|
|
92267
|
+
descriptionKey: "google-services:googleBrokerSettings.s_gmail-send.fromAddress.description"
|
|
92268
|
+
}, {
|
|
92269
|
+
type: "text",
|
|
92270
|
+
key: "fromName",
|
|
92271
|
+
label: "From display name (optional)",
|
|
92272
|
+
labelKey: "google-services:googleBrokerSettings.s_gmail-send.fromName.label"
|
|
92273
|
+
}]
|
|
92274
|
+
}
|
|
92275
|
+
] };
|
|
92276
|
+
}
|
|
92277
|
+
function escapeHtml(s) {
|
|
92278
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
92279
|
+
}
|
|
92280
|
+
//#endregion
|
|
92560
92281
|
//#region src/google-instances.ts
|
|
92561
92282
|
/**
|
|
92562
92283
|
* The Google accounts as `integration-instances` (planning#408 P3): one instance per broker
|
|
@@ -93843,22 +93564,7 @@ var GoogleServicesAddon = class extends BaseAddon {
|
|
|
93843
93564
|
this.publicOrigin = null;
|
|
93844
93565
|
}
|
|
93845
93566
|
}
|
|
93846
|
-
/**
|
|
93847
|
-
* Connectivity Calendars / Email: point at Brokers (no duplicate OAuth fields).
|
|
93848
|
-
* Addon page without cap: same pointer + note.
|
|
93849
|
-
*/
|
|
93850
|
-
globalSettingsSchema(cap) {
|
|
93851
|
-
const scoped = asSettingsCap(cap);
|
|
93852
|
-
return this.schema(buildGoogleFeatureSettingsSchema(scoped, this.publicOrigin));
|
|
93853
|
-
}
|
|
93854
|
-
async getGlobalSettings(overlay, cap, nodeId) {
|
|
93855
|
-
await this.refreshPublicOrigin();
|
|
93856
|
-
return super.getGlobalSettings(overlay, cap, nodeId);
|
|
93857
|
-
}
|
|
93858
93567
|
};
|
|
93859
|
-
function asSettingsCap(cap) {
|
|
93860
|
-
if (cap === "calendar-source" || cap === "smtp-provider") return cap;
|
|
93861
|
-
}
|
|
93862
93568
|
//#endregion
|
|
93863
93569
|
exports.DEFAULT_GOOGLE_CONFIG = DEFAULT_GOOGLE_CONFIG;
|
|
93864
93570
|
exports.GOOGLE_BROKER_KIND = GOOGLE_BROKER_KIND;
|