|
| 1 | +const { Endpoint } = require('./endpoint'); |
| 2 | + |
| 3 | +/** |
| 4 | + * @readonly |
| 5 | + * @enum {string} |
| 6 | + */ |
| 7 | +const SERVICE_NAME = { |
| 8 | + UC: 'uc', |
| 9 | + UP: 'up', |
| 10 | + IO: 'io', |
| 11 | + RS: 'rs', |
| 12 | + RSF: 'rsf', |
| 13 | + API: 'api', |
| 14 | + S3: 's3' |
| 15 | +}; |
| 16 | + |
| 17 | +// --- could split to files if migrate to typescript --- // |
| 18 | + |
| 19 | +/** |
| 20 | + * @typedef {SERVICE_NAME | string} ServiceKey |
| 21 | + */ |
| 22 | + |
| 23 | +/** |
| 24 | + * @param {Object} options |
| 25 | + * @param {string} [options.regionId] |
| 26 | + * @param {string} [options.s3RegionId] |
| 27 | + * @param {Object.<ServiceKey, Endpoint[]>} [options.services] |
| 28 | + * @param {number} [options.ttl] seconds. default 1 day. |
| 29 | + * @param {Date} [options.createTime] |
| 30 | + * @constructor |
| 31 | + */ |
| 32 | +function Region (options) { |
| 33 | + this.regionId = options.regionId; |
| 34 | + this.s3RegionId = options.s3RegionId || options.regionId; |
| 35 | + |
| 36 | + this.services = options.services || {}; |
| 37 | + // use Object.values when min version of Node.js update to ≥ v7.5.0 |
| 38 | + Object.keys(SERVICE_NAME).map(k => { |
| 39 | + const v = SERVICE_NAME[k]; |
| 40 | + if (!Array.isArray(this.services[v])) { |
| 41 | + this.services[v] = []; |
| 42 | + } |
| 43 | + }); |
| 44 | + |
| 45 | + this.ttl = options.ttl || 86400; |
| 46 | + this.createTime = options.createTime || new Date(); |
| 47 | +} |
| 48 | + |
| 49 | +/** |
| 50 | + * This is used to be compatible with Zone. |
| 51 | + * So this function will be removed after remove Zone. |
| 52 | + * NOTE: The Region instance obtained using this method |
| 53 | + * can only be used for the following services: up, io, rs, rsf, api. |
| 54 | + * Because the Zone not support other services. |
| 55 | + * @param {conf.Zone} zone |
| 56 | + * @param {Object} [options] |
| 57 | + * @param {string} [options.regionId] |
| 58 | + * @param {string} [options.s3RegionId] |
| 59 | + * @param {number} [options.ttl] |
| 60 | + * @param {boolean} [options.isPreferCdnHost] |
| 61 | + */ |
| 62 | +Region.fromZone = function (zone, options) { |
| 63 | + options = options || {}; |
| 64 | + options.ttl = options.ttl || -1; |
| 65 | + |
| 66 | + const upHosts = options.isPreferCdnHost |
| 67 | + ? zone.cdnUpHosts.concat(zone.srcUpHosts) |
| 68 | + : zone.srcUpHosts.concat(zone.cdnUpHosts); |
| 69 | + |
| 70 | + const services = { |
| 71 | + // use array destructure if migrate to typescript |
| 72 | + [SERVICE_NAME.UP]: upHosts.map( |
| 73 | + h => new Endpoint(h) |
| 74 | + ), |
| 75 | + [SERVICE_NAME.IO]: [ |
| 76 | + new Endpoint(zone.ioHost) |
| 77 | + ], |
| 78 | + [SERVICE_NAME.RS]: [ |
| 79 | + new Endpoint(zone.rsHost) |
| 80 | + ], |
| 81 | + [SERVICE_NAME.RSF]: [ |
| 82 | + new Endpoint(zone.rsfHost) |
| 83 | + ], |
| 84 | + [SERVICE_NAME.API]: [ |
| 85 | + new Endpoint(zone.apiHost) |
| 86 | + ] |
| 87 | + }; |
| 88 | + |
| 89 | + return new Region({ |
| 90 | + regionId: options.regionId, |
| 91 | + s3RegionId: options.s3RegionId || options.regionId, |
| 92 | + services: services, |
| 93 | + ttl: options.ttl |
| 94 | + }); |
| 95 | +}; |
| 96 | + |
| 97 | +/** |
| 98 | + * @param {string} regionId |
| 99 | + * @param {Object} [options] |
| 100 | + * @param {string} [options.s3RegionId] |
| 101 | + * @param {number} [options.ttl] |
| 102 | + * @param {Date} [options.createTime] |
| 103 | + * @param {Object.<ServiceKey, Endpoint[]>} [options.extendedServices] |
| 104 | + * @returns {Region} |
| 105 | + */ |
| 106 | +Region.fromRegionId = function (regionId, options) { |
| 107 | + options = options || {}; |
| 108 | + |
| 109 | + const s3RegionId = options.s3RegionId || regionId; |
| 110 | + const ttl = options.ttl; |
| 111 | + const createTime = options.createTime; |
| 112 | + |
| 113 | + const isZ0 = regionId === 'z0'; |
| 114 | + |
| 115 | + /** |
| 116 | + * @type {Object.<ServiceKey, Endpoint[]>} |
| 117 | + */ |
| 118 | + let services = { |
| 119 | + [SERVICE_NAME.UC]: [ |
| 120 | + new Endpoint('uc.qiniuapi.com') |
| 121 | + ], |
| 122 | + [SERVICE_NAME.UP]: isZ0 |
| 123 | + ? [ |
| 124 | + new Endpoint('upload.qiniup.com'), |
| 125 | + new Endpoint('up.qiniup.com'), |
| 126 | + new Endpoint('up.qbox.me') |
| 127 | + ] |
| 128 | + : [ |
| 129 | + new Endpoint('upload-' + regionId + '.qiniup.com'), |
| 130 | + new Endpoint('up-' + regionId + '.qiniup.com'), |
| 131 | + new Endpoint('up-' + regionId + '.qbox.me') |
| 132 | + ], |
| 133 | + [SERVICE_NAME.IO]: isZ0 |
| 134 | + ? [ |
| 135 | + new Endpoint('iovip.qiniuio.com'), |
| 136 | + new Endpoint('iovip.qbox.me') |
| 137 | + ] |
| 138 | + : [ |
| 139 | + new Endpoint('iovip-' + regionId + '.qiniuio.com'), |
| 140 | + new Endpoint('iovip-' + regionId + '.qbox.me') |
| 141 | + ], |
| 142 | + [SERVICE_NAME.RS]: [ |
| 143 | + new Endpoint('rs-' + regionId + '.qiniuapi.com'), |
| 144 | + new Endpoint('rs-' + regionId + '.qbox.me') |
| 145 | + ], |
| 146 | + [SERVICE_NAME.RSF]: [ |
| 147 | + new Endpoint('rsf-' + regionId + '.qiniuapi.com'), |
| 148 | + new Endpoint('rsf-' + regionId + '.qbox.me') |
| 149 | + ], |
| 150 | + [SERVICE_NAME.API]: [ |
| 151 | + new Endpoint('api-' + regionId + '.qiniuapi.com'), |
| 152 | + new Endpoint('api-' + regionId + '.qbox.me') |
| 153 | + ], |
| 154 | + [SERVICE_NAME.S3]: [ |
| 155 | + new Endpoint('s3.' + s3RegionId + '.qiniucs.com') |
| 156 | + ] |
| 157 | + }; |
| 158 | + |
| 159 | + services = Object.assign(services, options.extendedServices || {}); |
| 160 | + |
| 161 | + return new Region({ |
| 162 | + regionId: regionId, |
| 163 | + s3RegionId: s3RegionId, |
| 164 | + services: services, |
| 165 | + ttl: ttl, |
| 166 | + createTime: createTime |
| 167 | + }); |
| 168 | +}; |
| 169 | + |
| 170 | +Object.defineProperty(Region.prototype, 'isLive', { |
| 171 | + get: function () { |
| 172 | + if (this.ttl < 0) { |
| 173 | + return true; |
| 174 | + } |
| 175 | + // convert ms to s |
| 176 | + const liveTime = Math.round((Date.now() - this.createTime) / 1000); |
| 177 | + return liveTime < this.ttl; |
| 178 | + }, |
| 179 | + enumerable: false, |
| 180 | + configurable: true |
| 181 | +}); |
| 182 | + |
| 183 | +exports.SERVICE_NAME = SERVICE_NAME; |
| 184 | +exports.Region = Region; |
0 commit comments