canada-api 3.0.4 → 4.0.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/CONTRIBUTING.md +0 -7
- package/LICENSE +2 -1
- package/README.md +11 -69
- package/dist/ca.js +1 -1
- package/package.json +3 -6
- package/src/children.mjs +46 -0
- package/src/content.mjs +23 -0
- package/src/index.mjs +15 -0
- package/src/meta.mjs +86 -0
- package/src/normalize.mjs +33 -0
- package/src/request.mjs +9 -0
- package/webpack.config.js +2 -1
- package/SECURITY.md +0 -14
- package/src/basic/children.js +0 -35
- package/src/basic/content.js +0 -15
- package/src/basic/meta.js +0 -71
- package/src/core/normalize.js +0 -123
- package/src/core/request.js +0 -98
- package/src/index.js +0 -16
package/CONTRIBUTING.md
CHANGED
|
@@ -8,9 +8,6 @@ Feel free to propose changes by creating Pull Requests. If you don't have write
|
|
|
8
8
|
|
|
9
9
|
If this is your first time contributing on GitHub, don't worry! Let us know if you have any questions.
|
|
10
10
|
|
|
11
|
-
### Security
|
|
12
|
-
|
|
13
|
-
**Do not post any security issues on the public repository!** See [SECURITY.md](SECURITY.md)
|
|
14
11
|
______________________
|
|
15
12
|
|
|
16
13
|
## Comment contribuer
|
|
@@ -20,7 +17,3 @@ Lorsque vous contribuez, veuillez également publier des commentaires et discute
|
|
|
20
17
|
N'hésitez pas à proposer des modifications en créant des demandes de tirage (Pull Requests). Si vous n'avez pas accès au mode de rédaction, la modification d'un fichier créera une copie (Fork) de ce projet afin que vous puissiez enregistrer les modifications que vous proposez. Le fait de proposer une modification à un fichier l'écrira dans une nouvelle branche dans votre copie (Fork), de sorte que vous puissiez envoyer une demande de tirage (Pull Request).
|
|
21
18
|
|
|
22
19
|
Si c'est la première fois que vous contribuez à GitHub, ne vous en faites pas! Faites-nous part de vos questions.
|
|
23
|
-
|
|
24
|
-
### Sécurité
|
|
25
|
-
|
|
26
|
-
**Ne publiez aucun problème de sécurité sur le dépôt publique!** Voir [SECURITY.md](SECURITY.md)
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) His Majesty the King in Right of Canada, as represented by the
|
|
3
|
+
Copyright (c) His Majesty the King in Right of Canada, as represented by the
|
|
4
|
+
Minister of National Defence, 2022.
|
|
4
5
|
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
7
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Cross platform API for fetching public data from [canada.ca](https://www.canada.
|
|
|
7
7
|
|
|
8
8
|
## Browser
|
|
9
9
|
```html
|
|
10
|
-
<script src="https://cdn.jsdelivr.net/npm/canada-api@
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/canada-api@4.0.0"></script>
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
## Node 10+
|
|
@@ -29,47 +29,26 @@ const ca = require('canada-api')
|
|
|
29
29
|
### `ca.request(url)`
|
|
30
30
|
|
|
31
31
|
- `url` {string|URL} relative or absolute URL on [canada.ca](https://www.canada.ca)
|
|
32
|
-
- Returns: {Promise} Fulfills with {Object} upon success
|
|
32
|
+
- Returns: {Promise} Fulfills with axios response {Object} upon success
|
|
33
33
|
|
|
34
34
|
Throws {Error} if the request does not complete successfully or if the destination URL is not on [canada.ca](https://www.canada.ca).
|
|
35
35
|
|
|
36
|
-
The properties included on each object:
|
|
37
|
-
- `url` {string} destination URL
|
|
38
|
-
- `redirected` {boolean} If the destination path is different from the request
|
|
39
|
-
- `data` {string|Object} Document content as string or json data
|
|
40
|
-
|
|
41
36
|
```json
|
|
42
37
|
{
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
38
|
+
"data": {},
|
|
39
|
+
"status": 200,
|
|
40
|
+
"statusText": "OK",
|
|
41
|
+
"headers": {},
|
|
42
|
+
"config": {},
|
|
43
|
+
"request": {}
|
|
46
44
|
}
|
|
47
45
|
```
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
### `ca.request.limiter`
|
|
51
|
-
|
|
52
|
-
- {Bottleneck}
|
|
53
|
-
|
|
54
|
-
The [Rate limiter](https://github.com/SGrondin/bottleneck#readme) used in `ca.request()`.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
### `ca.normalize(url[, type])`
|
|
47
|
+
### `ca.normalize(url)`
|
|
58
48
|
|
|
59
49
|
- `url` {string|URL} node URL
|
|
60
|
-
- `type` {string} Possible values `'path'`, `'children'`, `'content'` or `'meta'`. **Default**: `'path'`
|
|
61
|
-
- Returns: {URL} Normalized URL
|
|
62
|
-
|
|
63
|
-
Validates and formats [canada.ca](https://www.canada.ca) URLs based on type. URLs can take many forms, so not all options will be valid. Throws an {Error} if the URL is invalid, or the type requested is not possible.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
### `ca.normalize.baseURL`
|
|
67
|
-
|
|
68
|
-
- {string}
|
|
69
|
-
|
|
70
|
-
Base URL used for resolving relative URLs as well as URL validation. Value is `'https://www.canada.ca'`.
|
|
71
|
-
|
|
72
50
|
|
|
51
|
+
Validates and formats [canada.ca](https://www.canada.ca). Throws an {Error} if the URL is invalid, or the type requested is not possible.
|
|
73
52
|
|
|
74
53
|
## Basic API
|
|
75
54
|
|
|
@@ -82,12 +61,10 @@ Parses sitemaps to get a list of child nodes.
|
|
|
82
61
|
|
|
83
62
|
```json
|
|
84
63
|
{
|
|
85
|
-
"url": "https://www.canada.ca/en/department-national-defence.sitemap.xml",
|
|
86
|
-
"redirected": false,
|
|
87
64
|
"data": [
|
|
88
65
|
{
|
|
89
66
|
"path": "https://www.canada.ca/en/department-national-defence/...",
|
|
90
|
-
"lastmod": "2022-09-
|
|
67
|
+
"lastmod": "2022-09-20"
|
|
91
68
|
},
|
|
92
69
|
]
|
|
93
70
|
}
|
|
@@ -102,27 +79,12 @@ Getting children of DAM folders/assets is not available.
|
|
|
102
79
|
|
|
103
80
|
Retrieves the document contents.
|
|
104
81
|
|
|
105
|
-
The properties included on each object:
|
|
106
82
|
```json
|
|
107
83
|
{
|
|
108
|
-
"url": "https://www.canada.ca/en/department-national-defence.html",
|
|
109
|
-
"redirected": false,
|
|
110
84
|
"data": "<!DOCTYPE html>\r\n...."
|
|
111
85
|
}
|
|
112
86
|
```
|
|
113
87
|
|
|
114
|
-
Can also be used for DAM assets:
|
|
115
|
-
|
|
116
|
-
```json
|
|
117
|
-
{
|
|
118
|
-
"url": "https://www.canada.ca/content/dam/dnd-mdn/documents/json/maple-en.json",
|
|
119
|
-
"redirected": false,
|
|
120
|
-
"data": {
|
|
121
|
-
"data": []
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
88
|
### `ca.meta(url)`
|
|
127
89
|
|
|
128
90
|
- `url` {string|URL} absolute or relative URL
|
|
@@ -130,11 +92,8 @@ Can also be used for DAM assets:
|
|
|
130
92
|
|
|
131
93
|
Nodes contain a variety of metadata properties that can be accessed through a public API. Some properties such as date formats are reformatted for consistency.
|
|
132
94
|
|
|
133
|
-
The properties included on each object:
|
|
134
95
|
```json
|
|
135
96
|
{
|
|
136
|
-
"url": "https://www.canada.ca/en/department-national-defence/_jcr_content.json",
|
|
137
|
-
"redirected": false,
|
|
138
97
|
"data": {
|
|
139
98
|
"cq:lastModified": "2022-10-25T19:16:28.000Z",
|
|
140
99
|
"fluidWidth": false,
|
|
@@ -142,20 +101,3 @@ The properties included on each object:
|
|
|
142
101
|
}
|
|
143
102
|
```
|
|
144
103
|
|
|
145
|
-
Can also be used for DAM assets:
|
|
146
|
-
|
|
147
|
-
```json
|
|
148
|
-
{
|
|
149
|
-
"url": "https://www.canada.ca/content/dam/dnd-mdn/documents/json/maple-en.json/_jcr_content.json",
|
|
150
|
-
"redirected": false,
|
|
151
|
-
"data": {
|
|
152
|
-
"dam:assetState": "processed",
|
|
153
|
-
"jcr:lastModified": "2022-10-26T19:39:54.000Z",
|
|
154
|
-
"jcr:primaryType": "dam:AssetContent"
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
## Extended API
|
|
160
|
-
|
|
161
|
-
TBD
|
package/dist/ca.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("ca",[],e):"object"==typeof exports?exports.ca=e():t.ca=e()}("undefined"!=typeof self?self:this,(()=>(()=>{var t={209:function(t,e,s){t.exports=function(){"use strict";var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==s.g?s.g:"undefined"!=typeof self?self:{};var e,r,i={load:function(t,e,s={}){var r,i,n;for(r in e)n=e[r],s[r]=null!=(i=t[r])?i:n;return s},overwrite:function(t,e,s={}){var r,i;for(r in t)i=t[r],void 0!==e[r]&&(s[r]=i);return s}},n=class{constructor(t,e){this.incr=t,this.decr=e,this._first=null,this._last=null,this.length=0}push(t){var e;this.length++,"function"==typeof this.incr&&this.incr(),e={value:t,prev:this._last,next:null},null!=this._last?(this._last.next=e,this._last=e):this._first=this._last=e}shift(){var t;if(null!=this._first)return this.length--,"function"==typeof this.decr&&this.decr(),t=this._first.value,null!=(this._first=this._first.next)?this._first.prev=null:this._last=null,t}first(){if(null!=this._first)return this._first.value}getArray(){var t,e,s;for(t=this._first,s=[];null!=t;)s.push((e=t,t=t.next,e.value));return s}forEachShift(t){var e;for(e=this.shift();null!=e;)t(e),e=this.shift()}debug(){var t,e,s,r,i;for(t=this._first,i=[];null!=t;)i.push((e=t,t=t.next,{value:e.value,prev:null!=(s=e.prev)?s.value:void 0,next:null!=(r=e.next)?r.value:void 0}));return i}},o=class{constructor(t){if(this.instance=t,this._events={},null!=this.instance.on||null!=this.instance.once||null!=this.instance.removeAllListeners)throw new Error("An Emitter already exists for this object");this.instance.on=(t,e)=>this._addListener(t,"many",e),this.instance.once=(t,e)=>this._addListener(t,"once",e),this.instance.removeAllListeners=(t=null)=>null!=t?delete this._events[t]:this._events={}}_addListener(t,e,s){var r;return null==(r=this._events)[t]&&(r[t]=[]),this._events[t].push({cb:s,status:e}),this.instance}listenerCount(t){return null!=this._events[t]?this._events[t].length:0}async trigger(t,...e){var s,r;try{if("debug"!==t&&this.trigger("debug",`Event triggered: ${t}`,e),null==this._events[t])return;return this._events[t]=this._events[t].filter((function(t){return"none"!==t.status})),r=this._events[t].map((async t=>{var s,r;if("none"!==t.status){"once"===t.status&&(t.status="none");try{return"function"==typeof(null!=(r="function"==typeof t.cb?t.cb(...e):void 0)?r.then:void 0)?await r:r}catch(t){return s=t,this.trigger("error",s),null}}})),(await Promise.all(r)).find((function(t){return null!=t}))}catch(t){return s=t,this.trigger("error",s),null}}};e=n,r=o;var a,h,u=class extends Error{};h=i,a=u;var l,c;c=i,l=u;var d;d=u;var p;p=n;var _,f,v,m,g,y="2.19.5",w={version:y},b=Object.freeze({version:y,default:w}),E=()=>console.log("You must import the full version of Bottleneck in order to use this feature."),x=()=>console.log("You must import the full version of Bottleneck in order to use this feature.");g=i,_=o,v=E,f=x,m=()=>console.log("You must import the full version of Bottleneck in order to use this feature.");var O,j,k=function(){class t{constructor(t={}){this.deleteKey=this.deleteKey.bind(this),this.limiterOptions=t,g.load(this.limiterOptions,this.defaults,this),this.Events=new _(this),this.instances={},this.Bottleneck=U,this._startAutoCleanup(),this.sharedConnection=null!=this.connection,null==this.connection&&("redis"===this.limiterOptions.datastore?this.connection=new v(Object.assign({},this.limiterOptions,{Events:this.Events})):"ioredis"===this.limiterOptions.datastore&&(this.connection=new f(Object.assign({},this.limiterOptions,{Events:this.Events}))))}key(t=""){var e;return null!=(e=this.instances[t])?e:(()=>{var e;return e=this.instances[t]=new this.Bottleneck(Object.assign(this.limiterOptions,{id:`${this.id}-${t}`,timeout:this.timeout,connection:this.connection})),this.Events.trigger("created",e,t),e})()}async deleteKey(t=""){var e,s;return s=this.instances[t],this.connection&&(e=await this.connection.__runCommand__(["del",...m.allKeys(`${this.id}-${t}`)])),null!=s&&(delete this.instances[t],await s.disconnect()),null!=s||e>0}limiters(){var t,e,s,r;for(t in s=[],e=this.instances)r=e[t],s.push({key:t,limiter:r});return s}keys(){return Object.keys(this.instances)}async clusterKeys(){var t,e,s,r,i,n,o,a,h;if(null==this.connection)return this.Promise.resolve(this.keys());for(n=[],t=null,h=`b_${this.id}-`.length,e="_settings".length;0!==t;)for([a,s]=await this.connection.__runCommand__(["scan",null!=t?t:0,"match",`b_${this.id}-*_settings`,"count",1e4]),t=~~a,r=0,o=s.length;r<o;r++)i=s[r],n.push(i.slice(h,-e));return n}_startAutoCleanup(){var t;return clearInterval(this.interval),"function"==typeof(t=this.interval=setInterval((async()=>{var t,e,s,r,i,n;for(e in i=Date.now(),r=[],s=this.instances){n=s[e];try{await n._store.__groupCheck__(i)?r.push(this.deleteKey(e)):r.push(void 0)}catch(e){t=e,r.push(n.Events.trigger("error",t))}}return r}),this.timeout/2)).unref?t.unref():void 0}updateSettings(t={}){if(g.overwrite(t,this.defaults,this),g.overwrite(t,t,this.limiterOptions),null!=t.timeout)return this._startAutoCleanup()}disconnect(t=!0){var e;if(!this.sharedConnection)return null!=(e=this.connection)?e.disconnect(t):void 0}}return t.prototype.defaults={timeout:3e5,connection:null,Promise,id:"group-key"},t}.call(t);j=i,O=o;var R,I,D,C,T,L,S,P,A,q=function(){class t{constructor(t={}){this.options=t,j.load(this.options,this.defaults,this),this.Events=new O(this),this._arr=[],this._resetPromise(),this._lastFlush=Date.now()}_resetPromise(){return this._promise=new this.Promise(((t,e)=>this._resolve=t))}_flush(){return clearTimeout(this._timeout),this._lastFlush=Date.now(),this._resolve(),this.Events.trigger("batch",this._arr),this._arr=[],this._resetPromise()}add(t){var e;return this._arr.push(t),e=this._promise,this._arr.length===this.maxSize?this._flush():null!=this.maxTime&&1===this._arr.length&&(this._timeout=setTimeout((()=>this._flush()),this.maxTime)),e}}return t.prototype.defaults={maxTime:null,maxSize:null,Promise},t}.call(t),$=(A=b)&&A.default||A,N=[].splice;P=i,C=class{constructor(t){this.Events=new r(this),this._length=0,this._lists=function(){var s,r,i;for(i=[],s=1,r=t;1<=r?s<=r:s>=r;1<=r?++s:--s)i.push(new e((()=>this.incr()),(()=>this.decr())));return i}.call(this)}incr(){if(0==this._length++)return this.Events.trigger("leftzero")}decr(){if(0==--this._length)return this.Events.trigger("zero")}push(t){return this._lists[t.options.priority].push(t)}queued(t){return null!=t?this._lists[t].length:this._length}shiftAll(t){return this._lists.forEach((function(e){return e.forEachShift(t)}))}getFirst(t=this._lists){var e,s,r;for(e=0,s=t.length;e<s;e++)if((r=t[e]).length>0)return r;return[]}shiftLastFrom(t){return this.getFirst(this._lists.slice(t).reverse()).shift()}},I=class{constructor(t,e,s,r,i,n,o,a){this.task=t,this.args=e,this.rejectOnDrop=i,this.Events=n,this._states=o,this.Promise=a,this.options=h.load(s,r),this.options.priority=this._sanitizePriority(this.options.priority),this.options.id===r.id&&(this.options.id=`${this.options.id}-${this._randomIndex()}`),this.promise=new this.Promise(((t,e)=>{this._resolve=t,this._reject=e})),this.retryCount=0}_sanitizePriority(t){var e;return(e=~~t!==t?5:t)<0?0:e>9?9:e}_randomIndex(){return Math.random().toString(36).slice(2)}doDrop({error:t,message:e="This job has been dropped by Bottleneck"}={}){return!!this._states.remove(this.options.id)&&(this.rejectOnDrop&&this._reject(null!=t?t:new a(e)),this.Events.trigger("dropped",{args:this.args,options:this.options,task:this.task,promise:this.promise}),!0)}_assertStatus(t){var e;if((e=this._states.jobStatus(this.options.id))!==t&&("DONE"!==t||null!==e))throw new a(`Invalid job status ${e}, expected ${t}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`)}doReceive(){return this._states.start(this.options.id),this.Events.trigger("received",{args:this.args,options:this.options})}doQueue(t,e){return this._assertStatus("RECEIVED"),this._states.next(this.options.id),this.Events.trigger("queued",{args:this.args,options:this.options,reachedHWM:t,blocked:e})}doRun(){return 0===this.retryCount?(this._assertStatus("QUEUED"),this._states.next(this.options.id)):this._assertStatus("EXECUTING"),this.Events.trigger("scheduled",{args:this.args,options:this.options})}async doExecute(t,e,s,r){var i,n,o;0===this.retryCount?(this._assertStatus("RUNNING"),this._states.next(this.options.id)):this._assertStatus("EXECUTING"),n={args:this.args,options:this.options,retryCount:this.retryCount},this.Events.trigger("executing",n);try{if(o=await(null!=t?t.schedule(this.options,this.task,...this.args):this.task(...this.args)),e())return this.doDone(n),await r(this.options,n),this._assertStatus("DONE"),this._resolve(o)}catch(t){return i=t,this._onFailure(i,n,e,s,r)}}doExpire(t,e,s){var r,i;return this._states.jobStatus("RUNNING"===this.options.id)&&this._states.next(this.options.id),this._assertStatus("EXECUTING"),i={args:this.args,options:this.options,retryCount:this.retryCount},r=new a(`This job timed out after ${this.options.expiration} ms.`),this._onFailure(r,i,t,e,s)}async _onFailure(t,e,s,r,i){var n,o;if(s())return null!=(n=await this.Events.trigger("failed",t,e))?(o=~~n,this.Events.trigger("retry",`Retrying ${this.options.id} after ${o} ms`,e),this.retryCount++,r(o)):(this.doDone(e),await i(this.options,e),this._assertStatus("DONE"),this._reject(t))}doDone(t){return this._assertStatus("EXECUTING"),this._states.next(this.options.id),this.Events.trigger("done",t)}},D=class{constructor(t,e,s){this.instance=t,this.storeOptions=e,this.clientId=this.instance._randomIndex(),c.load(s,s,this),this._nextRequest=this._lastReservoirRefresh=this._lastReservoirIncrease=Date.now(),this._running=0,this._done=0,this._unblockTime=0,this.ready=this.Promise.resolve(),this.clients={},this._startHeartbeat()}_startHeartbeat(){var t;return null==this.heartbeat&&(null!=this.storeOptions.reservoirRefreshInterval&&null!=this.storeOptions.reservoirRefreshAmount||null!=this.storeOptions.reservoirIncreaseInterval&&null!=this.storeOptions.reservoirIncreaseAmount)?"function"==typeof(t=this.heartbeat=setInterval((()=>{var t,e,s,r,i;if(r=Date.now(),null!=this.storeOptions.reservoirRefreshInterval&&r>=this._lastReservoirRefresh+this.storeOptions.reservoirRefreshInterval&&(this._lastReservoirRefresh=r,this.storeOptions.reservoir=this.storeOptions.reservoirRefreshAmount,this.instance._drainAll(this.computeCapacity())),null!=this.storeOptions.reservoirIncreaseInterval&&r>=this._lastReservoirIncrease+this.storeOptions.reservoirIncreaseInterval&&(({reservoirIncreaseAmount:t,reservoirIncreaseMaximum:s,reservoir:i}=this.storeOptions),this._lastReservoirIncrease=r,(e=null!=s?Math.min(t,s-i):t)>0))return this.storeOptions.reservoir+=e,this.instance._drainAll(this.computeCapacity())}),this.heartbeatInterval)).unref?t.unref():void 0:clearInterval(this.heartbeat)}async __publish__(t){return await this.yieldLoop(),this.instance.Events.trigger("message",t.toString())}async __disconnect__(t){return await this.yieldLoop(),clearInterval(this.heartbeat),this.Promise.resolve()}yieldLoop(t=0){return new this.Promise((function(e,s){return setTimeout(e,t)}))}computePenalty(){var t;return null!=(t=this.storeOptions.penalty)?t:15*this.storeOptions.minTime||5e3}async __updateSettings__(t){return await this.yieldLoop(),c.overwrite(t,t,this.storeOptions),this._startHeartbeat(),this.instance._drainAll(this.computeCapacity()),!0}async __running__(){return await this.yieldLoop(),this._running}async __queued__(){return await this.yieldLoop(),this.instance.queued()}async __done__(){return await this.yieldLoop(),this._done}async __groupCheck__(t){return await this.yieldLoop(),this._nextRequest+this.timeout<t}computeCapacity(){var t,e;return({maxConcurrent:t,reservoir:e}=this.storeOptions),null!=t&&null!=e?Math.min(t-this._running,e):null!=t?t-this._running:null!=e?e:null}conditionsCheck(t){var e;return null==(e=this.computeCapacity())||t<=e}async __incrementReservoir__(t){var e;return await this.yieldLoop(),e=this.storeOptions.reservoir+=t,this.instance._drainAll(this.computeCapacity()),e}async __currentReservoir__(){return await this.yieldLoop(),this.storeOptions.reservoir}isBlocked(t){return this._unblockTime>=t}check(t,e){return this.conditionsCheck(t)&&this._nextRequest-e<=0}async __check__(t){var e;return await this.yieldLoop(),e=Date.now(),this.check(t,e)}async __register__(t,e,s){var r,i;return await this.yieldLoop(),r=Date.now(),this.conditionsCheck(e)?(this._running+=e,null!=this.storeOptions.reservoir&&(this.storeOptions.reservoir-=e),i=Math.max(this._nextRequest-r,0),this._nextRequest=r+i+this.storeOptions.minTime,{success:!0,wait:i,reservoir:this.storeOptions.reservoir}):{success:!1}}strategyIsBlock(){return 3===this.storeOptions.strategy}async __submit__(t,e){var s,r,i;if(await this.yieldLoop(),null!=this.storeOptions.maxConcurrent&&e>this.storeOptions.maxConcurrent)throw new l(`Impossible to add a job having a weight of ${e} to a limiter having a maxConcurrent setting of ${this.storeOptions.maxConcurrent}`);return r=Date.now(),i=null!=this.storeOptions.highWater&&t===this.storeOptions.highWater&&!this.check(e,r),(s=this.strategyIsBlock()&&(i||this.isBlocked(r)))&&(this._unblockTime=r+this.computePenalty(),this._nextRequest=this._unblockTime+this.storeOptions.minTime,this.instance._dropAllQueued()),{reachedHWM:i,blocked:s,strategy:this.storeOptions.strategy}}async __free__(t,e){return await this.yieldLoop(),this._running-=e,this._done+=e,this.instance._drainAll(this.computeCapacity()),{running:this._running}}},T=()=>console.log("You must import the full version of Bottleneck in order to use this feature."),R=o,L=class{constructor(t){this.status=t,this._jobs={},this.counts=this.status.map((function(){return 0}))}next(t){var e,s;return s=(e=this._jobs[t])+1,null!=e&&s<this.status.length?(this.counts[e]--,this.counts[s]++,this._jobs[t]++):null!=e?(this.counts[e]--,delete this._jobs[t]):void 0}start(t){return 0,this._jobs[t]=0,this.counts[0]++}remove(t){var e;return null!=(e=this._jobs[t])&&(this.counts[e]--,delete this._jobs[t]),null!=e}jobStatus(t){var e;return null!=(e=this.status[this._jobs[t]])?e:null}statusJobs(t){var e,s,r,i;if(null!=t){if((s=this.status.indexOf(t))<0)throw new d(`status must be one of ${this.status.join(", ")}`);for(e in i=[],r=this._jobs)r[e]===s&&i.push(e);return i}return Object.keys(this._jobs)}statusCounts(){return this.counts.reduce(((t,e,s)=>(t[this.status[s]]=e,t)),{})}},S=class{constructor(t,e){this.schedule=this.schedule.bind(this),this.name=t,this.Promise=e,this._running=0,this._queue=new p}isEmpty(){return 0===this._queue.length}async _tryToRun(){var t,e,s,r,i,n,o;if(this._running<1&&this._queue.length>0)return this._running++,({task:o,args:t,resolve:i,reject:r}=this._queue.shift()),e=await async function(){try{return n=await o(...t),function(){return i(n)}}catch(t){return s=t,function(){return r(s)}}}(),this._running--,this._tryToRun(),e()}schedule(t,...e){var s,r,i;return i=r=null,s=new this.Promise((function(t,e){return i=t,r=e})),this._queue.push({task:t,args:e,resolve:i,reject:r}),this._tryToRun(),s}};var U=function(){class t{constructor(e={},...s){var r,i;this._addToQueue=this._addToQueue.bind(this),this._validateOptions(e,s),P.load(e,this.instanceDefaults,this),this._queues=new C(10),this._scheduled={},this._states=new L(["RECEIVED","QUEUED","RUNNING","EXECUTING"].concat(this.trackDoneStatus?["DONE"]:[])),this._limiter=null,this.Events=new R(this),this._submitLock=new S("submit",this.Promise),this._registerLock=new S("register",this.Promise),i=P.load(e,this.storeDefaults,{}),this._store=function(){if("redis"===this.datastore||"ioredis"===this.datastore||null!=this.connection)return r=P.load(e,this.redisStoreDefaults,{}),new T(this,i,r);if("local"===this.datastore)return r=P.load(e,this.localStoreDefaults,{}),new D(this,i,r);throw new t.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`)}.call(this),this._queues.on("leftzero",(()=>{var t;return null!=(t=this._store.heartbeat)&&"function"==typeof t.ref?t.ref():void 0})),this._queues.on("zero",(()=>{var t;return null!=(t=this._store.heartbeat)&&"function"==typeof t.unref?t.unref():void 0}))}_validateOptions(e,s){if(null==e||"object"!=typeof e||0!==s.length)throw new t.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1.")}ready(){return this._store.ready}clients(){return this._store.clients}channel(){return`b_${this.id}`}channel_client(){return`b_${this.id}_${this._store.clientId}`}publish(t){return this._store.__publish__(t)}disconnect(t=!0){return this._store.__disconnect__(t)}chain(t){return this._limiter=t,this}queued(t){return this._queues.queued(t)}clusterQueued(){return this._store.__queued__()}empty(){return 0===this.queued()&&this._submitLock.isEmpty()}running(){return this._store.__running__()}done(){return this._store.__done__()}jobStatus(t){return this._states.jobStatus(t)}jobs(t){return this._states.statusJobs(t)}counts(){return this._states.statusCounts()}_randomIndex(){return Math.random().toString(36).slice(2)}check(t=1){return this._store.__check__(t)}_clearGlobalState(t){return null!=this._scheduled[t]&&(clearTimeout(this._scheduled[t].expiration),delete this._scheduled[t],!0)}async _free(t,e,s,r){var i,n;try{if(({running:n}=await this._store.__free__(t,s.weight)),this.Events.trigger("debug",`Freed ${s.id}`,r),0===n&&this.empty())return this.Events.trigger("idle")}catch(t){return i=t,this.Events.trigger("error",i)}}_run(t,e,s){var r,i,n;return e.doRun(),r=this._clearGlobalState.bind(this,t),n=this._run.bind(this,t,e),i=this._free.bind(this,t,e),this._scheduled[t]={timeout:setTimeout((()=>e.doExecute(this._limiter,r,n,i)),s),expiration:null!=e.options.expiration?setTimeout((function(){return e.doExpire(r,n,i)}),s+e.options.expiration):void 0,job:e}}_drainOne(t){return this._registerLock.schedule((()=>{var e,s,r,i,n;return 0===this.queued()?this.Promise.resolve(null):(n=this._queues.getFirst(),({options:i,args:e}=r=n.first()),null!=t&&i.weight>t?this.Promise.resolve(null):(this.Events.trigger("debug",`Draining ${i.id}`,{args:e,options:i}),s=this._randomIndex(),this._store.__register__(s,i.weight,i.expiration).then((({success:t,wait:o,reservoir:a})=>{var h;return this.Events.trigger("debug",`Drained ${i.id}`,{success:t,args:e,options:i}),t?(n.shift(),(h=this.empty())&&this.Events.trigger("empty"),0===a&&this.Events.trigger("depleted",h),this._run(s,r,o),this.Promise.resolve(i.weight)):this.Promise.resolve(null)}))))}))}_drainAll(t,e=0){return this._drainOne(t).then((s=>{var r;return null!=s?(r=null!=t?t-s:t,this._drainAll(r,e+s)):this.Promise.resolve(e)})).catch((t=>this.Events.trigger("error",t)))}_dropAllQueued(t){return this._queues.shiftAll((function(e){return e.doDrop({message:t})}))}stop(e={}){var s,r;return e=P.load(e,this.stopDefaults),r=t=>{var e;return e=()=>{var e;return(e=this._states.counts)[0]+e[1]+e[2]+e[3]===t},new this.Promise(((t,s)=>e()?t():this.on("done",(()=>{if(e())return this.removeAllListeners("done"),t()}))))},s=e.dropWaitingJobs?(this._run=function(t,s){return s.doDrop({message:e.dropErrorMessage})},this._drainOne=()=>this.Promise.resolve(null),this._registerLock.schedule((()=>this._submitLock.schedule((()=>{var t,s,i;for(t in s=this._scheduled)i=s[t],"RUNNING"===this.jobStatus(i.job.options.id)&&(clearTimeout(i.timeout),clearTimeout(i.expiration),i.job.doDrop({message:e.dropErrorMessage}));return this._dropAllQueued(e.dropErrorMessage),r(0)}))))):this.schedule({priority:9,weight:0},(()=>r(1))),this._receive=function(s){return s._reject(new t.prototype.BottleneckError(e.enqueueErrorMessage))},this.stop=()=>this.Promise.reject(new t.prototype.BottleneckError("stop() has already been called")),s}async _addToQueue(e){var s,r,i,n,o,a,h;({args:s,options:n}=e);try{({reachedHWM:o,blocked:r,strategy:h}=await this._store.__submit__(this.queued(),n.weight))}catch(t){return i=t,this.Events.trigger("debug",`Could not queue ${n.id}`,{args:s,options:n,error:i}),e.doDrop({error:i}),!1}return r?(e.doDrop(),!0):o&&(null!=(a=h===t.prototype.strategy.LEAK?this._queues.shiftLastFrom(n.priority):h===t.prototype.strategy.OVERFLOW_PRIORITY?this._queues.shiftLastFrom(n.priority+1):h===t.prototype.strategy.OVERFLOW?e:void 0)&&a.doDrop(),null==a||h===t.prototype.strategy.OVERFLOW)?(null==a&&e.doDrop(),o):(e.doQueue(o,r),this._queues.push(e),await this._drainAll(),o)}_receive(e){return null!=this._states.jobStatus(e.options.id)?(e._reject(new t.prototype.BottleneckError(`A job with the same id already exists (id=${e.options.id})`)),!1):(e.doReceive(),this._submitLock.schedule(this._addToQueue,e))}submit(...t){var e,s,r,i,n,o,a;return"function"==typeof t[0]?(n=t,[s,...t]=n,[e]=N.call(t,-1),i=P.load({},this.jobDefaults)):(o=t,[i,s,...t]=o,[e]=N.call(t,-1),i=P.load(i,this.jobDefaults)),a=(...t)=>new this.Promise((function(e,r){return s(...t,(function(...t){return(null!=t[0]?r:e)(t)}))})),(r=new I(a,t,i,this.jobDefaults,this.rejectOnDrop,this.Events,this._states,this.Promise)).promise.then((function(t){return"function"==typeof e?e(...t):void 0})).catch((function(t){return Array.isArray(t)?"function"==typeof e?e(...t):void 0:"function"==typeof e?e(t):void 0})),this._receive(r)}schedule(...t){var e,s,r;return"function"==typeof t[0]?([r,...t]=t,s={}):[s,r,...t]=t,e=new I(r,t,s,this.jobDefaults,this.rejectOnDrop,this.Events,this._states,this.Promise),this._receive(e),e.promise}wrap(t){var e,s;return e=this.schedule.bind(this),(s=function(...s){return e(t.bind(this),...s)}).withOptions=function(s,...r){return e(s,t,...r)},s}async updateSettings(t={}){return await this._store.__updateSettings__(P.overwrite(t,this.storeDefaults)),P.overwrite(t,this.instanceDefaults,this),this}currentReservoir(){return this._store.__currentReservoir__()}incrementReservoir(t=0){return this._store.__incrementReservoir__(t)}}return t.default=t,t.Events=R,t.version=t.prototype.version=$.version,t.strategy=t.prototype.strategy={LEAK:1,OVERFLOW:2,OVERFLOW_PRIORITY:4,BLOCK:3},t.BottleneckError=t.prototype.BottleneckError=u,t.Group=t.prototype.Group=k,t.RedisConnection=t.prototype.RedisConnection=E,t.IORedisConnection=t.prototype.IORedisConnection=x,t.Batcher=t.prototype.Batcher=q,t.prototype.jobDefaults={priority:5,weight:1,expiration:null,id:"<no-id>"},t.prototype.storeDefaults={maxConcurrent:null,minTime:0,highWater:null,strategy:t.prototype.strategy.LEAK,penalty:null,reservoir:null,reservoirRefreshInterval:null,reservoirRefreshAmount:null,reservoirIncreaseInterval:null,reservoirIncreaseAmount:null,reservoirIncreaseMaximum:null},t.prototype.localStoreDefaults={Promise,timeout:null,heartbeatInterval:250},t.prototype.redisStoreDefaults={Promise,timeout:null,heartbeatInterval:5e3,clientTimeout:1e4,Redis:null,clientOptions:{},clusterNodes:null,clearDatastore:!1,connection:null},t.prototype.instanceDefaults={datastore:"local",connection:null,id:"<no-id>",rejectOnDrop:!0,trackDoneStatus:!1,Promise},t.prototype.stopDefaults={enqueueErrorMessage:"This limiter has been stopped and cannot accept new jobs.",dropWaitingJobs:!0,dropErrorMessage:"This limiter has been stopped."},t}.call(t);return U}()},920:(t,e,s)=>{const r=s(797),i=s(36);t.exports=async t=>{t=r(t,"children");let e=await i(t),s=e.data.match(/<url>.*?<\/url>/g).map((t=>{let e=t.match(/<loc>([^<]+)<\/loc>/),s=t.match(/<lastmod>([^<]+)<\/lastmod>/);return{path:r(e[1]).pathname,lastmod:s?new Date(s[1]).toISOString():null}}));return s.length&&s[0].path===r(t).pathname&&s.shift(),e.data=s,e}},420:(t,e,s)=>{const r=s(797),i=s(36);t.exports=async t=>(t=r(t,"content"),i(t))},30:(t,e,s)=>{const r=s(797),i=s(36),n={Jan:"01",Feb:"02",Mar:"03",Apr:"04",May:"05",Jun:"06",Jul:"07",Aug:"08",Sep:"09",Oct:"10",Nov:"11",Dec:"12"};function o(t){if(/^\d{4}-\d{2}-\d{2}$/.test(t))return new Date(t).toISOString();let e=/^\w{3} (\w{3}) (\d{2}) (\d{4}) ([\d:]{8}) GMT([\-+]\d{4})$/.exec(t);return e?new Date(e[3]+"-"+n[e[1]]+"-"+e[2]+"T"+e[4]+e[5]).toISOString():t}t.exports=async t=>{t=r(t,"meta");let e=await i(t),s=e.data;for(const[t,e]of Object.entries(s))"true"===e?s[t]=!0:"false"===e?s[t]=!1:t.endsWith("@TypeHint")?delete s[t]:"string"==typeof e?s[t]=o(s[t].trim()):Array.isArray(e)&&0===e.length&&delete s[t];return e.data=Object.keys(e.data).sort().reduce(((t,e)=>(t[e]=s[e],t)),{}),e}},797:(t,e)=>{const s="https://www.canada.ca/";t.exports=e=(t,e="path")=>{if("string"==typeof t)t=new URL(t,s);else if(!(t instanceof URL))throw new TypeError("string or URL object expected");if(t.protocol="https",!t.href.startsWith(s))throw new Error("URL must start with "+s);let r=t.pathname.startsWith("/content/dam");if(r||(t.pathname=t.pathname.replace(/^\/content\/canadasite\//,"")),!/^\/(en|fr|content\/dam)(\/|\.|$)/.test(t.pathname))throw new Error("Invalid root");return t.pathname=t.pathname.replace(/\/+$/,""),t.pathname.includes("/_jcr_content/par")?function(t,e){if("path"===e)throw new Error("Cant determine path of a reference node directly");if("meta"===e)t.pathname=t.pathname.replace(/\/image\.img\.\w+\//,"/image.json/");else if("children"===e)throw new Error("Cant load children of a reference node");return t}(t,e):r?function(t,e){let s=/(\/|\/\w+)$/.test(t.pathname);if("meta"===e)t.pathname+=s?".json":"/_jcr_content.json";else{if("children"===e)throw new Error("Cant load children of an asset node");if("content"===e&&s)throw new Error("Cant load content of an asset node")}return t}(t,e):function(t,e){return t.pathname=t.pathname.replace(/\/?\.(sitemap\.xml|[^/.]+)$/,""),"meta"===e?t.pathname+="/_jcr_content.json":"children"===e?t.pathname+=".sitemap.xml":"content"===e&&(t.pathname+=".html"),t}(t,e)},e.baseURL=s},36:(t,e,s)=>{const r=s(797);let i=new(s(209))({reservoir:150,reservoirRefreshAmount:150,reservoirRefreshInterval:5e3,maxConcurrent:10,trackDoneStatus:!0});const n=t=>fetch(t);async function o(t){return t.headers.get("content-type").includes("application/json")?t.json():t.text()}t.exports=e=async function(t){"string"==typeof t&&(t=new URL(t,r.baseURL)),t.searchParams.set("_",Date.now());let e=null;if(e=i?await i.schedule(n,t,{headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0"}}):await fetch(t,{headers:{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0"}}),!e.ok)throw new Error(e.statusText);if(!e.url.startsWith(r.baseURL))throw new Error("Invalid destination URL");let s=r(t).pathname!==r(e.url).pathname;return{url:e.url,redirected:s,data:await o(e)}},e.limiter=i},138:(t,e,s)=>{const r=s(36),i=s(797),n=s(920),o=s(420),a=s(30);t.exports={request:r,normalize:i,children:n,content:o,meta:a}}},e={};function s(r){var i=e[r];if(void 0!==i)return i.exports;var n=e[r]={exports:{}};return t[r].call(n.exports,n,n.exports,s),n.exports}return s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),s(138)})()));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("ca",[],t):"object"==typeof exports?exports.ca=t():e.ca=t()}("undefined"!=typeof self?self:this,(()=>(()=>{"use strict";var e={d:(t,n)=>{for(var r in n)e.o(n,r)&&!e.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:n[r]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{default:()=>vt});var n={};e.r(n),e.d(n,{hasBrowserEnv:()=>ue,hasStandardBrowserEnv:()=>de,hasStandardBrowserWebWorkerEnv:()=>pe,navigator:()=>fe,origin:()=>he});const r=e=>{if("string"==typeof e)e=new URL(e,"https://www.canada.ca/");else if(!(e instanceof URL))throw new TypeError("string or URL object expected");if("https://www.canada.ca"!==e.origin)throw new Error("URL must start with "+baseURL);if(e.pathname=e.pathname.replace(/^\/content\/canadasite/,""),!e.pathname.startsWith("/en/")&&!e.pathname.startsWith("/fr/"))throw new Error("Invalid path");return e.pathname=e.pathname.replace(/(\.[^/]+|\/+)$/,""),e};function o(e,t){return function(){return e.apply(t,arguments)}}const{toString:s}=Object.prototype,{getPrototypeOf:i}=Object,a=(c=Object.create(null),e=>{const t=s.call(e);return c[t]||(c[t]=t.slice(8,-1).toLowerCase())});var c;const l=e=>(e=e.toLowerCase(),t=>a(t)===e),u=e=>t=>typeof t===e,{isArray:f}=Array,d=u("undefined"),p=l("ArrayBuffer"),h=u("string"),m=u("function"),y=u("number"),b=e=>null!==e&&"object"==typeof e,g=e=>{if("object"!==a(e))return!1;const t=i(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||Symbol.toStringTag in e||Symbol.iterator in e)},w=l("Date"),E=l("File"),R=l("Blob"),O=l("FileList"),S=l("URLSearchParams"),[T,A,v,j]=["ReadableStream","Request","Response","Headers"].map(l);function x(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let r,o;if("object"!=typeof e&&(e=[e]),f(e))for(r=0,o=e.length;r<o;r++)t.call(null,e[r],r,e);else{const o=n?Object.getOwnPropertyNames(e):Object.keys(e),s=o.length;let i;for(r=0;r<s;r++)i=o[r],t.call(null,e[i],i,e)}}function P(e,t){t=t.toLowerCase();const n=Object.keys(e);let r,o=n.length;for(;o-- >0;)if(r=n[o],t===r.toLowerCase())return r;return null}const C="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,N=e=>!d(e)&&e!==C,U=(L="undefined"!=typeof Uint8Array&&i(Uint8Array),e=>L&&e instanceof L);var L;const _=l("HTMLFormElement"),F=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),B=l("RegExp"),D=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};x(n,((n,o)=>{let s;!1!==(s=t(n,o,e))&&(r[o]=s||n)})),Object.defineProperties(e,r)},k=l("AsyncFunction"),q=(M="function"==typeof setImmediate,I=m(C.postMessage),M?setImmediate:I?(z=`axios@${Math.random()}`,J=[],C.addEventListener("message",(({source:e,data:t})=>{e===C&&t===z&&J.length&&J.shift()()}),!1),e=>{J.push(e),C.postMessage(z,"*")}):e=>setTimeout(e));var M,I,z,J;const H="undefined"!=typeof queueMicrotask?queueMicrotask.bind(C):"undefined"!=typeof process&&process.nextTick||q,W={isArray:f,isArrayBuffer:p,isBuffer:function(e){return null!==e&&!d(e)&&null!==e.constructor&&!d(e.constructor)&&m(e.constructor.isBuffer)&&e.constructor.isBuffer(e)},isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||m(e.append)&&("formdata"===(t=a(e))||"object"===t&&m(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&p(e.buffer),t},isString:h,isNumber:y,isBoolean:e=>!0===e||!1===e,isObject:b,isPlainObject:g,isReadableStream:T,isRequest:A,isResponse:v,isHeaders:j,isUndefined:d,isDate:w,isFile:E,isBlob:R,isRegExp:B,isFunction:m,isStream:e=>b(e)&&m(e.pipe),isURLSearchParams:S,isTypedArray:U,isFileList:O,forEach:x,merge:function e(){const{caseless:t}=N(this)&&this||{},n={},r=(r,o)=>{const s=t&&P(n,o)||o;g(n[s])&&g(r)?n[s]=e(n[s],r):g(r)?n[s]=e({},r):f(r)?n[s]=r.slice():n[s]=r};for(let e=0,t=arguments.length;e<t;e++)arguments[e]&&x(arguments[e],r);return n},extend:(e,t,n,{allOwnKeys:r}={})=>(x(t,((t,r)=>{n&&m(t)?e[r]=o(t,n):e[r]=t}),{allOwnKeys:r}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,r)=>{let o,s,a;const c={};if(t=t||{},null==e)return t;do{for(o=Object.getOwnPropertyNames(e),s=o.length;s-- >0;)a=o[s],r&&!r(a,e,t)||c[a]||(t[a]=e[a],c[a]=!0);e=!1!==n&&i(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:a,kindOfTest:l,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return-1!==r&&r===n},toArray:e=>{if(!e)return null;if(f(e))return e;let t=e.length;if(!y(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=n.next())&&!r.done;){const n=r.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const r=[];for(;null!==(n=e.exec(t));)r.push(n);return r},isHTMLForm:_,hasOwnProperty:F,hasOwnProp:F,reduceDescriptors:D,freezeMethods:e=>{D(e,((t,n)=>{if(m(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const r=e[n];m(r)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(e,t)=>{const n={},r=e=>{e.forEach((e=>{n[e]=!0}))};return f(e)?r(e):r(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,n){return t.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(e,t)=>null!=e&&Number.isFinite(e=+e)?e:t,findKey:P,global:C,isContextDefined:N,isSpecCompliantForm:function(e){return!!(e&&m(e.append)&&"FormData"===e[Symbol.toStringTag]&&e[Symbol.iterator])},toJSONObject:e=>{const t=new Array(10),n=(e,r)=>{if(b(e)){if(t.indexOf(e)>=0)return;if(!("toJSON"in e)){t[r]=e;const o=f(e)?[]:{};return x(e,((e,t)=>{const s=n(e,r+1);!d(s)&&(o[t]=s)})),t[r]=void 0,o}}return e};return n(e,0)},isAsyncFn:k,isThenable:e=>e&&(b(e)||m(e))&&m(e.then)&&m(e.catch),setImmediate:q,asap:H};function K(e,t,n,r,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o,this.status=o.status?o.status:null)}W.inherits(K,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:W.toJSONObject(this.config),code:this.code,status:this.status}}});const V=K.prototype,$={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((e=>{$[e]={value:e}})),Object.defineProperties(K,$),Object.defineProperty(V,"isAxiosError",{value:!0}),K.from=(e,t,n,r,o,s)=>{const i=Object.create(V);return W.toFlatObject(e,i,(function(e){return e!==Error.prototype}),(e=>"isAxiosError"!==e)),K.call(i,e.message,t,n,r,o),i.cause=e,i.name=e.name,s&&Object.assign(i,s),i};const X=K;function G(e){return W.isPlainObject(e)||W.isArray(e)}function Q(e){return W.endsWith(e,"[]")?e.slice(0,-2):e}function Z(e,t,n){return e?e.concat(t).map((function(e,t){return e=Q(e),!n&&t?"["+e+"]":e})).join(n?".":""):t}const Y=W.toFlatObject(W,{},null,(function(e){return/^is[A-Z]/.test(e)})),ee=function(e,t,n){if(!W.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;const r=(n=W.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!W.isUndefined(t[e])}))).metaTokens,o=n.visitor||l,s=n.dots,i=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&W.isSpecCompliantForm(t);if(!W.isFunction(o))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(W.isDate(e))return e.toISOString();if(!a&&W.isBlob(e))throw new X("Blob is not supported. Use a Buffer instead.");return W.isArrayBuffer(e)||W.isTypedArray(e)?a&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function l(e,n,o){let a=e;if(e&&!o&&"object"==typeof e)if(W.endsWith(n,"{}"))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(W.isArray(e)&&function(e){return W.isArray(e)&&!e.some(G)}(e)||(W.isFileList(e)||W.endsWith(n,"[]"))&&(a=W.toArray(e)))return n=Q(n),a.forEach((function(e,r){!W.isUndefined(e)&&null!==e&&t.append(!0===i?Z([n],r,s):null===i?n:n+"[]",c(e))})),!1;return!!G(e)||(t.append(Z(o,n,s),c(e)),!1)}const u=[],f=Object.assign(Y,{defaultVisitor:l,convertValue:c,isVisitable:G});if(!W.isObject(e))throw new TypeError("data must be an object");return function e(n,r){if(!W.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+r.join("."));u.push(n),W.forEach(n,(function(n,s){!0===(!(W.isUndefined(n)||null===n)&&o.call(t,n,W.isString(s)?s.trim():s,r,f))&&e(n,r?r.concat(s):[s])})),u.pop()}}(e),t};function te(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function ne(e,t){this._pairs=[],e&&ee(e,this,t)}const re=ne.prototype;re.append=function(e,t){this._pairs.push([e,t])},re.toString=function(e){const t=e?function(t){return e.call(this,t,te)}:te;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};const oe=ne;function se(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function ie(e,t,n){if(!t)return e;const r=n&&n.encode||se;W.isFunction(n)&&(n={serialize:n});const o=n&&n.serialize;let s;if(s=o?o(t,n):W.isURLSearchParams(t)?t.toString():new oe(t,n).toString(r),s){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+s}return e}const ae=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){W.forEach(this.handlers,(function(t){null!==t&&e(t)}))}},ce={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},le={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:oe,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]},ue="undefined"!=typeof window&&"undefined"!=typeof document,fe="object"==typeof navigator&&navigator||void 0,de=ue&&(!fe||["ReactNative","NativeScript","NS"].indexOf(fe.product)<0),pe="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,he=ue&&window.location.href||"http://localhost",me={...n,...le},ye=function(e){function t(e,n,r,o){let s=e[o++];if("__proto__"===s)return!0;const i=Number.isFinite(+s),a=o>=e.length;return s=!s&&W.isArray(r)?r.length:s,a?(W.hasOwnProp(r,s)?r[s]=[r[s],n]:r[s]=n,!i):(r[s]&&W.isObject(r[s])||(r[s]=[]),t(e,n,r[s],o)&&W.isArray(r[s])&&(r[s]=function(e){const t={},n=Object.keys(e);let r;const o=n.length;let s;for(r=0;r<o;r++)s=n[r],t[s]=e[s];return t}(r[s])),!i)}if(W.isFormData(e)&&W.isFunction(e.entries)){const n={};return W.forEachEntry(e,((e,r)=>{t(function(e){return W.matchAll(/\w+|\[(\w*)]/g,e).map((e=>"[]"===e[0]?"":e[1]||e[0]))}(e),r,n,0)})),n}return null},be={transitional:ce,adapter:["xhr","http","fetch"],transformRequest:[function(e,t){const n=t.getContentType()||"",r=n.indexOf("application/json")>-1,o=W.isObject(e);if(o&&W.isHTMLForm(e)&&(e=new FormData(e)),W.isFormData(e))return r?JSON.stringify(ye(e)):e;if(W.isArrayBuffer(e)||W.isBuffer(e)||W.isStream(e)||W.isFile(e)||W.isBlob(e)||W.isReadableStream(e))return e;if(W.isArrayBufferView(e))return e.buffer;if(W.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let s;if(o){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return ee(e,new me.classes.URLSearchParams,Object.assign({visitor:function(e,t,n,r){return me.isNode&&W.isBuffer(e)?(this.append(t,e.toString("base64")),!1):r.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((s=W.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return ee(s?{"files[]":e}:e,t&&new t,this.formSerializer)}}return o||r?(t.setContentType("application/json",!1),function(e,t,n){if(W.isString(e))try{return(0,JSON.parse)(e),W.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(0,JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||be.transitional,n=t&&t.forcedJSONParsing,r="json"===this.responseType;if(W.isResponse(e)||W.isReadableStream(e))return e;if(e&&W.isString(e)&&(n&&!this.responseType||r)){const n=!(t&&t.silentJSONParsing)&&r;try{return JSON.parse(e)}catch(e){if(n){if("SyntaxError"===e.name)throw X.from(e,X.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:me.classes.FormData,Blob:me.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};W.forEach(["delete","get","head","post","put","patch"],(e=>{be.headers[e]={}}));const ge=be,we=W.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Ee=Symbol("internals");function Re(e){return e&&String(e).trim().toLowerCase()}function Oe(e){return!1===e||null==e?e:W.isArray(e)?e.map(Oe):String(e)}function Se(e,t,n,r,o){return W.isFunction(r)?r.call(this,t,n):(o&&(t=n),W.isString(t)?W.isString(r)?-1!==t.indexOf(r):W.isRegExp(r)?r.test(t):void 0:void 0)}class Te{constructor(e){e&&this.set(e)}set(e,t,n){const r=this;function o(e,t,n){const o=Re(t);if(!o)throw new Error("header name must be a non-empty string");const s=W.findKey(r,o);(!s||void 0===r[s]||!0===n||void 0===n&&!1!==r[s])&&(r[s||t]=Oe(e))}const s=(e,t)=>W.forEach(e,((e,n)=>o(e,n,t)));if(W.isPlainObject(e)||e instanceof this.constructor)s(e,t);else if(W.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))s((e=>{const t={};let n,r,o;return e&&e.split("\n").forEach((function(e){o=e.indexOf(":"),n=e.substring(0,o).trim().toLowerCase(),r=e.substring(o+1).trim(),!n||t[n]&&we[n]||("set-cookie"===n?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)})),t})(e),t);else if(W.isHeaders(e))for(const[t,r]of e.entries())o(r,t,n);else null!=e&&o(t,e,n);return this}get(e,t){if(e=Re(e)){const n=W.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}(e);if(W.isFunction(t))return t.call(this,e,n);if(W.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=Re(e)){const n=W.findKey(this,e);return!(!n||void 0===this[n]||t&&!Se(0,this[n],n,t))}return!1}delete(e,t){const n=this;let r=!1;function o(e){if(e=Re(e)){const o=W.findKey(n,e);!o||t&&!Se(0,n[o],o,t)||(delete n[o],r=!0)}}return W.isArray(e)?e.forEach(o):o(e),r}clear(e){const t=Object.keys(this);let n=t.length,r=!1;for(;n--;){const o=t[n];e&&!Se(0,this[o],o,e,!0)||(delete this[o],r=!0)}return r}normalize(e){const t=this,n={};return W.forEach(this,((r,o)=>{const s=W.findKey(n,o);if(s)return t[s]=Oe(r),void delete t[o];const i=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((e,t,n)=>t.toUpperCase()+n))}(o):String(o).trim();i!==o&&delete t[o],t[i]=Oe(r),n[i]=!0})),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return W.forEach(this,((n,r)=>{null!=n&&!1!==n&&(t[r]=e&&W.isArray(n)?n.join(", "):n)})),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([e,t])=>e+": "+t)).join("\n")}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach((e=>n.set(e))),n}static accessor(e){const t=(this[Ee]=this[Ee]={accessors:{}}).accessors,n=this.prototype;function r(e){const r=Re(e);t[r]||(function(e,t){const n=W.toCamelCase(" "+t);["get","set","has"].forEach((r=>{Object.defineProperty(e,r+n,{value:function(e,n,o){return this[r].call(this,t,e,n,o)},configurable:!0})}))}(n,e),t[r]=!0)}return W.isArray(e)?e.forEach(r):r(e),this}}Te.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),W.reduceDescriptors(Te.prototype,(({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}})),W.freezeMethods(Te);const Ae=Te;function ve(e,t){const n=this||ge,r=t||n,o=Ae.from(r.headers);let s=r.data;return W.forEach(e,(function(e){s=e.call(n,s,o.normalize(),t?t.status:void 0)})),o.normalize(),s}function je(e){return!(!e||!e.__CANCEL__)}function xe(e,t,n){X.call(this,null==e?"canceled":e,X.ERR_CANCELED,t,n),this.name="CanceledError"}W.inherits(xe,X,{__CANCEL__:!0});const Pe=xe;function Ce(e,t,n){const r=n.config.validateStatus;n.status&&r&&!r(n.status)?t(new X("Request failed with status code "+n.status,[X.ERR_BAD_REQUEST,X.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}const Ne=(e,t,n=3)=>{let r=0;const o=function(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o,s=0,i=0;return t=void 0!==t?t:1e3,function(a){const c=Date.now(),l=r[i];o||(o=c),n[s]=a,r[s]=c;let u=i,f=0;for(;u!==s;)f+=n[u++],u%=e;if(s=(s+1)%e,s===i&&(i=(i+1)%e),c-o<t)return;const d=l&&c-l;return d?Math.round(1e3*f/d):void 0}}(50,250);return function(e,t){let n,r,o=0,s=1e3/t;const i=(t,s=Date.now())=>{o=s,n=null,r&&(clearTimeout(r),r=null),e.apply(null,t)};return[(...e)=>{const t=Date.now(),a=t-o;a>=s?i(e,t):(n=e,r||(r=setTimeout((()=>{r=null,i(n)}),s-a)))},()=>n&&i(n)]}((n=>{const s=n.loaded,i=n.lengthComputable?n.total:void 0,a=s-r,c=o(a);r=s,e({loaded:s,total:i,progress:i?s/i:void 0,bytes:a,rate:c||void 0,estimated:c&&i&&s<=i?(i-s)/c:void 0,event:n,lengthComputable:null!=i,[t?"download":"upload"]:!0})}),n)},Ue=(e,t)=>{const n=null!=e;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},Le=e=>(...t)=>W.asap((()=>e(...t))),_e=me.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,me.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(me.origin),me.navigator&&/(msie|trident)/i.test(me.navigator.userAgent)):()=>!0,Fe=me.hasStandardBrowserEnv?{write(e,t,n,r,o,s){const i=[e+"="+encodeURIComponent(t)];W.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),W.isString(r)&&i.push("path="+r),W.isString(o)&&i.push("domain="+o),!0===s&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read:()=>null,remove(){}};function Be(e,t,n){let r=!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t);return e&&r||0==n?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}const De=e=>e instanceof Ae?{...e}:e;function ke(e,t){t=t||{};const n={};function r(e,t,n,r){return W.isPlainObject(e)&&W.isPlainObject(t)?W.merge.call({caseless:r},e,t):W.isPlainObject(t)?W.merge({},t):W.isArray(t)?t.slice():t}function o(e,t,n,o){return W.isUndefined(t)?W.isUndefined(e)?void 0:r(void 0,e,0,o):r(e,t,0,o)}function s(e,t){if(!W.isUndefined(t))return r(void 0,t)}function i(e,t){return W.isUndefined(t)?W.isUndefined(e)?void 0:r(void 0,e):r(void 0,t)}function a(n,o,s){return s in t?r(n,o):s in e?r(void 0,n):void 0}const c={url:s,method:s,data:s,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(e,t,n)=>o(De(e),De(t),0,!0)};return W.forEach(Object.keys(Object.assign({},e,t)),(function(r){const s=c[r]||o,i=s(e[r],t[r],r);W.isUndefined(i)&&s!==a||(n[r]=i)})),n}const qe=e=>{const t=ke({},e);let n,{data:r,withXSRFToken:o,xsrfHeaderName:s,xsrfCookieName:i,headers:a,auth:c}=t;if(t.headers=a=Ae.from(a),t.url=ie(Be(t.baseURL,t.url),e.params,e.paramsSerializer),c&&a.set("Authorization","Basic "+btoa((c.username||"")+":"+(c.password?unescape(encodeURIComponent(c.password)):""))),W.isFormData(r))if(me.hasStandardBrowserEnv||me.hasStandardBrowserWebWorkerEnv)a.setContentType(void 0);else if(!1!==(n=a.getContentType())){const[e,...t]=n?n.split(";").map((e=>e.trim())).filter(Boolean):[];a.setContentType([e||"multipart/form-data",...t].join("; "))}if(me.hasStandardBrowserEnv&&(o&&W.isFunction(o)&&(o=o(t)),o||!1!==o&&_e(t.url))){const e=s&&i&&Fe.read(i);e&&a.set(s,e)}return t},Me="undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,n){const r=qe(e);let o=r.data;const s=Ae.from(r.headers).normalize();let i,a,c,l,u,{responseType:f,onUploadProgress:d,onDownloadProgress:p}=r;function h(){l&&l(),u&&u(),r.cancelToken&&r.cancelToken.unsubscribe(i),r.signal&&r.signal.removeEventListener("abort",i)}let m=new XMLHttpRequest;function y(){if(!m)return;const r=Ae.from("getAllResponseHeaders"in m&&m.getAllResponseHeaders());Ce((function(e){t(e),h()}),(function(e){n(e),h()}),{data:f&&"text"!==f&&"json"!==f?m.response:m.responseText,status:m.status,statusText:m.statusText,headers:r,config:e,request:m}),m=null}m.open(r.method.toUpperCase(),r.url,!0),m.timeout=r.timeout,"onloadend"in m?m.onloadend=y:m.onreadystatechange=function(){m&&4===m.readyState&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))&&setTimeout(y)},m.onabort=function(){m&&(n(new X("Request aborted",X.ECONNABORTED,e,m)),m=null)},m.onerror=function(){n(new X("Network Error",X.ERR_NETWORK,e,m)),m=null},m.ontimeout=function(){let t=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const o=r.transitional||ce;r.timeoutErrorMessage&&(t=r.timeoutErrorMessage),n(new X(t,o.clarifyTimeoutError?X.ETIMEDOUT:X.ECONNABORTED,e,m)),m=null},void 0===o&&s.setContentType(null),"setRequestHeader"in m&&W.forEach(s.toJSON(),(function(e,t){m.setRequestHeader(t,e)})),W.isUndefined(r.withCredentials)||(m.withCredentials=!!r.withCredentials),f&&"json"!==f&&(m.responseType=r.responseType),p&&([c,u]=Ne(p,!0),m.addEventListener("progress",c)),d&&m.upload&&([a,l]=Ne(d),m.upload.addEventListener("progress",a),m.upload.addEventListener("loadend",l)),(r.cancelToken||r.signal)&&(i=t=>{m&&(n(!t||t.type?new Pe(null,e,m):t),m.abort(),m=null)},r.cancelToken&&r.cancelToken.subscribe(i),r.signal&&(r.signal.aborted?i():r.signal.addEventListener("abort",i)));const b=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(r.url);b&&-1===me.protocols.indexOf(b)?n(new X("Unsupported protocol "+b+":",X.ERR_BAD_REQUEST,e)):m.send(o||null)}))},Ie=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let n,r=new AbortController;const o=function(e){if(!n){n=!0,i();const t=e instanceof Error?e:this.reason;r.abort(t instanceof X?t:new Pe(t instanceof Error?t.message:t))}};let s=t&&setTimeout((()=>{s=null,o(new X(`timeout ${t} of ms exceeded`,X.ETIMEDOUT))}),t);const i=()=>{e&&(s&&clearTimeout(s),s=null,e.forEach((e=>{e.unsubscribe?e.unsubscribe(o):e.removeEventListener("abort",o)})),e=null)};e.forEach((e=>e.addEventListener("abort",o)));const{signal:a}=r;return a.unsubscribe=()=>W.asap(i),a}},ze=function*(e,t){let n=e.byteLength;if(!t||n<t)return void(yield e);let r,o=0;for(;o<n;)r=o+t,yield e.slice(o,r),o=r},Je=(e,t,n,r)=>{const o=async function*(e,t){for await(const n of async function*(e){if(e[Symbol.asyncIterator])return void(yield*e);const t=e.getReader();try{for(;;){const{done:e,value:n}=await t.read();if(e)break;yield n}}finally{await t.cancel()}}(e))yield*ze(n,t)}(e,t);let s,i=0,a=e=>{s||(s=!0,r&&r(e))};return new ReadableStream({async pull(e){try{const{done:t,value:r}=await o.next();if(t)return a(),void e.close();let s=r.byteLength;if(n){let e=i+=s;n(e)}e.enqueue(new Uint8Array(r))}catch(e){throw a(e),e}},cancel:e=>(a(e),o.return())},{highWaterMark:2})},He="function"==typeof fetch&&"function"==typeof Request&&"function"==typeof Response,We=He&&"function"==typeof ReadableStream,Ke=He&&("function"==typeof TextEncoder?(Ve=new TextEncoder,e=>Ve.encode(e)):async e=>new Uint8Array(await new Response(e).arrayBuffer()));var Ve;const $e=(e,...t)=>{try{return!!e(...t)}catch(e){return!1}},Xe=We&&$e((()=>{let e=!1;const t=new Request(me.origin,{body:new ReadableStream,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t})),Ge=We&&$e((()=>W.isReadableStream(new Response("").body))),Qe={stream:Ge&&(e=>e.body)};var Ze;He&&(Ze=new Response,["text","arrayBuffer","blob","formData","stream"].forEach((e=>{!Qe[e]&&(Qe[e]=W.isFunction(Ze[e])?t=>t[e]():(t,n)=>{throw new X(`Response type '${e}' is not supported`,X.ERR_NOT_SUPPORT,n)})})));const Ye={http:null,xhr:Me,fetch:He&&(async e=>{let{url:t,method:n,data:r,signal:o,cancelToken:s,timeout:i,onDownloadProgress:a,onUploadProgress:c,responseType:l,headers:u,withCredentials:f="same-origin",fetchOptions:d}=qe(e);l=l?(l+"").toLowerCase():"text";let p,h=Ie([o,s&&s.toAbortSignal()],i);const m=h&&h.unsubscribe&&(()=>{h.unsubscribe()});let y;try{if(c&&Xe&&"get"!==n&&"head"!==n&&0!==(y=await(async(e,t)=>{const n=W.toFiniteNumber(e.getContentLength());return null==n?(async e=>{if(null==e)return 0;if(W.isBlob(e))return e.size;if(W.isSpecCompliantForm(e)){const t=new Request(me.origin,{method:"POST",body:e});return(await t.arrayBuffer()).byteLength}return W.isArrayBufferView(e)||W.isArrayBuffer(e)?e.byteLength:(W.isURLSearchParams(e)&&(e+=""),W.isString(e)?(await Ke(e)).byteLength:void 0)})(t):n})(u,r))){let e,n=new Request(t,{method:"POST",body:r,duplex:"half"});if(W.isFormData(r)&&(e=n.headers.get("content-type"))&&u.setContentType(e),n.body){const[e,t]=Ue(y,Ne(Le(c)));r=Je(n.body,65536,e,t)}}W.isString(f)||(f=f?"include":"omit");const o="credentials"in Request.prototype;p=new Request(t,{...d,signal:h,method:n.toUpperCase(),headers:u.normalize().toJSON(),body:r,duplex:"half",credentials:o?f:void 0});let s=await fetch(p);const i=Ge&&("stream"===l||"response"===l);if(Ge&&(a||i&&m)){const e={};["status","statusText","headers"].forEach((t=>{e[t]=s[t]}));const t=W.toFiniteNumber(s.headers.get("content-length")),[n,r]=a&&Ue(t,Ne(Le(a),!0))||[];s=new Response(Je(s.body,65536,n,(()=>{r&&r(),m&&m()})),e)}l=l||"text";let b=await Qe[W.findKey(Qe,l)||"text"](s,e);return!i&&m&&m(),await new Promise(((t,n)=>{Ce(t,n,{data:b,headers:Ae.from(s.headers),status:s.status,statusText:s.statusText,config:e,request:p})}))}catch(t){if(m&&m(),t&&"TypeError"===t.name&&/fetch/i.test(t.message))throw Object.assign(new X("Network Error",X.ERR_NETWORK,e,p),{cause:t.cause||t});throw X.from(t,t&&t.code,e,p)}})};W.forEach(Ye,((e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));const et=e=>`- ${e}`,tt=e=>W.isFunction(e)||null===e||!1===e,nt={getAdapter:e=>{e=W.isArray(e)?e:[e];const{length:t}=e;let n,r;const o={};for(let s=0;s<t;s++){let t;if(n=e[s],r=n,!tt(n)&&(r=Ye[(t=String(n)).toLowerCase()],void 0===r))throw new X(`Unknown adapter '${t}'`);if(r)break;o[t||"#"+s]=r}if(!r){const e=Object.entries(o).map((([e,t])=>`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build")));let n=t?e.length>1?"since :\n"+e.map(et).join("\n"):" "+et(e[0]):"as no adapter specified";throw new X("There is no suitable adapter to dispatch the request "+n,"ERR_NOT_SUPPORT")}return r},adapters:Ye};function rt(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Pe(null,e)}function ot(e){return rt(e),e.headers=Ae.from(e.headers),e.data=ve.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),nt.getAdapter(e.adapter||ge.adapter)(e).then((function(t){return rt(e),t.data=ve.call(e,e.transformResponse,t),t.headers=Ae.from(t.headers),t}),(function(t){return je(t)||(rt(e),t&&t.response&&(t.response.data=ve.call(e,e.transformResponse,t.response),t.response.headers=Ae.from(t.response.headers))),Promise.reject(t)}))}const st={};["object","boolean","number","function","string","symbol"].forEach(((e,t)=>{st[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));const it={};st.transitional=function(e,t,n){function r(e,t){return"[Axios v1.8.1] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,o,s)=>{if(!1===e)throw new X(r(o," has been removed"+(t?" in "+t:"")),X.ERR_DEPRECATED);return t&&!it[o]&&(it[o]=!0,console.warn(r(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,o,s)}},st.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};const at={assertOptions:function(e,t,n){if("object"!=typeof e)throw new X("options must be an object",X.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let o=r.length;for(;o-- >0;){const s=r[o],i=t[s];if(i){const t=e[s],n=void 0===t||i(t,s,e);if(!0!==n)throw new X("option "+s+" must be "+n,X.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new X("Unknown option "+s,X.ERR_BAD_OPTION)}},validators:st},ct=at.validators;class lt{constructor(e){this.defaults=e,this.interceptors={request:new ae,response:new ae}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=new Error;const n=t.stack?t.stack.replace(/^.+\n/,""):"";try{e.stack?n&&!String(e.stack).endsWith(n.replace(/^.+\n.+\n/,""))&&(e.stack+="\n"+n):e.stack=n}catch(e){}}throw e}}_request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=ke(this.defaults,t);const{transitional:n,paramsSerializer:r,headers:o}=t;void 0!==n&&at.assertOptions(n,{silentJSONParsing:ct.transitional(ct.boolean),forcedJSONParsing:ct.transitional(ct.boolean),clarifyTimeoutError:ct.transitional(ct.boolean)},!1),null!=r&&(W.isFunction(r)?t.paramsSerializer={serialize:r}:at.assertOptions(r,{encode:ct.function,serialize:ct.function},!0)),void 0!==t.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),at.assertOptions(t,{baseUrl:ct.spelling("baseURL"),withXsrfToken:ct.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let s=o&&W.merge(o.common,o[t.method]);o&&W.forEach(["delete","get","head","post","put","patch","common"],(e=>{delete o[e]})),t.headers=Ae.concat(s,o);const i=[];let a=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(a=a&&e.synchronous,i.unshift(e.fulfilled,e.rejected))}));const c=[];let l;this.interceptors.response.forEach((function(e){c.push(e.fulfilled,e.rejected)}));let u,f=0;if(!a){const e=[ot.bind(this),void 0];for(e.unshift.apply(e,i),e.push.apply(e,c),u=e.length,l=Promise.resolve(t);f<u;)l=l.then(e[f++],e[f++]);return l}u=i.length;let d=t;for(f=0;f<u;){const e=i[f++],t=i[f++];try{d=e(d)}catch(e){t.call(this,e);break}}try{l=ot.call(this,d)}catch(e){return Promise.reject(e)}for(f=0,u=c.length;f<u;)l=l.then(c[f++],c[f++]);return l}getUri(e){return ie(Be((e=ke(this.defaults,e)).baseURL,e.url,e.allowAbsoluteUrls),e.params,e.paramsSerializer)}}W.forEach(["delete","get","head","options"],(function(e){lt.prototype[e]=function(t,n){return this.request(ke(n||{},{method:e,url:t,data:(n||{}).data}))}})),W.forEach(["post","put","patch"],(function(e){function t(t){return function(n,r,o){return this.request(ke(o||{},{method:e,headers:t?{"Content-Type":"multipart/form-data"}:{},url:n,data:r}))}}lt.prototype[e]=t(),lt.prototype[e+"Form"]=t(!0)}));const ut=lt;class ft{constructor(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");let t;this.promise=new Promise((function(e){t=e}));const n=this;this.promise.then((e=>{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null})),this.promise.then=e=>{let t;const r=new Promise((e=>{n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e((function(e,r,o){n.reason||(n.reason=new Pe(e,r,o),t(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}toAbortSignal(){const e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let e;return{token:new ft((function(t){e=t})),cancel:e}}}const dt=ft,pt={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(pt).forEach((([e,t])=>{pt[t]=e}));const ht=pt,mt=function e(t){const n=new ut(t),r=o(ut.prototype.request,n);return W.extend(r,ut.prototype,n,{allOwnKeys:!0}),W.extend(r,n,null,{allOwnKeys:!0}),r.create=function(n){return e(ke(t,n))},r}(ge);mt.Axios=ut,mt.CanceledError=Pe,mt.CancelToken=dt,mt.isCancel=je,mt.VERSION="1.8.1",mt.toFormData=ee,mt.AxiosError=X,mt.Cancel=mt.CanceledError,mt.all=function(e){return Promise.all(e)},mt.spread=function(e){return function(t){return e.apply(null,t)}},mt.isAxiosError=function(e){return W.isObject(e)&&!0===e.isAxiosError},mt.mergeConfig=ke,mt.AxiosHeaders=Ae,mt.formToJSON=e=>ye(W.isHTMLForm(e)?new FormData(e):e),mt.getAdapter=nt.getAdapter,mt.HttpStatusCode=ht,mt.default=mt;const yt=mt,bt=yt.create({baseURL:"https://www.canada.ca",timeout:3e4,maxRedirects:0});bt.interceptors.request.use((e=>(e.url=r(e.url),e.url.pathname=e.url.pathname+".sitemap.xml",e.url.searchParams.set("_",Date.now()),e)),(e=>Promise.reject(e))),bt.interceptors.response.use((e=>(e.data=gt(e.data),e)),(e=>Promise.reject(e)));const gt=e=>[...e.matchAll(/<url>.*?<loc>([^<]+)<\/loc>.*?(?:<lastmod>([^<]+)<\/lastmod>)?.*?<\/url>/g)].map((e=>({loc:r(e[1]).pathname,lastmod:e[2]??null}))),wt=bt,Et=yt.create({baseURL:"https://www.canada.ca",timeout:5e3,maxRedirects:0});Et.interceptors.request.use((e=>(e.url=r(e.url),e.url.pathname=e.url.pathname+".html",e.url.searchParams.set("_",Date.now()),e)),(e=>Promise.reject(e)));const Rt=Et,Ot=yt.create({baseURL:"https://www.canada.ca",timeout:5e3,maxRedirects:0});Ot.interceptors.request.use((e=>(e.url=r(e.url),e.url.pathname=e.url.pathname+"/_jcr_content.json",e.url.searchParams.set("_",Date.now()),e)),(e=>Promise.reject(e))),Ot.interceptors.response.use((e=>(e.data=At(e.data),e)),(e=>Promise.reject(e)));const St={Jan:"01",Feb:"02",Mar:"03",Apr:"04",May:"05",Jun:"06",Jul:"07",Aug:"08",Sep:"09",Oct:"10",Nov:"11",Dec:"12"};function Tt(e){if(/^\d{4}-\d{2}-\d{2}$/.test(e))return new Date(e).toISOString();let t=/^\w{3} (\w{3}) (\d{2}) (\d{4}) ([\d:]{8}) GMT([\-+]\d{4})$/.exec(e);return t?new Date(t[3]+"-"+St[t[1]]+"-"+t[2]+"T"+t[4]+t[5]).toISOString():e}const At=e=>{for(const[t,n]of Object.entries(e))"true"===n?e[t]=!0:"false"===n?e[t]=!1:t.endsWith("@TypeHint")?delete e[t]:"string"==typeof n?e[t]=Tt(e[t].trim()):Array.isArray(n)&&0===n.length&&delete e[t];return Object.keys(e).sort().reduce(((t,n)=>(t[n]=e[n],t)),{})},vt={normalize:r,children:wt,content:Rt,meta:Ot};return t})()));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canada-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Cross platform API to fetch data from canada.ca",
|
|
5
5
|
"browser": "dist/ca.js",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -27,9 +27,6 @@
|
|
|
27
27
|
"webpack-cli": "^4.9.2"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"
|
|
31
|
-
},
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">= 18.0.0"
|
|
30
|
+
"axios": "^1.11.0"
|
|
34
31
|
}
|
|
35
|
-
}
|
|
32
|
+
}
|
package/src/children.mjs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import normalize from "./normalize.mjs";
|
|
3
|
+
|
|
4
|
+
// Create a new axios instance
|
|
5
|
+
const children = axios.create({
|
|
6
|
+
baseURL: "https://www.canada.ca",
|
|
7
|
+
timeout: 30000,
|
|
8
|
+
maxRedirects: 0
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Transform URL
|
|
12
|
+
children.interceptors.request.use(config => {
|
|
13
|
+
config.url = normalize(config.url);
|
|
14
|
+
|
|
15
|
+
config.url.pathname = config.url.pathname + '.sitemap.xml';
|
|
16
|
+
config.url.searchParams.set('_', Date.now());
|
|
17
|
+
|
|
18
|
+
return config;
|
|
19
|
+
}, error => {
|
|
20
|
+
return Promise.reject(error);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Process response data
|
|
24
|
+
children.interceptors.response.use(response => {
|
|
25
|
+
response.data = parseSitemap(response.data);
|
|
26
|
+
|
|
27
|
+
return response;
|
|
28
|
+
}, error => {
|
|
29
|
+
return Promise.reject(error);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Sitemap parser
|
|
34
|
+
* @param {string} data
|
|
35
|
+
* @returns {Array<{path: string, lastmod: string}>}
|
|
36
|
+
*/
|
|
37
|
+
export const parseSitemap = (data) => {
|
|
38
|
+
const regex = /<url>.*?<loc>([^<]+)<\/loc>.*?(?:<lastmod>([^<]+)<\/lastmod>)?.*?<\/url>/g;
|
|
39
|
+
|
|
40
|
+
return [...data.matchAll(regex)].map(match => ({
|
|
41
|
+
loc: normalize(match[1]).pathname,
|
|
42
|
+
lastmod: match[2] ?? null
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default children;
|
package/src/content.mjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import normalize from "./normalize.mjs";
|
|
3
|
+
|
|
4
|
+
// Create a new axios instance
|
|
5
|
+
const content = axios.create({
|
|
6
|
+
baseURL: "https://www.canada.ca",
|
|
7
|
+
timeout: 5000,
|
|
8
|
+
maxRedirects: 0
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Transform URL
|
|
12
|
+
content.interceptors.request.use(config => {
|
|
13
|
+
config.url = normalize(config.url);
|
|
14
|
+
|
|
15
|
+
config.url.pathname = config.url.pathname + '.html';
|
|
16
|
+
config.url.searchParams.set('_', Date.now());
|
|
17
|
+
|
|
18
|
+
return config;
|
|
19
|
+
}, error => {
|
|
20
|
+
return Promise.reject(error);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export default content;
|
package/src/index.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import normalize from "./normalize.mjs";
|
|
2
|
+
import request from "./request.mjs";
|
|
3
|
+
import children from "./children.mjs";
|
|
4
|
+
import content from "./content.mjs";
|
|
5
|
+
import meta from "./meta.mjs";
|
|
6
|
+
|
|
7
|
+
const ca = {
|
|
8
|
+
normalize,
|
|
9
|
+
request,
|
|
10
|
+
children,
|
|
11
|
+
content,
|
|
12
|
+
meta
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default ca
|
package/src/meta.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import normalize from "./normalize.mjs";
|
|
3
|
+
|
|
4
|
+
// Create a new axios instance
|
|
5
|
+
const meta = axios.create({
|
|
6
|
+
baseURL: "https://www.canada.ca",
|
|
7
|
+
timeout: 5000,
|
|
8
|
+
maxRedirects: 0
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Transform URL
|
|
12
|
+
meta.interceptors.request.use(config => {
|
|
13
|
+
config.url = normalize(config.url);
|
|
14
|
+
|
|
15
|
+
config.url.pathname = config.url.pathname + '/_jcr_content.json';
|
|
16
|
+
config.url.searchParams.set('_', Date.now());
|
|
17
|
+
|
|
18
|
+
return config;
|
|
19
|
+
}, error => {
|
|
20
|
+
return Promise.reject(error);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Process response data
|
|
24
|
+
meta.interceptors.response.use(response => {
|
|
25
|
+
response.data = formatMeta(response.data);
|
|
26
|
+
|
|
27
|
+
return response;
|
|
28
|
+
}, error => {
|
|
29
|
+
return Promise.reject(error);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Map month name to number
|
|
34
|
+
* @const {object}
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
const months = {
|
|
38
|
+
'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
|
|
39
|
+
'Jul': '07', 'Aug': '08', 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Try to format dates
|
|
44
|
+
* @param {string} text
|
|
45
|
+
* @returns {string}
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
function formatDate(text) {
|
|
49
|
+
// Simple
|
|
50
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(text)) {
|
|
51
|
+
return new Date(text).toISOString()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// RFC1123
|
|
55
|
+
let m = /^\w{3} (\w{3}) (\d{2}) (\d{4}) ([\d:]{8}) GMT([\-+]\d{4})$/.exec(text)
|
|
56
|
+
if (m) {
|
|
57
|
+
return new Date(m[3] + '-' + months[m[1]] + '-' + m[2] + 'T' + m[4] + m[5]).toISOString()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return text
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const formatMeta = (data) => {
|
|
64
|
+
// Format some properties for consistency
|
|
65
|
+
for (const [key, value] of Object.entries(data)) {
|
|
66
|
+
if (value === 'true') {
|
|
67
|
+
data[key] = true
|
|
68
|
+
} else if (value === 'false') {
|
|
69
|
+
data[key] = false
|
|
70
|
+
} else if (key.endsWith('@TypeHint')) {
|
|
71
|
+
delete data[key]
|
|
72
|
+
} else if (typeof value === 'string') {
|
|
73
|
+
data[key] = formatDate(data[key].trim())
|
|
74
|
+
} else if (Array.isArray(value) && value.length === 0) {
|
|
75
|
+
delete data[key]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Sort object keys alphabetically for readability
|
|
80
|
+
return Object.keys(data).sort().reduce((obj, key) => {
|
|
81
|
+
obj[key] = data[key]
|
|
82
|
+
return obj
|
|
83
|
+
}, {})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default meta;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Normalize AEM path
|
|
4
|
+
* @param {string|URL} url
|
|
5
|
+
* @returns {URL}
|
|
6
|
+
*/
|
|
7
|
+
const normalize = (url) => {
|
|
8
|
+
|
|
9
|
+
if (typeof url === 'string') {
|
|
10
|
+
url = new URL(url, 'https://www.canada.ca/')
|
|
11
|
+
} else if (!(url instanceof URL)) {
|
|
12
|
+
throw new TypeError('string or URL object expected')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Verify domain
|
|
16
|
+
if (url.origin !== 'https://www.canada.ca') {
|
|
17
|
+
throw new Error('URL must start with ' + baseURL)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
url.pathname = url.pathname.replace(/^\/content\/canadasite/, '');
|
|
21
|
+
|
|
22
|
+
// Verify root
|
|
23
|
+
if (!url.pathname.startsWith('/en/') && !url.pathname.startsWith('/fr/')) {
|
|
24
|
+
throw new Error('Invalid path')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Strip extension and trailing slashes
|
|
28
|
+
url.pathname = url.pathname.replace(/(\.[^/]+|\/+)$/, '')
|
|
29
|
+
|
|
30
|
+
return url
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default normalize;
|
package/src/request.mjs
ADDED
package/webpack.config.js
CHANGED
|
@@ -2,7 +2,7 @@ const path = require('path');
|
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
mode: 'production',
|
|
5
|
-
entry: './src/index.
|
|
5
|
+
entry: './src/index.mjs',
|
|
6
6
|
output: {
|
|
7
7
|
path: path.resolve(__dirname, './dist/'),
|
|
8
8
|
filename: 'ca.js',
|
|
@@ -14,4 +14,5 @@ module.exports = {
|
|
|
14
14
|
globalObject: 'typeof self !== \'undefined\' ? self : this',
|
|
15
15
|
clean: true
|
|
16
16
|
},
|
|
17
|
+
devtool: false
|
|
17
18
|
}
|
package/SECURITY.md
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
([Français](#sécurité))
|
|
2
|
-
|
|
3
|
-
# Security
|
|
4
|
-
|
|
5
|
-
**Do not post any security issues on the public repository!** Security vulnerabilities must be reported by email to
|
|
6
|
-
|
|
7
|
-
[DND.WebPosting-PublicationWeb.MDN\@forces.gc.ca](mailto:DND.WebPosting-PublicationWeb.MDN@forces.gc.ca?subject=GitHub%20SECURITY)
|
|
8
|
-
______________________
|
|
9
|
-
|
|
10
|
-
## Sécurité
|
|
11
|
-
|
|
12
|
-
**Ne publiez aucun problème de sécurité sur le dépôt publique!** Les vulnérabilités de sécurité doivent être signalées par courriel à
|
|
13
|
-
|
|
14
|
-
[DND.WebPosting-PublicationWeb.MDN\@forces.gc.ca](mailto:DND.WebPosting-PublicationWeb.MDN@forces.gc.ca?subject=GitHub%20SÉCURITÉ)
|
package/src/basic/children.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
const normalize = require('../core/normalize.js')
|
|
2
|
-
const request = require('../core/request.js')
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Get list of child nodes from sitemap
|
|
6
|
-
* @param {string} url node url
|
|
7
|
-
* @returns {Promise<Array>}
|
|
8
|
-
*/
|
|
9
|
-
const children = async url => {
|
|
10
|
-
url = normalize(url, 'children')
|
|
11
|
-
|
|
12
|
-
let response = await request(url)
|
|
13
|
-
|
|
14
|
-
// Parse XML sitemap
|
|
15
|
-
let children = response.data.match(/<url>.*?<\/url>/g).map(url => {
|
|
16
|
-
let loc = url.match(/<loc>([^<]+)<\/loc>/)
|
|
17
|
-
let mod = url.match(/<lastmod>([^<]+)<\/lastmod>/)
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
path: normalize(loc[1]).pathname,
|
|
21
|
-
lastmod: mod ? new Date(mod[1]).toISOString() : null
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
// First entry may be the parent
|
|
26
|
-
if (children.length && children[0].path === normalize(url).pathname) {
|
|
27
|
-
children.shift()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
response.data = children
|
|
31
|
-
return response
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Default export
|
|
35
|
-
module.exports = exports = children
|
package/src/basic/content.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
const normalize = require('../core/normalize.js')
|
|
2
|
-
const request = require('../core/request.js')
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Get node content
|
|
6
|
-
* @param {string} url node URL
|
|
7
|
-
* @returns {Promise<any>}
|
|
8
|
-
*/
|
|
9
|
-
const content = async url => {
|
|
10
|
-
url = normalize(url, 'content')
|
|
11
|
-
return request(url)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Default export
|
|
15
|
-
module.exports = exports = content
|
package/src/basic/meta.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
const normalize = require('../core/normalize.js')
|
|
2
|
-
const request = require('../core/request.js')
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Get node metadata from jcr content
|
|
6
|
-
* @param {string} url node path
|
|
7
|
-
* @returns {Promise<Object>}
|
|
8
|
-
*/
|
|
9
|
-
const meta = async url => {
|
|
10
|
-
url = normalize(url, 'meta')
|
|
11
|
-
|
|
12
|
-
let response = await request(url)
|
|
13
|
-
let json = response.data
|
|
14
|
-
|
|
15
|
-
// Format some properties for consistency
|
|
16
|
-
for (const [key, value] of Object.entries(json)) {
|
|
17
|
-
if (value === 'true') {
|
|
18
|
-
json[key] = true
|
|
19
|
-
} else if (value === 'false') {
|
|
20
|
-
json[key] = false
|
|
21
|
-
} else if (key.endsWith('@TypeHint')) {
|
|
22
|
-
delete json[key]
|
|
23
|
-
} else if (typeof value === 'string') {
|
|
24
|
-
json[key] = maybeParseDate(json[key].trim())
|
|
25
|
-
} else if (Array.isArray(value) && value.length === 0) {
|
|
26
|
-
delete json[key]
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Sort object keys alphabetically for readability
|
|
31
|
-
response.data = Object.keys(response.data).sort().reduce((obj, key) => {
|
|
32
|
-
obj[key] = json[key]
|
|
33
|
-
return obj
|
|
34
|
-
}, {})
|
|
35
|
-
|
|
36
|
-
return response
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Map month name to number
|
|
41
|
-
* @const {object}
|
|
42
|
-
* @private
|
|
43
|
-
*/
|
|
44
|
-
const months = {
|
|
45
|
-
'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
|
|
46
|
-
'Jul': '07', 'Aug': '08', 'Sep': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Try to parse a date
|
|
51
|
-
* @param {string} date
|
|
52
|
-
* @returns {number|string}
|
|
53
|
-
* @private
|
|
54
|
-
*/
|
|
55
|
-
function maybeParseDate(date) {
|
|
56
|
-
// Simple
|
|
57
|
-
if (/^\d{4}-\d{2}-\d{2}$/.test(date)) {
|
|
58
|
-
return new Date(date).toISOString()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// RFC1123
|
|
62
|
-
let m = /^\w{3} (\w{3}) (\d{2}) (\d{4}) ([\d:]{8}) GMT([\-+]\d{4})$/.exec(date)
|
|
63
|
-
if (m) {
|
|
64
|
-
return new Date(m[3] + '-' + months[m[1]] + '-' + m[2] + 'T' + m[4] + m[5]).toISOString()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return date
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Default export
|
|
71
|
-
module.exports = exports = meta
|
package/src/core/normalize.js
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* Base URL
|
|
4
|
-
* @const {string}
|
|
5
|
-
* @private
|
|
6
|
-
*/
|
|
7
|
-
const baseURL = 'https://www.canada.ca/'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Normalize AEM URL
|
|
11
|
-
* @param {string|URL} url
|
|
12
|
-
* @param {string} [type=path]
|
|
13
|
-
* @returns {string}
|
|
14
|
-
*/
|
|
15
|
-
const normalize = (url, type = 'path') => {
|
|
16
|
-
|
|
17
|
-
if (typeof url === 'string') {
|
|
18
|
-
url = new URL(url, baseURL)
|
|
19
|
-
} else if (!(url instanceof URL)) {
|
|
20
|
-
throw new TypeError('string or URL object expected')
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Force https
|
|
24
|
-
url.protocol = 'https'
|
|
25
|
-
|
|
26
|
-
// Verify domain
|
|
27
|
-
if (!url.href.startsWith(baseURL)) {
|
|
28
|
-
throw new Error('URL must start with ' + baseURL)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
let isAsset = url.pathname.startsWith('/content/dam')
|
|
32
|
-
|
|
33
|
-
// Strip canadasite prefix
|
|
34
|
-
if (!isAsset) {
|
|
35
|
-
url.pathname = url.pathname.replace(/^\/content\/canadasite\//, '')
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Verify root
|
|
39
|
-
if (!/^\/(en|fr|content\/dam)(\/|\.|$)/.test(url.pathname)) {
|
|
40
|
-
throw new Error('Invalid root')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Strip Trailing slashes
|
|
44
|
-
url.pathname = url.pathname.replace(/\/+$/, '')
|
|
45
|
-
|
|
46
|
-
// Handle other URL types
|
|
47
|
-
if (url.pathname.includes('/_jcr_content/par')) {
|
|
48
|
-
return normalizeReference(url, type)
|
|
49
|
-
} else if (isAsset) {
|
|
50
|
-
return normalizeAsset(url, type)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return normalizePage(url, type)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Normalize AEM page
|
|
58
|
-
* @param {URL} url
|
|
59
|
-
* @param {string} type
|
|
60
|
-
* @returns {URL}
|
|
61
|
-
* @private
|
|
62
|
-
*/
|
|
63
|
-
function normalizePage(url, type) {
|
|
64
|
-
// Remove existing extension
|
|
65
|
-
url.pathname = url.pathname.replace(/\/?\.(sitemap\.xml|[^/.]+)$/, '')
|
|
66
|
-
|
|
67
|
-
if (type === 'meta') {
|
|
68
|
-
url.pathname += '/_jcr_content.json'
|
|
69
|
-
} else if (type === 'children') {
|
|
70
|
-
url.pathname += '.sitemap.xml'
|
|
71
|
-
} else if (type === 'content') {
|
|
72
|
-
url.pathname += '.html'
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return url
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Normalize AEM asset
|
|
80
|
-
* @param {URL} url
|
|
81
|
-
* @param {string} type
|
|
82
|
-
* @returns {URL}
|
|
83
|
-
* @private
|
|
84
|
-
*/
|
|
85
|
-
function normalizeAsset(url, type) {
|
|
86
|
-
let isDir = /(\/|\/\w+)$/.test(url.pathname)
|
|
87
|
-
|
|
88
|
-
if (type === 'meta') {
|
|
89
|
-
url.pathname += isDir ? '.json' : '/_jcr_content.json'
|
|
90
|
-
} else if (type === 'children') {
|
|
91
|
-
throw new Error('Cant load children of an asset node')
|
|
92
|
-
} else if (type === 'content' && isDir) {
|
|
93
|
-
throw new Error('Cant load content of an asset node')
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return url
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Normalize AEM reference
|
|
101
|
-
* @param {URL} url
|
|
102
|
-
* @param {string} type
|
|
103
|
-
* @returns {URL}
|
|
104
|
-
* @private
|
|
105
|
-
*/
|
|
106
|
-
function normalizeReference(url, type) {
|
|
107
|
-
|
|
108
|
-
if (type === 'path') {
|
|
109
|
-
throw new Error('Cant determine path of a reference node directly')
|
|
110
|
-
} else if (type === 'meta') {
|
|
111
|
-
url.pathname = url.pathname.replace(/\/image\.img\.\w+\//, '/image.json/')
|
|
112
|
-
} else if (type === 'children') {
|
|
113
|
-
throw new Error('Cant load children of a reference node')
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return url
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Default export
|
|
120
|
-
module.exports = exports = normalize
|
|
121
|
-
|
|
122
|
-
// Expose the baseURL
|
|
123
|
-
exports.baseURL = baseURL
|
package/src/core/request.js
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
const normalize = require('./normalize')
|
|
2
|
-
const Bottleneck = require('bottleneck/light.js')
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Default limiter options
|
|
6
|
-
* @see https://stackleap.io/js/bottleneck#user-content-constructor
|
|
7
|
-
* @const {object}
|
|
8
|
-
* @private
|
|
9
|
-
*/
|
|
10
|
-
const limiterOptions = {
|
|
11
|
-
reservoir: 150,
|
|
12
|
-
reservoirRefreshAmount: 150,
|
|
13
|
-
reservoirRefreshInterval: 5000,
|
|
14
|
-
maxConcurrent: 10,
|
|
15
|
-
trackDoneStatus: true
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Rate limiter
|
|
20
|
-
* @const {Bottleneck}
|
|
21
|
-
*/
|
|
22
|
-
let limiter = new Bottleneck(limiterOptions)
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Passthrough to prevent running method on non window object
|
|
26
|
-
* @param {string|URL} url
|
|
27
|
-
* @private
|
|
28
|
-
*/
|
|
29
|
-
const fetchWrapped = url => fetch(url)
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Modified rate limited fetch
|
|
33
|
-
* @param {string|URL} url
|
|
34
|
-
* @param {object} [options] Fetch options
|
|
35
|
-
* @returns {Promise<Object>}
|
|
36
|
-
*/
|
|
37
|
-
async function request(url) {
|
|
38
|
-
|
|
39
|
-
// Handle relative URLs
|
|
40
|
-
if (typeof url === 'string') {
|
|
41
|
-
url = new URL(url, normalize.baseURL)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Set cache busting param
|
|
45
|
-
url.searchParams.set('_', Date.now())
|
|
46
|
-
|
|
47
|
-
let response = null
|
|
48
|
-
if (limiter) {
|
|
49
|
-
response = await limiter.schedule(fetchWrapped, url, {
|
|
50
|
-
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0' }
|
|
51
|
-
})
|
|
52
|
-
} else {
|
|
53
|
-
response = await fetch(url, {
|
|
54
|
-
headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0' }
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Verify response code
|
|
59
|
-
if (!response.ok) {
|
|
60
|
-
throw new Error(response.statusText)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Verify destination
|
|
64
|
-
if (!response.url.startsWith(normalize.baseURL)) {
|
|
65
|
-
throw new Error('Invalid destination URL')
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Determine if path changed
|
|
69
|
-
let redirected = normalize(url).pathname !== normalize(response.url).pathname
|
|
70
|
-
|
|
71
|
-
// Format result
|
|
72
|
-
return {
|
|
73
|
-
url: response.url,
|
|
74
|
-
redirected: redirected,
|
|
75
|
-
data: await responseData(response),
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Get data of the response by type
|
|
81
|
-
* @param {Response} response
|
|
82
|
-
* @returns {Promise<any>}
|
|
83
|
-
* @private
|
|
84
|
-
*/
|
|
85
|
-
async function responseData(response) {
|
|
86
|
-
const contentType = response.headers.get('content-type')
|
|
87
|
-
|
|
88
|
-
// Parse JSON
|
|
89
|
-
if (contentType.includes('application/json')) {
|
|
90
|
-
return response.json()
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return response.text()
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Exports
|
|
97
|
-
module.exports = exports = request
|
|
98
|
-
exports.limiter = limiter
|
package/src/index.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const request = require('./core/request.js')
|
|
2
|
-
const normalize = require('./core/normalize.js')
|
|
3
|
-
const children = require('./basic/children.js')
|
|
4
|
-
const content = require('./basic/content.js')
|
|
5
|
-
const meta = require('./basic/meta.js')
|
|
6
|
-
|
|
7
|
-
module.exports = exports = {
|
|
8
|
-
// Core
|
|
9
|
-
request,
|
|
10
|
-
normalize,
|
|
11
|
-
|
|
12
|
-
// Basic API
|
|
13
|
-
children,
|
|
14
|
-
content,
|
|
15
|
-
meta,
|
|
16
|
-
}
|