@appwrite.io/console 18.2.0 → 18.3.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/sdk.js CHANGED
@@ -669,7 +669,7 @@ class Client {
669
669
  'x-sdk-name': 'Console',
670
670
  'x-sdk-platform': 'console',
671
671
  'x-sdk-language': 'web',
672
- 'x-sdk-version': '18.2.0',
672
+ 'x-sdk-version': '18.3.0-rc.1',
673
673
  'X-Appwrite-Response-Format': '2.3.0',
674
674
  };
675
675
  this.realtime = {
@@ -1522,29 +1522,6 @@ class Client {
1522
1522
  }
1523
1523
  Client.CHUNK_SIZE = 1024 * 1024 * 5;
1524
1524
 
1525
- class Service {
1526
- constructor(client) {
1527
- this.client = client;
1528
- }
1529
- static flatten(data, prefix = '') {
1530
- let output = {};
1531
- for (const [key, value] of Object.entries(data)) {
1532
- const finalKey = prefix ? prefix + '[' + key + ']' : key;
1533
- if (Array.isArray(value)) {
1534
- output = Object.assign(Object.assign({}, output), Service.flatten(value, finalKey));
1535
- }
1536
- else {
1537
- output[finalKey] = value;
1538
- }
1539
- }
1540
- return output;
1541
- }
1542
- }
1543
- /**
1544
- * The size for chunked uploads in bytes.
1545
- */
1546
- Service.CHUNK_SIZE = 5 * 1024 * 1024; // 5MB
1547
-
1548
1525
  class Account {
1549
1526
  constructor(client) {
1550
1527
  this.client = client;
@@ -3606,7 +3583,7 @@ class Account {
3606
3583
  }
3607
3584
  const uri = new URL(this.client.config.endpoint + apiPath);
3608
3585
  apiPayload['project'] = this.client.config.project;
3609
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
3586
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
3610
3587
  uri.searchParams.append(key, value);
3611
3588
  }
3612
3589
  if (typeof window !== 'undefined' && (window === null || window === void 0 ? void 0 : window.location)) {
@@ -4015,7 +3992,7 @@ class Account {
4015
3992
  }
4016
3993
  const uri = new URL(this.client.config.endpoint + apiPath);
4017
3994
  apiPayload['project'] = this.client.config.project;
4018
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
3995
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
4019
3996
  uri.searchParams.append(key, value);
4020
3997
  }
4021
3998
  if (typeof window !== 'undefined' && (window === null || window === void 0 ? void 0 : window.location)) {
@@ -4583,6 +4560,369 @@ class Affiliates {
4583
4560
  }
4584
4561
  }
4585
4562
 
4563
+ class Analytics {
4564
+ constructor(client) {
4565
+ this.client = client;
4566
+ }
4567
+ listProperties(paramsOrFirst, ...rest) {
4568
+ let params;
4569
+ if ((typeof paramsOrFirst === 'undefined' && rest.length === 0) ||
4570
+ (paramsOrFirst &&
4571
+ typeof paramsOrFirst === 'object' &&
4572
+ !Array.isArray(paramsOrFirst))) {
4573
+ params = (paramsOrFirst || {});
4574
+ }
4575
+ else {
4576
+ params = {
4577
+ queries: paramsOrFirst,
4578
+ search: rest[0],
4579
+ total: rest[1],
4580
+ };
4581
+ }
4582
+ const queries = params.queries;
4583
+ const search = params.search;
4584
+ const total = params.total;
4585
+ const apiPath = '/analytics/properties';
4586
+ const apiPayload = {};
4587
+ if (typeof queries !== 'undefined') {
4588
+ apiPayload['queries'] = queries;
4589
+ }
4590
+ if (typeof search !== 'undefined') {
4591
+ apiPayload['search'] = search;
4592
+ }
4593
+ if (typeof total !== 'undefined') {
4594
+ apiPayload['total'] = total;
4595
+ }
4596
+ const uri = new URL(this.client.config.endpoint + apiPath);
4597
+ const apiHeaders = {
4598
+ 'X-Appwrite-Project': this.client.config.project,
4599
+ accept: 'application/json',
4600
+ };
4601
+ return this.client.call('get', uri, apiHeaders, apiPayload);
4602
+ }
4603
+ createProperty(paramsOrFirst, ...rest) {
4604
+ let params;
4605
+ if (paramsOrFirst &&
4606
+ typeof paramsOrFirst === 'object' &&
4607
+ !Array.isArray(paramsOrFirst)) {
4608
+ params = (paramsOrFirst || {});
4609
+ }
4610
+ else {
4611
+ params = {
4612
+ propertyId: paramsOrFirst,
4613
+ name: rest[0],
4614
+ domain: rest[1],
4615
+ timezone: rest[2],
4616
+ enabled: rest[3],
4617
+ xpublic: rest[4],
4618
+ allowedOrigins: rest[5],
4619
+ };
4620
+ }
4621
+ const propertyId = params.propertyId;
4622
+ const name = params.name;
4623
+ const domain = params.domain;
4624
+ const timezone = params.timezone;
4625
+ const enabled = params.enabled;
4626
+ const xpublic = params.xpublic;
4627
+ const allowedOrigins = params.allowedOrigins;
4628
+ if (typeof propertyId === 'undefined') {
4629
+ throw new AppwriteException('Missing required parameter: "propertyId"');
4630
+ }
4631
+ if (typeof name === 'undefined') {
4632
+ throw new AppwriteException('Missing required parameter: "name"');
4633
+ }
4634
+ const apiPath = '/analytics/properties';
4635
+ const apiPayload = {};
4636
+ if (typeof propertyId !== 'undefined') {
4637
+ apiPayload['propertyId'] = propertyId;
4638
+ }
4639
+ if (typeof name !== 'undefined') {
4640
+ apiPayload['name'] = name;
4641
+ }
4642
+ if (typeof domain !== 'undefined') {
4643
+ apiPayload['domain'] = domain;
4644
+ }
4645
+ if (typeof timezone !== 'undefined') {
4646
+ apiPayload['timezone'] = timezone;
4647
+ }
4648
+ if (typeof enabled !== 'undefined') {
4649
+ apiPayload['enabled'] = enabled;
4650
+ }
4651
+ if (typeof xpublic !== 'undefined') {
4652
+ apiPayload['public'] = xpublic;
4653
+ }
4654
+ if (typeof allowedOrigins !== 'undefined') {
4655
+ apiPayload['allowedOrigins'] = allowedOrigins;
4656
+ }
4657
+ const uri = new URL(this.client.config.endpoint + apiPath);
4658
+ const apiHeaders = {
4659
+ 'X-Appwrite-Project': this.client.config.project,
4660
+ 'content-type': 'application/json',
4661
+ accept: 'application/json',
4662
+ };
4663
+ return this.client.call('post', uri, apiHeaders, apiPayload);
4664
+ }
4665
+ getProperty(paramsOrFirst) {
4666
+ let params;
4667
+ if (paramsOrFirst &&
4668
+ typeof paramsOrFirst === 'object' &&
4669
+ !Array.isArray(paramsOrFirst)) {
4670
+ params = (paramsOrFirst || {});
4671
+ }
4672
+ else {
4673
+ params = {
4674
+ propertyId: paramsOrFirst,
4675
+ };
4676
+ }
4677
+ const propertyId = params.propertyId;
4678
+ if (typeof propertyId === 'undefined' || propertyId === '') {
4679
+ throw new AppwriteException('Missing required parameter: "propertyId"');
4680
+ }
4681
+ const apiPath = '/analytics/properties/{propertyId}'.replace('{propertyId}', encodeURIComponent(String(propertyId)));
4682
+ const apiPayload = {};
4683
+ const uri = new URL(this.client.config.endpoint + apiPath);
4684
+ const apiHeaders = {
4685
+ 'X-Appwrite-Project': this.client.config.project,
4686
+ accept: 'application/json',
4687
+ };
4688
+ return this.client.call('get', uri, apiHeaders, apiPayload);
4689
+ }
4690
+ updateProperty(paramsOrFirst, ...rest) {
4691
+ let params;
4692
+ if (paramsOrFirst &&
4693
+ typeof paramsOrFirst === 'object' &&
4694
+ !Array.isArray(paramsOrFirst)) {
4695
+ params = (paramsOrFirst || {});
4696
+ }
4697
+ else {
4698
+ params = {
4699
+ propertyId: paramsOrFirst,
4700
+ name: rest[0],
4701
+ domain: rest[1],
4702
+ timezone: rest[2],
4703
+ enabled: rest[3],
4704
+ xpublic: rest[4],
4705
+ allowedOrigins: rest[5],
4706
+ };
4707
+ }
4708
+ const propertyId = params.propertyId;
4709
+ const name = params.name;
4710
+ const domain = params.domain;
4711
+ const timezone = params.timezone;
4712
+ const enabled = params.enabled;
4713
+ const xpublic = params.xpublic;
4714
+ const allowedOrigins = params.allowedOrigins;
4715
+ if (typeof propertyId === 'undefined' || propertyId === '') {
4716
+ throw new AppwriteException('Missing required parameter: "propertyId"');
4717
+ }
4718
+ const apiPath = '/analytics/properties/{propertyId}'.replace('{propertyId}', encodeURIComponent(String(propertyId)));
4719
+ const apiPayload = {};
4720
+ if (typeof name !== 'undefined') {
4721
+ apiPayload['name'] = name;
4722
+ }
4723
+ if (typeof domain !== 'undefined') {
4724
+ apiPayload['domain'] = domain;
4725
+ }
4726
+ if (typeof timezone !== 'undefined') {
4727
+ apiPayload['timezone'] = timezone;
4728
+ }
4729
+ if (typeof enabled !== 'undefined') {
4730
+ apiPayload['enabled'] = enabled;
4731
+ }
4732
+ if (typeof xpublic !== 'undefined') {
4733
+ apiPayload['public'] = xpublic;
4734
+ }
4735
+ if (typeof allowedOrigins !== 'undefined') {
4736
+ apiPayload['allowedOrigins'] = allowedOrigins;
4737
+ }
4738
+ const uri = new URL(this.client.config.endpoint + apiPath);
4739
+ const apiHeaders = {
4740
+ 'X-Appwrite-Project': this.client.config.project,
4741
+ 'content-type': 'application/json',
4742
+ accept: 'application/json',
4743
+ };
4744
+ return this.client.call('patch', uri, apiHeaders, apiPayload);
4745
+ }
4746
+ deleteProperty(paramsOrFirst) {
4747
+ let params;
4748
+ if (paramsOrFirst &&
4749
+ typeof paramsOrFirst === 'object' &&
4750
+ !Array.isArray(paramsOrFirst)) {
4751
+ params = (paramsOrFirst || {});
4752
+ }
4753
+ else {
4754
+ params = {
4755
+ propertyId: paramsOrFirst,
4756
+ };
4757
+ }
4758
+ const propertyId = params.propertyId;
4759
+ if (typeof propertyId === 'undefined' || propertyId === '') {
4760
+ throw new AppwriteException('Missing required parameter: "propertyId"');
4761
+ }
4762
+ const apiPath = '/analytics/properties/{propertyId}'.replace('{propertyId}', encodeURIComponent(String(propertyId)));
4763
+ const apiPayload = {};
4764
+ const uri = new URL(this.client.config.endpoint + apiPath);
4765
+ const apiHeaders = {
4766
+ 'X-Appwrite-Project': this.client.config.project,
4767
+ 'content-type': 'application/json',
4768
+ accept: 'application/json',
4769
+ };
4770
+ return this.client.call('delete', uri, apiHeaders, apiPayload);
4771
+ }
4772
+ createEvent(paramsOrFirst, ...rest) {
4773
+ let params;
4774
+ if (paramsOrFirst &&
4775
+ typeof paramsOrFirst === 'object' &&
4776
+ !Array.isArray(paramsOrFirst)) {
4777
+ params = (paramsOrFirst || {});
4778
+ }
4779
+ else {
4780
+ params = {
4781
+ propertyId: paramsOrFirst,
4782
+ name: rest[0],
4783
+ url: rest[1],
4784
+ domain: rest[2],
4785
+ referrer: rest[3],
4786
+ screenWidth: rest[4],
4787
+ sessionHash: rest[5],
4788
+ scrollDepth: rest[6],
4789
+ engagementTime: rest[7],
4790
+ props: rest[8],
4791
+ userId: rest[9],
4792
+ ip: rest[10],
4793
+ userAgent: rest[11],
4794
+ };
4795
+ }
4796
+ const propertyId = params.propertyId;
4797
+ const name = params.name;
4798
+ const url = params.url;
4799
+ const domain = params.domain;
4800
+ const referrer = params.referrer;
4801
+ const screenWidth = params.screenWidth;
4802
+ const sessionHash = params.sessionHash;
4803
+ const scrollDepth = params.scrollDepth;
4804
+ const engagementTime = params.engagementTime;
4805
+ const props = params.props;
4806
+ const userId = params.userId;
4807
+ const ip = params.ip;
4808
+ const userAgent = params.userAgent;
4809
+ if (typeof propertyId === 'undefined' || propertyId === '') {
4810
+ throw new AppwriteException('Missing required parameter: "propertyId"');
4811
+ }
4812
+ if (typeof name === 'undefined') {
4813
+ throw new AppwriteException('Missing required parameter: "name"');
4814
+ }
4815
+ if (typeof url === 'undefined') {
4816
+ throw new AppwriteException('Missing required parameter: "url"');
4817
+ }
4818
+ const apiPath = '/analytics/properties/{propertyId}/events'.replace('{propertyId}', encodeURIComponent(String(propertyId)));
4819
+ const apiPayload = {};
4820
+ if (typeof name !== 'undefined') {
4821
+ apiPayload['name'] = name;
4822
+ }
4823
+ if (typeof url !== 'undefined') {
4824
+ apiPayload['url'] = url;
4825
+ }
4826
+ if (typeof domain !== 'undefined') {
4827
+ apiPayload['domain'] = domain;
4828
+ }
4829
+ if (typeof referrer !== 'undefined') {
4830
+ apiPayload['referrer'] = referrer;
4831
+ }
4832
+ if (typeof screenWidth !== 'undefined') {
4833
+ apiPayload['screenWidth'] = screenWidth;
4834
+ }
4835
+ if (typeof sessionHash !== 'undefined') {
4836
+ apiPayload['sessionHash'] = sessionHash;
4837
+ }
4838
+ if (typeof scrollDepth !== 'undefined') {
4839
+ apiPayload['scrollDepth'] = scrollDepth;
4840
+ }
4841
+ if (typeof engagementTime !== 'undefined') {
4842
+ apiPayload['engagementTime'] = engagementTime;
4843
+ }
4844
+ if (typeof props !== 'undefined') {
4845
+ apiPayload['props'] = props;
4846
+ }
4847
+ if (typeof userId !== 'undefined') {
4848
+ apiPayload['userId'] = userId;
4849
+ }
4850
+ if (typeof ip !== 'undefined') {
4851
+ apiPayload['ip'] = ip;
4852
+ }
4853
+ if (typeof userAgent !== 'undefined') {
4854
+ apiPayload['userAgent'] = userAgent;
4855
+ }
4856
+ const uri = new URL(this.client.config.endpoint + apiPath);
4857
+ const apiHeaders = {
4858
+ 'X-Appwrite-Project': this.client.config.project,
4859
+ 'content-type': 'application/json',
4860
+ accept: 'application/json',
4861
+ };
4862
+ return this.client.call('post', uri, apiHeaders, apiPayload);
4863
+ }
4864
+ listMetrics(paramsOrFirst, ...rest) {
4865
+ let params;
4866
+ if (paramsOrFirst &&
4867
+ typeof paramsOrFirst === 'object' &&
4868
+ !Array.isArray(paramsOrFirst)) {
4869
+ params = (paramsOrFirst || {});
4870
+ }
4871
+ else {
4872
+ params = {
4873
+ propertyId: paramsOrFirst,
4874
+ queries: rest[0],
4875
+ interval: rest[1],
4876
+ dimensions: rest[2],
4877
+ dateRange: rest[3],
4878
+ startAt: rest[4],
4879
+ endAt: rest[5],
4880
+ limit: rest[6],
4881
+ };
4882
+ }
4883
+ const propertyId = params.propertyId;
4884
+ const queries = params.queries;
4885
+ const interval = params.interval;
4886
+ const dimensions = params.dimensions;
4887
+ const dateRange = params.dateRange;
4888
+ const startAt = params.startAt;
4889
+ const endAt = params.endAt;
4890
+ const limit = params.limit;
4891
+ if (typeof propertyId === 'undefined' || propertyId === '') {
4892
+ throw new AppwriteException('Missing required parameter: "propertyId"');
4893
+ }
4894
+ const apiPath = '/analytics/properties/{propertyId}/metrics'.replace('{propertyId}', encodeURIComponent(String(propertyId)));
4895
+ const apiPayload = {};
4896
+ if (typeof queries !== 'undefined') {
4897
+ apiPayload['queries'] = queries;
4898
+ }
4899
+ if (typeof interval !== 'undefined') {
4900
+ apiPayload['interval'] = interval;
4901
+ }
4902
+ if (typeof dimensions !== 'undefined') {
4903
+ apiPayload['dimensions'] = dimensions;
4904
+ }
4905
+ if (typeof dateRange !== 'undefined') {
4906
+ apiPayload['dateRange'] = dateRange;
4907
+ }
4908
+ if (typeof startAt !== 'undefined') {
4909
+ apiPayload['startAt'] = startAt;
4910
+ }
4911
+ if (typeof endAt !== 'undefined') {
4912
+ apiPayload['endAt'] = endAt;
4913
+ }
4914
+ if (typeof limit !== 'undefined') {
4915
+ apiPayload['limit'] = limit;
4916
+ }
4917
+ const uri = new URL(this.client.config.endpoint + apiPath);
4918
+ const apiHeaders = {
4919
+ 'X-Appwrite-Project': this.client.config.project,
4920
+ accept: 'application/json',
4921
+ };
4922
+ return this.client.call('get', uri, apiHeaders, apiPayload);
4923
+ }
4924
+ }
4925
+
4586
4926
  class Apps {
4587
4927
  constructor(client) {
4588
4928
  this.client = client;
@@ -5475,7 +5815,7 @@ class Avatars {
5475
5815
  const uri = new URL(this.client.config.endpoint + apiPath);
5476
5816
  apiPayload['project'] = this.client.config.project;
5477
5817
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5478
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
5818
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5479
5819
  uri.searchParams.append(key, value);
5480
5820
  }
5481
5821
  return uri.toString();
@@ -5520,7 +5860,7 @@ class Avatars {
5520
5860
  const uri = new URL(this.client.config.endpoint + apiPath);
5521
5861
  apiPayload['project'] = this.client.config.project;
5522
5862
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5523
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
5863
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5524
5864
  uri.searchParams.append(key, value);
5525
5865
  }
5526
5866
  return uri.toString();
@@ -5549,7 +5889,7 @@ class Avatars {
5549
5889
  const uri = new URL(this.client.config.endpoint + apiPath);
5550
5890
  apiPayload['project'] = this.client.config.project;
5551
5891
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5552
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
5892
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5553
5893
  uri.searchParams.append(key, value);
5554
5894
  }
5555
5895
  return uri.toString();
@@ -5594,7 +5934,7 @@ class Avatars {
5594
5934
  const uri = new URL(this.client.config.endpoint + apiPath);
5595
5935
  apiPayload['project'] = this.client.config.project;
5596
5936
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5597
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
5937
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5598
5938
  uri.searchParams.append(key, value);
5599
5939
  }
5600
5940
  return uri.toString();
@@ -5633,7 +5973,7 @@ class Avatars {
5633
5973
  const uri = new URL(this.client.config.endpoint + apiPath);
5634
5974
  apiPayload['project'] = this.client.config.project;
5635
5975
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5636
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
5976
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5637
5977
  uri.searchParams.append(key, value);
5638
5978
  }
5639
5979
  return uri.toString();
@@ -5675,7 +6015,7 @@ class Avatars {
5675
6015
  const uri = new URL(this.client.config.endpoint + apiPath);
5676
6016
  apiPayload['project'] = this.client.config.project;
5677
6017
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5678
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
6018
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5679
6019
  uri.searchParams.append(key, value);
5680
6020
  }
5681
6021
  return uri.toString();
@@ -5737,7 +6077,7 @@ class Avatars {
5737
6077
  const uri = new URL(this.client.config.endpoint + apiPath);
5738
6078
  apiPayload['project'] = this.client.config.project;
5739
6079
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5740
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
6080
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5741
6081
  uri.searchParams.append(key, value);
5742
6082
  }
5743
6083
  return uri.toString();
@@ -5831,7 +6171,7 @@ class Avatars {
5831
6171
  const uri = new URL(this.client.config.endpoint + apiPath);
5832
6172
  apiPayload['project'] = this.client.config.project;
5833
6173
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5834
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
6174
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5835
6175
  uri.searchParams.append(key, value);
5836
6176
  }
5837
6177
  return uri.toString();
@@ -5955,7 +6295,7 @@ class Avatars {
5955
6295
  const uri = new URL(this.client.config.endpoint + apiPath);
5956
6296
  apiPayload['project'] = this.client.config.project;
5957
6297
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
5958
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
6298
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
5959
6299
  uri.searchParams.append(key, value);
5960
6300
  }
5961
6301
  return uri.toString();
@@ -15531,7 +15871,7 @@ class Functions {
15531
15871
  const uri = new URL(this.client.config.endpoint + apiPath);
15532
15872
  apiPayload['project'] = this.client.config.project;
15533
15873
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
15534
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
15874
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
15535
15875
  uri.searchParams.append(key, value);
15536
15876
  }
15537
15877
  return uri.toString();
@@ -26170,7 +26510,7 @@ class Organizations {
26170
26510
  const uri = new URL(this.client.config.endpoint + apiPath);
26171
26511
  apiPayload['project'] = this.client.config.project;
26172
26512
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
26173
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
26513
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
26174
26514
  uri.searchParams.append(key, value);
26175
26515
  }
26176
26516
  return uri.toString();
@@ -26277,7 +26617,7 @@ class Organizations {
26277
26617
  const uri = new URL(this.client.config.endpoint + apiPath);
26278
26618
  apiPayload['project'] = this.client.config.project;
26279
26619
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
26280
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
26620
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
26281
26621
  uri.searchParams.append(key, value);
26282
26622
  }
26283
26623
  return uri.toString();
@@ -34461,7 +34801,7 @@ class Sites {
34461
34801
  const uri = new URL(this.client.config.endpoint + apiPath);
34462
34802
  apiPayload['project'] = this.client.config.project;
34463
34803
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
34464
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
34804
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
34465
34805
  uri.searchParams.append(key, value);
34466
34806
  }
34467
34807
  return uri.toString();
@@ -35292,7 +35632,7 @@ class Storage {
35292
35632
  const uri = new URL(this.client.config.endpoint + apiPath);
35293
35633
  apiPayload['project'] = this.client.config.project;
35294
35634
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
35295
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
35635
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
35296
35636
  uri.searchParams.append(key, value);
35297
35637
  }
35298
35638
  return uri.toString();
@@ -35385,7 +35725,7 @@ class Storage {
35385
35725
  const uri = new URL(this.client.config.endpoint + apiPath);
35386
35726
  apiPayload['project'] = this.client.config.project;
35387
35727
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
35388
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
35728
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
35389
35729
  uri.searchParams.append(key, value);
35390
35730
  }
35391
35731
  return uri.toString();
@@ -35423,7 +35763,7 @@ class Storage {
35423
35763
  const uri = new URL(this.client.config.endpoint + apiPath);
35424
35764
  apiPayload['project'] = this.client.config.project;
35425
35765
  apiPayload['impersonateuserid'] = this.client.config.impersonateuserid;
35426
- for (const [key, value] of Object.entries(Service.flatten(apiPayload))) {
35766
+ for (const [key, value] of Object.entries(Client.flatten(apiPayload))) {
35427
35767
  uri.searchParams.append(key, value);
35428
35768
  }
35429
35769
  return uri.toString();
@@ -46002,9 +46342,8 @@ const RECONNECT_PERIOD_MS = 2000;
46002
46342
  * );
46003
46343
  * // sub.update({ background: true }); sub.unsubscribe();
46004
46344
  */
46005
- class Push extends Service {
46345
+ class Push {
46006
46346
  constructor(client) {
46007
- super(client);
46008
46347
  this.mqtt = null;
46009
46348
  this.connecting = null;
46010
46349
  this.Buffer = null;
@@ -46034,6 +46373,7 @@ class Push extends Service {
46034
46373
  this.connectedKey = '';
46035
46374
  this.connectionEpoch = 0;
46036
46375
  this.subscriptions = new Map();
46376
+ this.client = client;
46037
46377
  }
46038
46378
  // The broker subscription for a filter uses the highest QoS any local subscription on
46039
46379
  // it wants, so a QoS-0 subscription never downgrades a QoS-1 one sharing the filter.
@@ -46773,6 +47113,670 @@ function matches(filter, topic) {
46773
47113
  return filterParts.length === topicParts.length;
46774
47114
  }
46775
47115
 
47116
+ /**
47117
+ * Analytics auto-tracking helpers.
47118
+ *
47119
+ * These are hand-written companions to the generated `Analytics` service.
47120
+ * The generated service exposes `createEvent(params)` for arbitrary events;
47121
+ * this module wires up common auto-tracking behaviours (pageviews, outbound
47122
+ * links, downloads, scroll depth, active engagement) on top of it.
47123
+ *
47124
+ * The tracking helpers accept a plain event-emitter function so they do not
47125
+ * hard-couple to the generated `Analytics` class. The emitter adapts this
47126
+ * module's option shape to `createEvent`: `url` is required there, and `props`
47127
+ * is a flat alternating key/value list rather than an object.
47128
+ *
47129
+ * ```ts
47130
+ * const analytics = new Analytics(client);
47131
+ * const tracking = new AnalyticsTracking(
47132
+ * (name, options) => analytics.createEvent({
47133
+ * propertyId: options?.propertyId ?? '<PROPERTY_ID>',
47134
+ * name,
47135
+ * url: options?.url ?? window.location.href,
47136
+ * referrer: options?.referrer,
47137
+ * scrollDepth: options?.scrollDepth,
47138
+ * engagementTime: options?.engagementTime,
47139
+ * props: Object.entries(options?.props ?? {}).flatMap(
47140
+ * ([key, value]) => [key, String(value)],
47141
+ * ),
47142
+ * }),
47143
+ * { propertyId: '<PROPERTY_ID>' }
47144
+ * );
47145
+ * tracking.enableAllAutoTracking();
47146
+ * ```
47147
+ *
47148
+ * `propertyId` is optional: when set it is merged into the options of every
47149
+ * emitted event, so an emitter that forwards `options.propertyId` (as above)
47150
+ * picks it up instead of every caller hand-rolling it into the closure.
47151
+ * Per-event `propertyId` always wins over the configured default.
47152
+ *
47153
+ * All helpers respect `navigator.doNotTrack === '1'` by default; opt out with
47154
+ * `respectDoNotTrack: false` in the constructor options.
47155
+ *
47156
+ * Engagement time follows Plausible's model: rather than one total at unload,
47157
+ * a delta is emitted at every natural checkpoint of the visit (tab hidden, SPA
47158
+ * route change, unload). See `enableAutoEngagementTime` for details.
47159
+ *
47160
+ * Auto-emitted event names follow `snake_case` + lowercase (`pageview`,
47161
+ * `outbound_link`, `file_download`, `screen_view`, etc.). Any prop keys use
47162
+ * camelCase to match the endpoint's parameter naming. Callers can pass any
47163
+ * custom event name; the auto-track methods only own the events they emit
47164
+ * themselves.
47165
+ */
47166
+ const DEFAULT_DOWNLOAD_EXTENSIONS = [
47167
+ 'pdf',
47168
+ 'zip',
47169
+ 'rar',
47170
+ '7z',
47171
+ 'tar',
47172
+ 'gz',
47173
+ 'csv',
47174
+ 'tsv',
47175
+ 'xls',
47176
+ 'xlsx',
47177
+ 'doc',
47178
+ 'docx',
47179
+ 'ppt',
47180
+ 'pptx',
47181
+ 'dmg',
47182
+ 'exe',
47183
+ 'msi',
47184
+ 'pkg',
47185
+ 'deb',
47186
+ 'rpm',
47187
+ 'apk',
47188
+ 'mp3',
47189
+ 'wav',
47190
+ 'flac',
47191
+ 'mp4',
47192
+ 'mov',
47193
+ 'avi',
47194
+ 'mkv',
47195
+ 'webm',
47196
+ ];
47197
+ /**
47198
+ * Two-part public suffixes common enough to matter for outbound-link detection.
47199
+ * See `rootDomain()` for why this is a short list rather than the Public Suffix
47200
+ * List.
47201
+ */
47202
+ const MULTI_PART_SUFFIXES = new Set([
47203
+ 'co.uk',
47204
+ 'org.uk',
47205
+ 'ac.uk',
47206
+ 'gov.uk',
47207
+ 'me.uk',
47208
+ 'net.uk',
47209
+ 'sch.uk',
47210
+ 'co.jp',
47211
+ 'ne.jp',
47212
+ 'or.jp',
47213
+ 'ac.jp',
47214
+ 'go.jp',
47215
+ 'com.au',
47216
+ 'net.au',
47217
+ 'org.au',
47218
+ 'edu.au',
47219
+ 'gov.au',
47220
+ 'com.br',
47221
+ 'net.br',
47222
+ 'org.br',
47223
+ 'com.cn',
47224
+ 'net.cn',
47225
+ 'org.cn',
47226
+ 'gov.cn',
47227
+ 'co.in',
47228
+ 'net.in',
47229
+ 'org.in',
47230
+ 'co.nz',
47231
+ 'net.nz',
47232
+ 'org.nz',
47233
+ 'co.za',
47234
+ 'org.za',
47235
+ 'com.mx',
47236
+ 'com.ar',
47237
+ 'com.co',
47238
+ 'com.pe',
47239
+ 'com.tr',
47240
+ 'com.tw',
47241
+ 'com.sg',
47242
+ 'com.hk',
47243
+ 'com.my',
47244
+ 'com.ph',
47245
+ 'com.vn',
47246
+ 'co.kr',
47247
+ 'co.il',
47248
+ 'co.id',
47249
+ 'co.th',
47250
+ 'com.ua',
47251
+ 'com.pl',
47252
+ 'com.es',
47253
+ ]);
47254
+ const SCROLL_DEPTH_THROTTLE_MS = 200;
47255
+ class AnalyticsTracking {
47256
+ constructor(emit, options = {}) {
47257
+ this.pageviewCleanups = [];
47258
+ this.scrollCleanups = [];
47259
+ this.engagementCleanups = [];
47260
+ this.maxScrollDepth = 0;
47261
+ this.scrollTicking = false;
47262
+ this.lastScrollReport = 0;
47263
+ this.engagementStart = 0;
47264
+ this.engagementAccumulatedMs = 0;
47265
+ this.engagementActive = false;
47266
+ this.emit = emit;
47267
+ this.respectDoNotTrack = options.respectDoNotTrack !== false;
47268
+ this.propertyId = options.propertyId;
47269
+ }
47270
+ /**
47271
+ * Enable the opinionated default auto-tracking set: pageviews, outbound
47272
+ * links, scroll depth and active engagement time. Downloads must be opted
47273
+ * into separately via `enableAutoDownloadTracking()` because the extension
47274
+ * list is application-specific.
47275
+ */
47276
+ enableAllAutoTracking() {
47277
+ this.enableAutoPageviews();
47278
+ this.enableAutoOutboundTracking();
47279
+ this.enableAutoScrollDepth();
47280
+ this.enableAutoEngagementTime();
47281
+ }
47282
+ /**
47283
+ * Track an event manually. Respects the DNT setting and swallows emitter
47284
+ * exceptions so tracking failures never surface to the host page.
47285
+ */
47286
+ track(name, options) {
47287
+ if (!this.canTrack()) {
47288
+ return;
47289
+ }
47290
+ try {
47291
+ this.emit(name, this.withPropertyId(options));
47292
+ }
47293
+ catch (error) {
47294
+ console.warn('AnalyticsTracking: emitter threw', error);
47295
+ }
47296
+ }
47297
+ /**
47298
+ * Convenience wrapper for pageview-shaped events.
47299
+ */
47300
+ pageview(url, referrer) {
47301
+ this.track('pageview', {
47302
+ url: url !== null && url !== void 0 ? url : this.currentPageUrl(),
47303
+ referrer: referrer !== null && referrer !== void 0 ? referrer : (typeof document !== 'undefined'
47304
+ ? document.referrer
47305
+ : undefined),
47306
+ });
47307
+ }
47308
+ /**
47309
+ * Enable SPA-aware pageview tracking. Fires an initial pageview on
47310
+ * enable, then again on every `pushState`, `replaceState`, `popstate`
47311
+ * or hashchange. Idempotent — repeat calls no-op.
47312
+ */
47313
+ enableAutoPageviews() {
47314
+ if (this.pageviewCleanups.length > 0) {
47315
+ return;
47316
+ }
47317
+ if (typeof window === 'undefined' || typeof history === 'undefined') {
47318
+ return;
47319
+ }
47320
+ this.currentPath = this.currentPageUrl();
47321
+ this.pageview();
47322
+ const handleNavigation = () => {
47323
+ const nextPath = this.currentPageUrl();
47324
+ if (nextPath === this.currentPath) {
47325
+ return;
47326
+ }
47327
+ const previous = this.currentPath;
47328
+ this.currentPath = nextPath;
47329
+ this.flushScrollDepth(previous);
47330
+ this.flushEngagement(previous);
47331
+ this.pageview(nextPath);
47332
+ // flushEngagement no longer auto-restarts the timer (see its
47333
+ // implementation note re: bfcache). SPA navigation stays on the
47334
+ // same document, so restart engagement tracking for the new
47335
+ // route as long as the tab is visible.
47336
+ if (this.engagementCleanups.length > 0 &&
47337
+ (typeof document === 'undefined' ||
47338
+ document.visibilityState !== 'hidden')) {
47339
+ this.startEngagement();
47340
+ }
47341
+ };
47342
+ const originalPushState = history.pushState.bind(history);
47343
+ const originalReplaceState = history.replaceState.bind(history);
47344
+ // Our wrappers stay reachable after cleanup whenever another library
47345
+ // patched on top of ours, so they have to be switchable off rather than
47346
+ // merely unreferenced.
47347
+ let patchActive = true;
47348
+ const patchedPushState = (data, unused, url) => {
47349
+ originalPushState(data, unused, url);
47350
+ if (patchActive) {
47351
+ handleNavigation();
47352
+ }
47353
+ };
47354
+ const patchedReplaceState = (data, unused, url) => {
47355
+ originalReplaceState(data, unused, url);
47356
+ if (patchActive) {
47357
+ handleNavigation();
47358
+ }
47359
+ };
47360
+ history.pushState = patchedPushState;
47361
+ history.replaceState = patchedReplaceState;
47362
+ const popstateHandler = () => handleNavigation();
47363
+ const hashchangeHandler = () => handleNavigation();
47364
+ window.addEventListener('popstate', popstateHandler);
47365
+ window.addEventListener('hashchange', hashchangeHandler);
47366
+ this.pageviewCleanups.push(() => {
47367
+ // Only unwind our own patch. A router (Next.js App Router, React
47368
+ // Router, …) that patched these after us owns the current value,
47369
+ // and assigning our saved reference back would silently throw its
47370
+ // wrapper away. In that case ours stays in the chain, which is why
47371
+ // `patchActive` exists: the wrapper keeps delegating to the original
47372
+ // but stops reporting.
47373
+ patchActive = false;
47374
+ if (history.pushState === patchedPushState) {
47375
+ history.pushState = originalPushState;
47376
+ }
47377
+ if (history.replaceState === patchedReplaceState) {
47378
+ history.replaceState = originalReplaceState;
47379
+ }
47380
+ window.removeEventListener('popstate', popstateHandler);
47381
+ window.removeEventListener('hashchange', hashchangeHandler);
47382
+ });
47383
+ }
47384
+ /**
47385
+ * Disable auto-pageview tracking installed by `enableAutoPageviews`.
47386
+ * Safe to call when auto-pageviews were never enabled.
47387
+ */
47388
+ disableAutoPageviews() {
47389
+ for (const cleanup of this.pageviewCleanups) {
47390
+ cleanup();
47391
+ }
47392
+ this.pageviewCleanups = [];
47393
+ }
47394
+ /**
47395
+ * Enable click-based outbound link tracking. Detects anchor clicks that
47396
+ * navigate to a different origin and fires an `outbound_link` event
47397
+ * (with `hostname` and `href` props) before the browser navigates.
47398
+ */
47399
+ enableAutoOutboundTracking(options = {}) {
47400
+ if (this.outboundCleanup) {
47401
+ return;
47402
+ }
47403
+ if (typeof document === 'undefined') {
47404
+ return;
47405
+ }
47406
+ const includeSubdomains = options.includeSubdomains === true;
47407
+ const clickHandler = (event) => {
47408
+ const anchor = this.findAnchor(event.target);
47409
+ if (!anchor || !anchor.href) {
47410
+ return;
47411
+ }
47412
+ const target = this.parseUrl(anchor.href);
47413
+ if (!target || !this.isExternal(target, includeSubdomains)) {
47414
+ return;
47415
+ }
47416
+ this.track('outbound_link', {
47417
+ url: target.href,
47418
+ props: { hostname: target.hostname, href: target.href },
47419
+ });
47420
+ };
47421
+ document.addEventListener('click', clickHandler, { capture: true });
47422
+ this.outboundCleanup = () => document.removeEventListener('click', clickHandler, {
47423
+ capture: true,
47424
+ });
47425
+ }
47426
+ /**
47427
+ * Disable outbound-link tracking installed by `enableAutoOutboundTracking`.
47428
+ * Safe to call when auto-outbound was never enabled.
47429
+ */
47430
+ disableAutoOutboundTracking() {
47431
+ if (this.outboundCleanup) {
47432
+ this.outboundCleanup();
47433
+ this.outboundCleanup = undefined;
47434
+ }
47435
+ }
47436
+ /**
47437
+ * Enable click-based download tracking. Detects anchor clicks that point
47438
+ * at a file whose extension appears in the configured list and fires a
47439
+ * `file_download` event with `filename`, `extension` and `href` props.
47440
+ */
47441
+ enableAutoDownloadTracking(options = {}) {
47442
+ var _a;
47443
+ if (this.downloadCleanup) {
47444
+ return;
47445
+ }
47446
+ if (typeof document === 'undefined') {
47447
+ return;
47448
+ }
47449
+ const extensions = ((_a = options.extensions) !== null && _a !== void 0 ? _a : DEFAULT_DOWNLOAD_EXTENSIONS).map((ext) => ext.toLowerCase().replace(/^\./, ''));
47450
+ const extensionSet = new Set(extensions);
47451
+ const clickHandler = (event) => {
47452
+ var _a, _b;
47453
+ const anchor = this.findAnchor(event.target);
47454
+ if (!anchor || !anchor.href) {
47455
+ return;
47456
+ }
47457
+ const url = this.parseUrl(anchor.href);
47458
+ if (!url) {
47459
+ return;
47460
+ }
47461
+ const filename = (_a = url.pathname.split('/').pop()) !== null && _a !== void 0 ? _a : '';
47462
+ const extension = filename.includes('.')
47463
+ ? (_b = filename.split('.').pop()) === null || _b === void 0 ? void 0 : _b.toLowerCase()
47464
+ : undefined;
47465
+ if (!extension || !extensionSet.has(extension)) {
47466
+ return;
47467
+ }
47468
+ this.track('file_download', {
47469
+ url: url.href,
47470
+ props: { filename, extension, href: url.href },
47471
+ });
47472
+ };
47473
+ document.addEventListener('click', clickHandler, { capture: true });
47474
+ this.downloadCleanup = () => document.removeEventListener('click', clickHandler, {
47475
+ capture: true,
47476
+ });
47477
+ }
47478
+ /**
47479
+ * Disable file-download tracking installed by `enableAutoDownloadTracking`.
47480
+ * Safe to call when auto-download was never enabled.
47481
+ */
47482
+ disableAutoDownloadTracking() {
47483
+ if (this.downloadCleanup) {
47484
+ this.downloadCleanup();
47485
+ this.downloadCleanup = undefined;
47486
+ }
47487
+ }
47488
+ /**
47489
+ * Enable passive scroll-depth tracking. Records the maximum percent of the
47490
+ * document scrolled and reports it on `beforeunload` and on SPA route
47491
+ * changes. Uses a throttled passive listener so it is safe on hot paths.
47492
+ */
47493
+ enableAutoScrollDepth() {
47494
+ if (this.scrollCleanups.length > 0) {
47495
+ return;
47496
+ }
47497
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
47498
+ return;
47499
+ }
47500
+ this.maxScrollDepth = 0;
47501
+ this.lastScrollReport = 0;
47502
+ const scrollHandler = () => {
47503
+ if (this.scrollTicking) {
47504
+ return;
47505
+ }
47506
+ this.scrollTicking = true;
47507
+ window.requestAnimationFrame(() => {
47508
+ const now = Date.now();
47509
+ if (now - this.lastScrollReport < SCROLL_DEPTH_THROTTLE_MS) {
47510
+ this.scrollTicking = false;
47511
+ return;
47512
+ }
47513
+ this.lastScrollReport = now;
47514
+ const depth = this.computeScrollDepth();
47515
+ if (depth > this.maxScrollDepth) {
47516
+ this.maxScrollDepth = depth;
47517
+ }
47518
+ this.scrollTicking = false;
47519
+ });
47520
+ };
47521
+ const unloadHandler = () => {
47522
+ this.flushScrollDepth(this.currentPageUrl());
47523
+ };
47524
+ window.addEventListener('scroll', scrollHandler, { passive: true });
47525
+ window.addEventListener('beforeunload', unloadHandler);
47526
+ window.addEventListener('pagehide', unloadHandler);
47527
+ this.scrollCleanups.push(() => {
47528
+ window.removeEventListener('scroll', scrollHandler);
47529
+ window.removeEventListener('beforeunload', unloadHandler);
47530
+ window.removeEventListener('pagehide', unloadHandler);
47531
+ });
47532
+ }
47533
+ /**
47534
+ * Disable scroll-depth tracking installed by `enableAutoScrollDepth`. Safe
47535
+ * to call when auto-scroll-depth was never enabled. Any accumulated depth
47536
+ * for the current page is dropped.
47537
+ */
47538
+ disableAutoScrollDepth() {
47539
+ for (const cleanup of this.scrollCleanups) {
47540
+ cleanup();
47541
+ }
47542
+ this.scrollCleanups = [];
47543
+ this.maxScrollDepth = 0;
47544
+ this.scrollTicking = false;
47545
+ this.lastScrollReport = 0;
47546
+ }
47547
+ /**
47548
+ * Enable active engagement-time tracking. Counts time the tab is visible
47549
+ * and uses `visibilitychange` to exclude background time.
47550
+ *
47551
+ * Delivery follows Plausible's model rather than a single total at the
47552
+ * end of the visit: an `engagement_time` event is emitted at every natural
47553
+ * checkpoint — the tab going hidden, an SPA route change, and finally
47554
+ * `beforeunload`/`pagehide`. Unload is kept only as a best-effort last
47555
+ * flush; it is the least reliable moment to send anything (browsers
47556
+ * routinely cancel in-flight requests there, and `sendBeacon` cannot set
47557
+ * the `X-Appwrite-Project` header the endpoint requires), so it must never
47558
+ * be the only delivery.
47559
+ *
47560
+ * Each event carries a **delta** — the seconds accrued since the previous
47561
+ * flush, not a running total — so the values are additive per session and
47562
+ * a lost event costs only its own slice.
47563
+ *
47564
+ * There is deliberately no periodic ping. The cadence is driven by
47565
+ * navigation and tab switches, so request volume tracks what the visitor
47566
+ * actually does instead of multiplying with time on page.
47567
+ */
47568
+ enableAutoEngagementTime() {
47569
+ if (this.engagementCleanups.length > 0) {
47570
+ return;
47571
+ }
47572
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
47573
+ return;
47574
+ }
47575
+ this.engagementAccumulatedMs = 0;
47576
+ // Do not start the clock for a tab that is already hidden (prerender,
47577
+ // background tab restore); `visibilitychange` starts it when it is
47578
+ // actually looked at.
47579
+ if (document.visibilityState !== 'hidden') {
47580
+ this.startEngagement();
47581
+ }
47582
+ const visibilityHandler = () => {
47583
+ if (document.visibilityState === 'hidden') {
47584
+ // Flush, don't just pause. The page is still fully alive here,
47585
+ // which makes this the most reliable delivery point in the
47586
+ // whole visit — and it is the same moment Plausible reports on.
47587
+ this.flushEngagement(this.currentPageUrl());
47588
+ }
47589
+ else if (document.visibilityState === 'visible') {
47590
+ this.startEngagement();
47591
+ }
47592
+ };
47593
+ const unloadHandler = () => {
47594
+ this.flushEngagement(this.currentPageUrl());
47595
+ };
47596
+ const pageshowHandler = (event) => {
47597
+ // When the page is restored from the back-forward cache the
47598
+ // engagement timer is in a stopped state (flushEngagement paused
47599
+ // it on pagehide and does not auto-restart). Kick off a fresh
47600
+ // engagementStart so bfcache dwell time is not billed as
47601
+ // engagement.
47602
+ if (event.persisted) {
47603
+ this.startEngagement();
47604
+ }
47605
+ };
47606
+ document.addEventListener('visibilitychange', visibilityHandler);
47607
+ window.addEventListener('beforeunload', unloadHandler);
47608
+ window.addEventListener('pagehide', unloadHandler);
47609
+ window.addEventListener('pageshow', pageshowHandler);
47610
+ this.engagementCleanups.push(() => {
47611
+ document.removeEventListener('visibilitychange', visibilityHandler);
47612
+ window.removeEventListener('beforeunload', unloadHandler);
47613
+ window.removeEventListener('pagehide', unloadHandler);
47614
+ window.removeEventListener('pageshow', pageshowHandler);
47615
+ });
47616
+ }
47617
+ /**
47618
+ * Disable engagement-time tracking installed by `enableAutoEngagementTime`.
47619
+ * Safe to call when auto-engagement was never enabled. Any accumulated
47620
+ * engagement time is dropped without being emitted.
47621
+ */
47622
+ disableAutoEngagementTime() {
47623
+ for (const cleanup of this.engagementCleanups) {
47624
+ cleanup();
47625
+ }
47626
+ this.engagementCleanups = [];
47627
+ this.engagementActive = false;
47628
+ this.engagementAccumulatedMs = 0;
47629
+ this.engagementStart = 0;
47630
+ }
47631
+ /**
47632
+ * Merge the configured `propertyId` into an event's options. Returns the
47633
+ * caller's object untouched when no default is configured (or the event
47634
+ * already carries one), so emitters written against the pre-`propertyId`
47635
+ * shape keep receiving exactly what they received before.
47636
+ */
47637
+ withPropertyId(options) {
47638
+ if (this.propertyId === undefined ||
47639
+ (options === null || options === void 0 ? void 0 : options.propertyId) !== undefined) {
47640
+ return options;
47641
+ }
47642
+ return Object.assign(Object.assign({}, (options !== null && options !== void 0 ? options : {})), { propertyId: this.propertyId });
47643
+ }
47644
+ canTrack() {
47645
+ if (!this.respectDoNotTrack) {
47646
+ return true;
47647
+ }
47648
+ if (typeof navigator === 'undefined') {
47649
+ return true;
47650
+ }
47651
+ return navigator.doNotTrack !== '1';
47652
+ }
47653
+ currentPageUrl() {
47654
+ if (typeof window === 'undefined' || !window.location) {
47655
+ return '';
47656
+ }
47657
+ return window.location.href;
47658
+ }
47659
+ findAnchor(target) {
47660
+ let node = target;
47661
+ while (node) {
47662
+ if (node.tagName === 'A') {
47663
+ return node;
47664
+ }
47665
+ node = node.parentNode;
47666
+ }
47667
+ return null;
47668
+ }
47669
+ parseUrl(href) {
47670
+ try {
47671
+ return new URL(href, window.location.href);
47672
+ }
47673
+ catch (_a) {
47674
+ return null;
47675
+ }
47676
+ }
47677
+ isExternal(target, includeSubdomains) {
47678
+ if (target.protocol !== 'http:' && target.protocol !== 'https:') {
47679
+ return false;
47680
+ }
47681
+ if (target.hostname === window.location.hostname) {
47682
+ return false;
47683
+ }
47684
+ if (includeSubdomains) {
47685
+ return true;
47686
+ }
47687
+ const root = this.rootDomain(window.location.hostname);
47688
+ return this.rootDomain(target.hostname) !== root;
47689
+ }
47690
+ rootDomain(hostname) {
47691
+ const parts = hostname.split('.');
47692
+ if (parts.length <= 2) {
47693
+ return hostname;
47694
+ }
47695
+ // Taking the last two labels is wrong wherever the registry sells names
47696
+ // one level down: `shop.example.co.uk` and `google.co.uk` both reduce to
47697
+ // `co.uk`, so every outbound click between two `.co.uk` sites looks
47698
+ // internal and is dropped. Take three labels after a known two-part
47699
+ // suffix instead.
47700
+ //
47701
+ // This is a heuristic, not the Public Suffix List — the full list is
47702
+ // orders of magnitude larger than this whole file, and a tracking
47703
+ // snippet cannot carry it. Sites on a suffix that is missing here can
47704
+ // pass `includeSubdomains: true` to treat every other host as outbound.
47705
+ const suffix = parts.slice(-2).join('.');
47706
+ if (parts.length > 2 && MULTI_PART_SUFFIXES.has(suffix)) {
47707
+ return parts.slice(-3).join('.');
47708
+ }
47709
+ return suffix;
47710
+ }
47711
+ computeScrollDepth() {
47712
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
47713
+ const viewport = window.innerHeight || document.documentElement.clientHeight;
47714
+ const total = document.documentElement.scrollHeight;
47715
+ if (total <= viewport) {
47716
+ return 100;
47717
+ }
47718
+ const depth = Math.round(((scrollTop + viewport) / total) * 100);
47719
+ return Math.max(0, Math.min(100, depth));
47720
+ }
47721
+ flushScrollDepth(url) {
47722
+ if (this.scrollCleanups.length === 0) {
47723
+ return;
47724
+ }
47725
+ if (this.maxScrollDepth <= 0) {
47726
+ return;
47727
+ }
47728
+ this.track('scroll_depth', {
47729
+ url,
47730
+ scrollDepth: this.maxScrollDepth,
47731
+ });
47732
+ this.maxScrollDepth = 0;
47733
+ }
47734
+ startEngagement() {
47735
+ if (this.engagementActive) {
47736
+ return;
47737
+ }
47738
+ this.engagementActive = true;
47739
+ this.engagementStart = Date.now();
47740
+ }
47741
+ pauseEngagement() {
47742
+ if (!this.engagementActive) {
47743
+ return;
47744
+ }
47745
+ this.engagementActive = false;
47746
+ this.engagementAccumulatedMs += Date.now() - this.engagementStart;
47747
+ }
47748
+ flushEngagement(url) {
47749
+ if (this.engagementCleanups.length === 0) {
47750
+ return;
47751
+ }
47752
+ this.pauseEngagement();
47753
+ // Deltas, not a running total: emit only what accrued since the last
47754
+ // flush. `floor` plus keeping the sub-second remainder in the
47755
+ // accumulator is what makes repeated flushes safe — nothing is emitted
47756
+ // twice, and a visit chopped into many short segments does not lose a
47757
+ // fraction of a second to rounding on every one of them.
47758
+ const seconds = Math.floor(this.engagementAccumulatedMs / 1000);
47759
+ if (seconds > 0) {
47760
+ // Deduct before emitting so a synchronous emitter that re-enters
47761
+ // (or throws) can never bill the same seconds again.
47762
+ this.engagementAccumulatedMs -= seconds * 1000;
47763
+ this.track('engagement_time', {
47764
+ url,
47765
+ engagementTime: seconds,
47766
+ });
47767
+ }
47768
+ // NOTE: intentionally do NOT call startEngagement() here. flushEngagement
47769
+ // runs on `pagehide`, which is also the last hook before the browser
47770
+ // may freeze the page into the back-forward cache. Auto-restarting
47771
+ // would snapshot engagementStart just before the freeze; the next
47772
+ // pauseEngagement (after bfcache restore) would then bill the entire
47773
+ // bfcache dwell as active engagement. Restart is driven by explicit
47774
+ // resume signals: `pageshow` (with `persisted === true`),
47775
+ // `visibilitychange` back to visible, or the SPA navigation flow in
47776
+ // `enableAutoPageviews`.
47777
+ }
47778
+ }
47779
+
46776
47780
  /**
46777
47781
  * Helper class to generate permission strings for resources.
46778
47782
  */
@@ -47479,6 +48483,40 @@ exports.OAuthProvider = void 0;
47479
48483
  OAuthProvider["Zoom"] = "zoom";
47480
48484
  })(exports.OAuthProvider || (exports.OAuthProvider = {}));
47481
48485
 
48486
+ exports.AnalyticsInterval = void 0;
48487
+ (function (AnalyticsInterval) {
48488
+ AnalyticsInterval["OneHour"] = "1h";
48489
+ AnalyticsInterval["OneDay"] = "1d";
48490
+ AnalyticsInterval["OneWeek"] = "1w";
48491
+ AnalyticsInterval["OneMonth"] = "1m";
48492
+ })(exports.AnalyticsInterval || (exports.AnalyticsInterval = {}));
48493
+
48494
+ exports.AnalyticsDimension = void 0;
48495
+ (function (AnalyticsDimension) {
48496
+ AnalyticsDimension["Country"] = "country";
48497
+ AnalyticsDimension["Region"] = "region";
48498
+ AnalyticsDimension["City"] = "city";
48499
+ AnalyticsDimension["Browser"] = "browser";
48500
+ AnalyticsDimension["OperatingSystem"] = "operatingSystem";
48501
+ AnalyticsDimension["Device"] = "device";
48502
+ AnalyticsDimension["ScreenSize"] = "screenSize";
48503
+ AnalyticsDimension["ReferrerSource"] = "referrerSource";
48504
+ AnalyticsDimension["Channel"] = "channel";
48505
+ AnalyticsDimension["UtmSource"] = "utmSource";
48506
+ AnalyticsDimension["UtmMedium"] = "utmMedium";
48507
+ AnalyticsDimension["UtmCampaign"] = "utmCampaign";
48508
+ AnalyticsDimension["UtmContent"] = "utmContent";
48509
+ AnalyticsDimension["UtmTerm"] = "utmTerm";
48510
+ AnalyticsDimension["Page"] = "page";
48511
+ AnalyticsDimension["Hostname"] = "hostname";
48512
+ AnalyticsDimension["EntryPage"] = "entryPage";
48513
+ AnalyticsDimension["ExitPage"] = "exitPage";
48514
+ AnalyticsDimension["TrafficType"] = "trafficType";
48515
+ AnalyticsDimension["BotName"] = "botName";
48516
+ AnalyticsDimension["BotCategory"] = "botCategory";
48517
+ AnalyticsDimension["EventName"] = "eventName";
48518
+ })(exports.AnalyticsDimension || (exports.AnalyticsDimension = {}));
48519
+
47482
48520
  exports.Browser = void 0;
47483
48521
  (function (Browser) {
47484
48522
  Browser["AvantBrowser"] = "aa";
@@ -48294,6 +49332,7 @@ exports.QuerySuggestionResource = void 0;
48294
49332
  QuerySuggestionResource["ResourceTokens"] = "resourcetokens";
48295
49333
  QuerySuggestionResource["Transactions"] = "transactions";
48296
49334
  QuerySuggestionResource["TransactionLogs"] = "transactionlogs";
49335
+ QuerySuggestionResource["AnalyticsProperties"] = "analyticsproperties";
48297
49336
  QuerySuggestionResource["DedicatedDatabases"] = "dedicateddatabases";
48298
49337
  QuerySuggestionResource["DedicatedDatabaseConfigs"] = "dedicateddatabaseconfigs";
48299
49338
  QuerySuggestionResource["DedicatedDatabaseRuntimes"] = "dedicateddatabaseruntimes";
@@ -48734,6 +49773,8 @@ exports.ProjectKeyScopes = void 0;
48734
49773
  ProjectKeyScopes["Oauth2Read"] = "oauth2.read";
48735
49774
  ProjectKeyScopes["Oauth2Write"] = "oauth2.write";
48736
49775
  ProjectKeyScopes["Oauth2Introspect"] = "oauth2.introspect";
49776
+ ProjectKeyScopes["AnalyticsRead"] = "analytics.read";
49777
+ ProjectKeyScopes["AnalyticsWrite"] = "analytics.write";
48737
49778
  })(exports.ProjectKeyScopes || (exports.ProjectKeyScopes = {}));
48738
49779
 
48739
49780
  exports.FunctionTemplateUseCase = void 0;
@@ -49368,6 +50409,9 @@ exports.TablesDBIndexType = void 0;
49368
50409
 
49369
50410
  exports.UsageEventMetric = void 0;
49370
50411
  (function (UsageEventMetric) {
50412
+ UsageEventMetric["AnalyticsEvents"] = "analytics.events";
50413
+ UsageEventMetric["AnalyticsPageviews"] = "analytics.pageviews";
50414
+ UsageEventMetric["AnalyticsBotsEvents"] = "analytics.bots.events";
49371
50415
  UsageEventMetric["NetworkRequests"] = "network.requests";
49372
50416
  UsageEventMetric["NetworkInbound"] = "network.inbound";
49373
50417
  UsageEventMetric["NetworkOutbound"] = "network.outbound";
@@ -49485,6 +50529,7 @@ exports.UsageOrderDirection = void 0;
49485
50529
 
49486
50530
  exports.UsageGaugeMetric = void 0;
49487
50531
  (function (UsageGaugeMetric) {
50532
+ UsageGaugeMetric["AnalyticsProperties"] = "analytics.properties";
49488
50533
  UsageGaugeMetric["Teams"] = "teams";
49489
50534
  UsageGaugeMetric["Users"] = "users";
49490
50535
  UsageGaugeMetric["Messages"] = "messages";
@@ -49760,6 +50805,7 @@ exports.ProxyRuleDeploymentResourceType = void 0;
49760
50805
  (function (ProxyRuleDeploymentResourceType) {
49761
50806
  ProxyRuleDeploymentResourceType["Function"] = "function";
49762
50807
  ProxyRuleDeploymentResourceType["Site"] = "site";
50808
+ ProxyRuleDeploymentResourceType["DedicatedDatabase"] = "dedicatedDatabase";
49763
50809
  })(exports.ProxyRuleDeploymentResourceType || (exports.ProxyRuleDeploymentResourceType = {}));
49764
50810
 
49765
50811
  exports.ProxyRuleStatus = void 0;
@@ -49819,6 +50865,8 @@ exports.Account = Account;
49819
50865
  exports.Activities = Activities;
49820
50866
  exports.Advisor = Advisor;
49821
50867
  exports.Affiliates = Affiliates;
50868
+ exports.Analytics = Analytics;
50869
+ exports.AnalyticsTracking = AnalyticsTracking;
49822
50870
  exports.Apps = Apps;
49823
50871
  exports.AppwriteException = AppwriteException;
49824
50872
  exports.Assistant = Assistant;