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