Compare commits
40 Commits
Author | SHA1 | Date |
---|---|---|
|
8a5568de77 | |
|
57cd21060b | |
|
7fa34ff6a6 | |
|
22c0e57947 | |
|
cdea9a26b1 | |
|
50ac48e026 | |
|
3c6840bdd7 | |
|
4c9af68899 | |
|
cc6667c5b1 | |
|
d6ee163a36 | |
|
41e3965870 | |
|
a3feb781a7 | |
|
910f7e4bfe | |
|
7f1870778e | |
|
d044e6cef4 | |
|
005134d725 | |
|
e3cb1d5955 | |
|
6df7ece0a8 | |
|
27a8fa7651 | |
|
a3f33bd901 | |
|
194629a25b | |
|
34055b4117 | |
|
9ae37cef32 | |
|
a9a7fe64d8 | |
|
3940268149 | |
|
2b703c0621 | |
|
01affdbb51 | |
|
643dd12ab8 | |
|
c9f5808675 | |
|
3e9670d9cf | |
|
d5e2dd8ae0 | |
|
61a415ec6f | |
|
17ea984a61 | |
|
180dcf72fe | |
|
8c06bda57f | |
|
b219a870bd | |
|
e5c1359509 | |
|
744fc56f29 | |
|
1a63399df0 | |
|
f1bfe2d065 |
|
@ -177,6 +177,10 @@ Please let us know how can we help. Do check out [issues](https://github.com/nac
|
|||
|
||||
PR is welcome.
|
||||
|
||||
nacos-sdk-nodejs ding group : 44654232
|
||||

|
||||
|
||||
|
||||
## License
|
||||
|
||||
[Apache License V2](LICENSE)
|
||||
|
|
|
@ -3,8 +3,11 @@
|
|||
const NacosConfigClient = require('nacos').NacosConfigClient;
|
||||
|
||||
const configClient = new NacosConfigClient({
|
||||
serverAddr: '106.14.43.196:8848',
|
||||
serverAddr: 'aliyun.nacos.net:80',
|
||||
namespace: '',
|
||||
// 如果nacos开启了认证鉴权,需要在此处填写用户名密码
|
||||
// username: 'xxx',
|
||||
// password: 'xxx'
|
||||
});
|
||||
|
||||
function sleep(time){
|
||||
|
@ -18,7 +21,7 @@ function sleep(time){
|
|||
(async () => {
|
||||
await configClient.ready();
|
||||
|
||||
const dataId = 'nacos.test.1';
|
||||
const dataId = 'nacos.test.22';
|
||||
const group = 'DEFAULT_GROUP';
|
||||
const str = `example_test_${Math.random()}_${Date.now()}`;
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
"name": "nacos-example",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"nacos": "^1.0.0"
|
||||
"nacos": "^2.5.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
"ignoreChanges": [
|
||||
"*.md"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"conventionalCommits": true,
|
||||
"createRelease": "github"
|
||||
}
|
||||
},
|
||||
"version": "2.0.1"
|
||||
"version": "2.6.0"
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"ci": "npm run cov",
|
||||
"build": "lerna run build && cp ./README.md ./packages/nacos/README.md"
|
||||
},
|
||||
"license": "Apache",
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nacos-group/nacos-sdk-nodejs/issues"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "nacos-config",
|
||||
"version": "2.0.1",
|
||||
"version": "2.6.0",
|
||||
"description": "nacos config client",
|
||||
"keywords": [
|
||||
"nacos-config",
|
||||
|
|
|
@ -54,7 +54,8 @@ export class DataClient extends Base implements BaseClient {
|
|||
|
||||
this.snapshot = this.getSnapshot();
|
||||
this.serverMgr = this.getServerListManager();
|
||||
this.httpAgent = new HttpAgent({ configuration: this.configuration });
|
||||
const CustomHttpAgent = this.configuration.get(ClientOptionKeys.HTTP_AGENT);
|
||||
this.httpAgent = CustomHttpAgent ? new CustomHttpAgent({ configuration: this.configuration }) : new HttpAgent({ configuration: this.configuration });
|
||||
|
||||
this.configuration.merge({
|
||||
snapshot: this.snapshot,
|
||||
|
@ -162,7 +163,7 @@ export class DataClient extends Base implements BaseClient {
|
|||
async publishSingle(dataId, group, content, options) {
|
||||
checkParameters(dataId, group);
|
||||
const client = this.getClient(options);
|
||||
return await client.publishSingle(dataId, group, content);
|
||||
return await client.publishSingle(dataId, group, content, options && options.type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -217,6 +217,10 @@ export class ClientWorker extends Base implements IClientWorker {
|
|||
}
|
||||
|
||||
const postData = {};
|
||||
// 开启权限验证后需要携带租户,否则没有权限
|
||||
if (tenant) {
|
||||
Object.assign(postData, { tenant })
|
||||
}
|
||||
postData[ this.listenerDataKey ] = probeUpdate.join('');
|
||||
const content = await this.httpAgent.request(this.apiRoutePath.LISTENER, {
|
||||
method: 'POST',
|
||||
|
@ -345,9 +349,10 @@ export class ClientWorker extends Base implements IClientWorker {
|
|||
* @param {String} dataId - id of the data
|
||||
* @param {String} group - group name of the data
|
||||
* @param {String} content - config value
|
||||
* @param {String} type - type of the data
|
||||
* @return {Boolean} success
|
||||
*/
|
||||
async publishSingle(dataId, group, content) {
|
||||
async publishSingle(dataId, group, content, type) {
|
||||
await this.httpAgent.request(this.apiRoutePath.PUBLISH, {
|
||||
method: 'POST',
|
||||
encode: true,
|
||||
|
@ -356,6 +361,8 @@ export class ClientWorker extends Base implements IClientWorker {
|
|||
group,
|
||||
content,
|
||||
tenant: this.namespace,
|
||||
type,
|
||||
appName: this.appName
|
||||
},
|
||||
});
|
||||
return true;
|
||||
|
|
|
@ -19,6 +19,7 @@ import { ClientOptionKeys, IConfiguration, IServerListManager } from './interfac
|
|||
import * as urllib from 'urllib';
|
||||
import * as crypto from 'crypto';
|
||||
import { encodingParams, transformGBKToUTF8 } from './utils';
|
||||
import * as dns from 'dns';
|
||||
|
||||
export class HttpAgent {
|
||||
|
||||
|
@ -82,6 +83,22 @@ export class HttpAgent {
|
|||
return this.configuration.get(ClientOptionKeys.DEFAULT_ENCODING) || 'utf8';
|
||||
}
|
||||
|
||||
get identityKey() {
|
||||
return this.configuration.get(ClientOptionKeys.IDENTITY_KEY);
|
||||
}
|
||||
|
||||
get identityValue() {
|
||||
return this.configuration.get(ClientOptionKeys.IDENTITY_VALUE);
|
||||
}
|
||||
|
||||
get endpointQueryParams() {
|
||||
return this.configuration.get(ClientOptionKeys.ENDPOINT_QUERY_PARAMS)
|
||||
}
|
||||
|
||||
get decodeRes() {
|
||||
return this.configuration.get(ClientOptionKeys.DECODE_RES);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 请求
|
||||
|
@ -106,6 +123,11 @@ export class HttpAgent {
|
|||
const endTime = Date.now() + timeout;
|
||||
let lastErr;
|
||||
|
||||
if (this.options?.configuration?.innerConfig?.username &&
|
||||
this.options?.configuration?.innerConfig?.password) {
|
||||
data.username = this.options.configuration.innerConfig.username;
|
||||
data.password = this.options.configuration.innerConfig.password;
|
||||
}
|
||||
let signStr = data.tenant;
|
||||
if (data.group && data.tenant) {
|
||||
signStr = data.tenant + '+' + data.group;
|
||||
|
@ -125,6 +147,7 @@ export class HttpAgent {
|
|||
timeStamp: ts,
|
||||
exConfigInfo: 'true',
|
||||
'Spas-Signature': signature,
|
||||
...this.identityKey ? {[this.identityKey]: this.identityValue} : {}
|
||||
});
|
||||
|
||||
let requestData = data;
|
||||
|
@ -152,6 +175,9 @@ export class HttpAgent {
|
|||
this.debug('%s %s, got %s, body: %j', method, url, res.status, res.data);
|
||||
switch (res.status) {
|
||||
case HTTP_OK:
|
||||
if (this.decodeRes) {
|
||||
return this.decodeRes(res, method, this.defaultEncoding)
|
||||
}
|
||||
return this.decodeResData(res, method);
|
||||
case HTTP_NOT_FOUND:
|
||||
return null;
|
||||
|
@ -170,6 +196,9 @@ export class HttpAgent {
|
|||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code === dns.NOTFOUND) {
|
||||
throw err;
|
||||
}
|
||||
err.url = `${method} ${url}`;
|
||||
err.data = data;
|
||||
err.headers = headers;
|
||||
|
|
|
@ -24,6 +24,7 @@ export { DataClient } from './client';
|
|||
export { ClientWorker } from './client_worker';
|
||||
export { ServerListManager } from './server_list_mgr';
|
||||
export { Snapshot } from './snapshot';
|
||||
export { HttpAgent } from './http_agent'
|
||||
|
||||
const APIClientBase = require('cluster-client').APIClientBase;
|
||||
|
||||
|
|
|
@ -251,9 +251,10 @@ export interface ClientOptions {
|
|||
accessKey?: string; // 阿里云的 accessKey
|
||||
secretKey?: string; // 阿里云的 secretKey
|
||||
httpclient?: any; // http 请求客户端,默认为 urllib
|
||||
httpAgent?: any; // httpAgent
|
||||
appName?: string; // 应用名,可选
|
||||
ssl?: boolean; // 是否为 https 请求
|
||||
refreshInterval?: number; // 重新拉去地址列表的间隔时间
|
||||
refreshInterval?: number; // 重新拉取地址列表的间隔时间
|
||||
contextPath?: string; // 请求的 contextPath
|
||||
clusterName?: string; // 请求的 path
|
||||
requestTimeout?: number; // 请求超时时间
|
||||
|
@ -261,7 +262,13 @@ export interface ClientOptions {
|
|||
serverAddr?: string; // 用于直连,包含端口
|
||||
unit?: string; // 内部单元化用
|
||||
nameServerAddr?: string; // 老的兼容参数,逐步废弃,同 endpoint
|
||||
username?: string; // 认证的用户名
|
||||
password?: string; // 认证的密码
|
||||
cacheDir?: string; // 缓存文件的路径
|
||||
identityKey?: string; // Identity Key
|
||||
identityValue?: string; // Identity Value
|
||||
endpointQueryParams?: string; // endPoint 查询参数 e.g: param_1=1¶m_2=2
|
||||
decodeRes?: (res: any, method?: string, encoding?: string) => any
|
||||
}
|
||||
|
||||
export enum ClientOptionKeys {
|
||||
|
@ -285,6 +292,10 @@ export enum ClientOptionKeys {
|
|||
HTTP_AGENT = 'httpAgent',
|
||||
SERVER_MGR = 'serverMgr',
|
||||
DEFAULT_ENCODING = 'defaultEncoding',
|
||||
IDENTITY_KEY = 'identityKey',
|
||||
IDENTITY_VALUE = 'identityValue',
|
||||
DECODE_RES = 'decodeRes',
|
||||
ENDPOINT_QUERY_PARAMS = 'endpointQueryParams'
|
||||
}
|
||||
|
||||
export interface IConfiguration {
|
||||
|
|
|
@ -108,6 +108,10 @@ export class ServerListManager extends Base implements IServerListManager {
|
|||
return this.configuration.get(ClientOptionKeys.CLUSTER_NAME) || 'serverlist';
|
||||
}
|
||||
|
||||
get endpointQueryParams() {
|
||||
return this.configuration.get(ClientOptionKeys.ENDPOINT_QUERY_PARAMS)
|
||||
}
|
||||
|
||||
get requestTimeout(): number {
|
||||
return this.configuration.get(ClientOptionKeys.REQUEST_TIMEOUT);
|
||||
}
|
||||
|
@ -226,7 +230,8 @@ export class ServerListManager extends Base implements IServerListManager {
|
|||
|
||||
// 获取请求 url
|
||||
protected getRequestUrl(unit) {
|
||||
return `http://${this.nameServerAddr}/${this.contextPath}/${this.clusterName}`;
|
||||
const endpointQueryParams = !!this.endpointQueryParams ? `?${this.endpointQueryParams}` : '';
|
||||
return `http://${this.nameServerAddr}/${this.contextPath}/${this.clusterName}${endpointQueryParams}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
import { DataClient } from '../src/client';
|
||||
import { HttpAgent } from '../src/http_agent'
|
||||
|
||||
const mm = require('mm');
|
||||
const assert = require('assert');
|
||||
|
@ -117,4 +118,20 @@ describe('test/client.test.ts', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('support custom httpAgent', () => {
|
||||
class CustomHttpAgent {};
|
||||
assert(client.httpAgent instanceof HttpAgent);
|
||||
client = new DataClient({
|
||||
appName: 'test',
|
||||
endpoint: 'acm.aliyun.com',
|
||||
namespace: '81597370-5076-4216-9df5-538a2b55bac3',
|
||||
accessKey: '4c796a4dcd0d4f5895d4ba83a296b489',
|
||||
secretKey: 'UjLemP8inirhjMg1NZyY0faOk1E=',
|
||||
httpclient,
|
||||
httpAgent: CustomHttpAgent,
|
||||
ssl: false
|
||||
});
|
||||
assert(client.httpAgent instanceof CustomHttpAgent);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -497,5 +497,32 @@ describe('test/client_worker.test.ts', () => {
|
|||
assert(error && error.name === 'NacosServerConflictError');
|
||||
});
|
||||
});
|
||||
|
||||
describe('custom decode res data', () => {
|
||||
before(async () => {
|
||||
configuration.merge({ decodeRes(res) {
|
||||
if (/^\d+\.\d+\.\d+\.\d+\:\d+$/.test(res.data)) {
|
||||
return 'customDecode' + res.data
|
||||
}
|
||||
return res.data;
|
||||
}});
|
||||
client = getClient(configuration);
|
||||
await client.publishSingle('com.taobao.hsf.redis', 'DEFAULT_GROUP', '10.123.32.1:8080');
|
||||
await sleep(1000);
|
||||
await client.ready();
|
||||
});
|
||||
afterEach(mm.restore);
|
||||
|
||||
after(async () => {
|
||||
client.close();
|
||||
await client.remove('com.taobao.hsf.redis', 'DEFAULT_GROUP');
|
||||
await rimraf(cacheDir);
|
||||
});
|
||||
|
||||
it('should be handled by decodeRes', async () => {
|
||||
const content = await client.getConfig('com.taobao.hsf.redis', 'DEFAULT_GROUP');
|
||||
assert(/^customDecode\d+\.\d+\.\d+\.\d+\:\d+$/.test(content));
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
|
|
|
@ -18,14 +18,6 @@
|
|||
import { Configuration } from '../src/configuration';
|
||||
import { DEFAULT_OPTIONS } from '../src/const';
|
||||
|
||||
export function delay(timeout) {
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
export function createDefaultConfiguration(config: any) {
|
||||
return new Configuration(Object.assign({}, DEFAULT_OPTIONS)).merge(config);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Author: ugrg
|
||||
* Create Time: 2021/8/20 9:12
|
||||
*/
|
||||
interface Instance {
|
||||
instanceId: string,
|
||||
ip: string, //IP of instance
|
||||
port: number, //Port of instance
|
||||
healthy: boolean,
|
||||
enabled: boolean,
|
||||
serviceName?: string,
|
||||
weight?: number,
|
||||
ephemeral?: boolean,
|
||||
clusterName?: string
|
||||
}
|
||||
|
||||
export interface Host {
|
||||
instanceId: string;
|
||||
ip: string;
|
||||
port: number;
|
||||
weight: number;
|
||||
healthy: boolean;
|
||||
enabled: boolean;
|
||||
ephemeral: boolean;
|
||||
clusterName: string;
|
||||
serviceName: string;
|
||||
metadata: any;
|
||||
instanceHeartBeatInterval: number;
|
||||
instanceIdGenerator: string;
|
||||
instanceHeartBeatTimeOut: number;
|
||||
ipDeleteTimeout: number;
|
||||
}
|
||||
|
||||
type Hosts = Host[];
|
||||
|
||||
interface SubscribeInfo {
|
||||
serviceName: string,
|
||||
groupName?: string,
|
||||
clusters?: string
|
||||
}
|
||||
|
||||
interface NacosNamingClientConfig {
|
||||
logger: typeof console,
|
||||
serverList: string | string[],
|
||||
namespace?: string,
|
||||
username?: string,
|
||||
password?: string,
|
||||
endpoint?: string,
|
||||
vipSrvRefInterMillis?: number,
|
||||
ssl?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Nacos服务发现组件
|
||||
*/
|
||||
export class NacosNamingClient {
|
||||
constructor (config: NacosNamingClientConfig);
|
||||
|
||||
ready: () => Promise<void>;
|
||||
// Register an instance to service
|
||||
registerInstance: (
|
||||
serviceName: string, //Service name
|
||||
instance: Instance, //Instance
|
||||
groupName?: string // group name, default is DEFAULT_GROUP
|
||||
) => Promise<void>;
|
||||
// Delete instance from service.
|
||||
deregisterInstance: (
|
||||
serviceName: string, //Service name
|
||||
instance: Instance, //Instance
|
||||
groupName?: string // group name, default is DEFAULT_GROUP
|
||||
) => Promise<void>;
|
||||
// Query instance list of service.
|
||||
getAllInstances: (
|
||||
serviceName: string, //Service name
|
||||
groupName?: string, //group name, default is DEFAULT_GROUP
|
||||
clusters?: string, //Cluster names
|
||||
subscribe?: boolean //whether subscribe the service, default is true
|
||||
) => Promise<Hosts>;
|
||||
// Select instance list of service.
|
||||
selectInstances: (
|
||||
serviceName: string,
|
||||
groupName?: string,
|
||||
clusters?: string,
|
||||
healthy?: boolean,
|
||||
subscribe?: boolean
|
||||
) => Promise<Hosts>;
|
||||
// Get the status of nacos server, 'UP' or 'DOWN'.
|
||||
getServerStatus: () => 'UP' | 'DOWN';
|
||||
subscribe: (
|
||||
info: SubscribeInfo | string, //service info, if type is string, it's the serviceName
|
||||
listener: (host: Hosts) => void //the listener function
|
||||
) => void;
|
||||
unSubscribe: (
|
||||
info: SubscribeInfo | string, //service info, if type is string, it's the serviceName
|
||||
listener: (host: Hosts) => void //the listener function
|
||||
) => void;
|
||||
}
|
|
@ -50,3 +50,5 @@ exports.NAMING_DEFAULT_CLUSTER_NAME = 'DEFAULT';
|
|||
exports.SERVICE_INFO_SPLITER = '@@';
|
||||
|
||||
exports.DEFAULT_GROUP = 'DEFAULT_GROUP';
|
||||
|
||||
exports.DEFAULT_DELAY = 5000;
|
||||
|
|
|
@ -22,6 +22,7 @@ const Base = require('sdk-base');
|
|||
const Constants = require('../const');
|
||||
const ServiceInfo = require('./service_info');
|
||||
const PushReceiver = require('./push_receiver');
|
||||
const equals = require('equals');
|
||||
|
||||
class HostReactor extends Base {
|
||||
constructor(options = {}) {
|
||||
|
@ -92,7 +93,7 @@ class HostReactor extends Base {
|
|||
const key = host.ip + ':' + host.port;
|
||||
newHostMap.set(key, host);
|
||||
|
||||
if (oldHostMap.has(key) && JSON.stringify(host) !== JSON.stringify(oldHostMap.get(key))) {
|
||||
if (oldHostMap.has(key) && !equals(host, oldHostMap.get(key))) {
|
||||
modHosts.push(host);
|
||||
continue;
|
||||
}
|
||||
|
@ -133,7 +134,6 @@ class HostReactor extends Base {
|
|||
this.emit(`${serviceInfo.getKey()}_changed`, serviceInfo.hosts, serviceInfo);
|
||||
// TODO: 本地缓存
|
||||
}
|
||||
this.logger.info('[HostReactor] current ips(%d) service: %s -> %s', serviceInfo.ipCount, serviceInfo.name, JSON.stringify(serviceInfo.hosts));
|
||||
return serviceInfo;
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ class HostReactor extends Base {
|
|||
|
||||
if (this._futureMap.has(key)) {
|
||||
const serviceInfo = this._serviceInfoMap.get(key);
|
||||
let delay = 1000;
|
||||
let delay = Constants.DEFAULT_DELAY;
|
||||
if (serviceInfo) {
|
||||
delay = serviceInfo.cacheMillis;
|
||||
task.lastRefTime = serviceInfo.lastRefTime;
|
||||
|
|
|
@ -160,6 +160,10 @@ class NameProxy extends Base {
|
|||
}
|
||||
|
||||
const url = (this.options.ssl ? 'https://' : 'http://') + serverAddr + api;
|
||||
if (this.options.username && this.options.password) {
|
||||
params.username = this.options.username;
|
||||
params.password = this.options.password;
|
||||
}
|
||||
const result = await this.httpclient.request(url, {
|
||||
method,
|
||||
headers,
|
||||
|
@ -284,7 +288,7 @@ class NameProxy extends Base {
|
|||
err.message = `[CLIENT-BEAT] failed to send beat: ${JSON.stringify(beatInfo)}, caused by ${err.message}`;
|
||||
this.logger.error(err);
|
||||
}
|
||||
return 0;
|
||||
return Constants.DEFAULT_DELAY;
|
||||
}
|
||||
|
||||
async getServiceList(pageNo, pageSize, groupName) {
|
||||
|
|
|
@ -66,7 +66,7 @@ class PushReceiver extends Base {
|
|||
});
|
||||
this._server.on('message', (msg, rinfo) => this._handlePushMessage(msg, rinfo));
|
||||
// 随机绑定一个端口
|
||||
this._server.bind();
|
||||
this._server.bind({port: 0, exclusive: true}, null);
|
||||
}
|
||||
|
||||
_handlePushMessage(msg, rinfo) {
|
||||
|
@ -104,7 +104,13 @@ class PushReceiver extends Base {
|
|||
}
|
||||
|
||||
close() {
|
||||
this._isClosed = true;
|
||||
return new Promise((resolve) => {
|
||||
this._isClosed = true;
|
||||
if (this._server) {
|
||||
this._server.close(resolve)
|
||||
this._server = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const Constants = require('../const');
|
||||
const EMPTY = '';
|
||||
const SPLITER = '@@';
|
||||
// const ALL_IPS = '000--00-ALL_IPS--00--000';
|
||||
|
@ -27,7 +28,7 @@ class ServiceInfo {
|
|||
this.groupName = data.groupName;
|
||||
this.clusters = data.clusters;
|
||||
this.isAllIPs = data.allIPs || false;
|
||||
this.cacheMillis = data.cacheMillis || 1000;
|
||||
this.cacheMillis = data.cacheMillis || Constants.DEFAULT_DELAY;
|
||||
this.hosts = data.hosts;
|
||||
this.lastRefTime = data.lastRefTime || 0;
|
||||
this.checksum = data.checksum || '';
|
||||
|
@ -39,7 +40,12 @@ class ServiceInfo {
|
|||
}
|
||||
|
||||
get isValid() {
|
||||
return !!this.hosts;
|
||||
const valid = !!this.hosts;
|
||||
// 如果 this.hosts 是空数组要返回 false
|
||||
if (valid && Array.isArray(this.hosts)) {
|
||||
return this.hosts.length > 0;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
getKey() {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
{
|
||||
"name": "nacos-naming",
|
||||
"version": "2.0.1",
|
||||
"version": "2.6.0",
|
||||
"description": "nacos (https://nacos.io/en-us/) nodejs sdk",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"lib",
|
||||
"index.js"
|
||||
"index.js",
|
||||
"index.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"autod": "autod",
|
||||
|
@ -42,6 +43,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"address": "^1.1.0",
|
||||
"equals": "^1.0.5",
|
||||
"mz-modules": "^2.1.0",
|
||||
"sdk-base": "^3.6.0",
|
||||
"urllib": "^2.33.3",
|
||||
|
|
|
@ -177,6 +177,10 @@ Please let us know how can we help. Do check out [issues](https://github.com/nac
|
|||
|
||||
PR is welcome.
|
||||
|
||||
nacos-sdk-nodejs ding group : 44654232
|
||||

|
||||
|
||||
|
||||
## License
|
||||
|
||||
[Apache License V2](LICENSE)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "nacos",
|
||||
"version": "2.0.1",
|
||||
"version": "2.6.0",
|
||||
"description": "nacos client main package",
|
||||
"keywords": [
|
||||
"nacos",
|
||||
|
@ -12,8 +12,8 @@
|
|||
"main": "dist/index.js",
|
||||
"author": "czy88840616@gmail.com",
|
||||
"dependencies": {
|
||||
"nacos-config": "^2.0.1",
|
||||
"nacos-naming": "^2.0.1"
|
||||
"nacos-config": "^2.6.0",
|
||||
"nacos-naming": "^2.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.5",
|
||||
|
|
Loading…
Reference in New Issue