@openziti/ziti-sdk-nodejs 0.7.0 → 0.8.0

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/binding.gyp CHANGED
@@ -36,6 +36,7 @@
36
36
  "./src/Ziti_https_request_data.c",
37
37
  "./src/Ziti_https_request_end.c",
38
38
  "./src/ziti_init.c",
39
+ "./src/ziti_listen.c",
39
40
  "./src/ziti_service_available.c",
40
41
  "./src/ziti_shutdown.c",
41
42
  "./src/ziti_write.c",
@@ -105,18 +106,19 @@
105
106
  "GCC_ENABLE_PASCAL_STRINGS": "NO", # No -mpascal-strings
106
107
  "GCC_THREADSAFE_STATICS": "NO", # -fno-threadsafe-statics
107
108
  "PREBINDING": "NO", # No -Wl,-prebind
108
- "MACOSX_DEPLOYMENT_TARGET": "10.15", # -mmacosx-version-min=10.14
109
+ "MACOSX_DEPLOYMENT_TARGET": "12", # -mmacosx-version-min=10.14
109
110
  "USE_HEADERMAP": "NO",
110
111
  "OTHER_CFLAGS": [
111
112
  "-fno-strict-aliasing",
112
113
  "-g",
113
114
  "-fno-pie",
114
115
  "-DSOURCE_PATH_SIZE=3",
115
- "-DZITI_OS=macos"
116
+ "-DZITI_OS=macos",
117
+ "-DCXXFLAGS=-mmacosx-version-min=11",
116
118
  ],
117
119
  "OTHER_LDFLAGS": [
118
120
  "-g",
119
- "-mmacosx-version-min=10.15",
121
+ "-mmacosx-version-min=11",
120
122
  ],
121
123
  "WARNING_CFLAGS": [
122
124
  "-Wall",
@@ -0,0 +1,267 @@
1
+ /*
2
+ Copyright Netfoundry, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ https://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ const zitiListen = require('./listen').listen;
18
+ const EventEmitter = require('events');
19
+
20
+ const normalizedArgsSymbol = Symbol('normalizedArgs');
21
+
22
+
23
+ var _serversIndex = 1;
24
+ var _servers = new Map();
25
+
26
+ /**
27
+ * on_listen()
28
+ *
29
+ * @param {*} status
30
+ */
31
+ Server.prototype.on_listen = ( status ) => {
32
+
33
+ console.log('----------- Now inside on_listen callback ----------, status is: %o', status);
34
+
35
+ };
36
+
37
+ /**
38
+ * on_listen_client()
39
+ *
40
+ * @param {*} obj
41
+ */
42
+ Server.prototype.on_listen_client = ( obj ) => {
43
+
44
+ console.log('----------- Now inside on_listen_client callback ----------, obj is: %o', obj);
45
+
46
+ };
47
+
48
+ /**
49
+ * on_client_write()
50
+ *
51
+ * @param {*} obj
52
+ */
53
+ Server.prototype.on_client_write = ( obj ) => {
54
+
55
+ console.log('----------- Now inside on_client_write callback ----------, obj is: %o', obj);
56
+
57
+ };
58
+
59
+ /**
60
+ * on_listen_client_connect()
61
+ *
62
+ * @param {*} obj
63
+ */
64
+ Server.prototype.on_listen_client_connect = ( obj ) => {
65
+
66
+ console.log('----------- Now inside on_listen_client_connect callback ----------, obj is: %o', obj);
67
+
68
+ let self = _servers.get(obj.js_arb_data);
69
+
70
+ // console.log('----------- Now inside on_listen_client_connect callback ----------, self is: %o', self);
71
+
72
+ console.log('----------- Now inside on_listen_client_connect callback ----------, emitting `connection` event for client/socket: %o', obj.client);
73
+ self.emit('connection', obj.client);
74
+
75
+
76
+ };
77
+
78
+ /**
79
+ * on_listen_client_data()
80
+ *
81
+ * @param {*} obj
82
+ */
83
+ Server.prototype.on_listen_client_data = ( obj ) => {
84
+
85
+ console.log('----------- Now inside on_listen_client_data callback ----------, obj is: %o', obj);
86
+
87
+ if (obj.app_data) {
88
+ console.log('----------- app_data ----------, app_data string is: \n%o', obj.app_data.toString());
89
+ }
90
+
91
+ };
92
+
93
+
94
+ /**
95
+ *
96
+ * @param {*} args
97
+ * @returns
98
+ */
99
+ function normalizeArgs(args) {
100
+ let arr;
101
+
102
+ if (args.length === 0) {
103
+ arr = [{}, null];
104
+ arr[normalizedArgsSymbol] = true;
105
+ return arr;
106
+ }
107
+
108
+ const arg0 = args[0];
109
+ let options = {};
110
+ if (typeof arg0 === 'object' && arg0 !== null) {
111
+ // (options[...][, cb])
112
+ options = arg0;
113
+ } else {
114
+ // ([port][, host][...][, cb])
115
+ options.port = arg0;
116
+ if (args.length > 1 && typeof args[1] === 'string') {
117
+ options.host = args[1];
118
+ }
119
+ }
120
+
121
+ const cb = args[args.length - 1];
122
+ if (typeof cb !== 'function')
123
+ arr = [options, null];
124
+ else
125
+ arr = [options, cb];
126
+
127
+ arr[normalizedArgsSymbol] = true;
128
+ return arr;
129
+ }
130
+
131
+ function Server(serviceName, options, connectionListener) {
132
+
133
+ if (!(this instanceof Server))
134
+ return new Server(options, connectionListener);
135
+
136
+ EventEmitter.call(this);
137
+
138
+ if (typeof options === 'function') {
139
+ connectionListener = options;
140
+ options = {};
141
+ this.on('connection', connectionListener);
142
+ } else if (options == null || typeof options === 'object') {
143
+ options = { ...options };
144
+
145
+ if (typeof connectionListener === 'function') {
146
+ this.on('connection', connectionListener);
147
+ }
148
+ } else {
149
+ throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
150
+ }
151
+ if (typeof options.keepAliveInitialDelay !== 'undefined') {
152
+ validateNumber(
153
+ options.keepAliveInitialDelay, 'options.keepAliveInitialDelay'
154
+ );
155
+
156
+ if (options.keepAliveInitialDelay < 0) {
157
+ options.keepAliveInitialDelay = 0;
158
+ }
159
+ }
160
+
161
+ this._serviceName = serviceName;
162
+
163
+ this._connections = 0;
164
+
165
+ // this[async_id_symbol] = -1;
166
+ this._handle = null;
167
+ this._usingWorkers = false;
168
+ this._workers = [];
169
+ this._unref = false;
170
+
171
+ this.allowHalfOpen = options.allowHalfOpen || false;
172
+ this.pauseOnConnect = !!options.pauseOnConnect;
173
+ this.noDelay = Boolean(options.noDelay);
174
+ this.keepAlive = Boolean(options.keepAlive);
175
+ this.keepAliveInitialDelay = ~~(options.keepAliveInitialDelay / 1000);
176
+
177
+ }
178
+ Object.setPrototypeOf(Server.prototype, EventEmitter.prototype);
179
+ Object.setPrototypeOf(Server, EventEmitter);
180
+
181
+
182
+ Server.prototype.listen = function( serviceName, ...args ) {
183
+
184
+ console.log('=======================> express-listener: Server.prototype.listen() entered: arguments: ', arguments);
185
+
186
+ let normalized = normalizeArgs(args);
187
+ normalized = normalizeArgs(normalized[0]);
188
+ console.log('=======================> express-listener: Server.prototype.listen() normalized: ', normalized);
189
+
190
+ // let options = normalized[0]; // we currently ignore options (a.k.a. `port`)
191
+ let cb = normalized[1];
192
+ if (cb === null) { cb = this.on_listen; } // Use our on_listen cb is necessary, else use cb from teh calling app
193
+
194
+ let index = _serversIndex++;
195
+ _servers.set(index, this);
196
+
197
+ zitiListen( serviceName, index, cb, this.on_listen_client, this.on_listen_client_connect, this.on_listen_client_data );
198
+
199
+ };
200
+
201
+ Server.prototype.address = function() {
202
+ if (this._handle && this._handle.getsockname) {
203
+ const out = {};
204
+ const err = this._handle.getsockname(out);
205
+ if (err) {
206
+ throw errnoException(err, 'address');
207
+ }
208
+ return out;
209
+ } else if (this._pipeName) {
210
+ return this._pipeName;
211
+ }
212
+ return null;
213
+ };
214
+
215
+ Server.prototype.close = function(cb) {
216
+ if (typeof cb === 'function') {
217
+ if (!this._handle) {
218
+ this.once('close', function close() {
219
+ cb(new ERR_SERVER_NOT_RUNNING());
220
+ });
221
+ } else {
222
+ this.once('close', cb);
223
+ }
224
+ }
225
+
226
+ if (this._handle) {
227
+ this._handle.close();
228
+ this._handle = null;
229
+ }
230
+
231
+ if (this._usingWorkers) {
232
+ let left = this._workers.length;
233
+ const onWorkerClose = () => {
234
+ if (--left !== 0) return;
235
+
236
+ this._connections = 0;
237
+ this._emitCloseIfDrained();
238
+ };
239
+
240
+ // Increment connections to be sure that, even if all sockets will be closed
241
+ // during polling of workers, `close` event will be emitted only once.
242
+ this._connections++;
243
+
244
+ // Poll workers
245
+ for (let n = 0; n < this._workers.length; n++)
246
+ this._workers[n].close(onWorkerClose);
247
+ } else {
248
+ this._emitCloseIfDrained();
249
+ }
250
+
251
+ return this;
252
+ };
253
+
254
+ Object.defineProperty(Server.prototype, 'listening', {
255
+ __proto__: null,
256
+ get: function() {
257
+ return !!this._handle;
258
+ },
259
+ configurable: true,
260
+ enumerable: true
261
+ });
262
+
263
+
264
+ module.exports = {
265
+ Server,
266
+ };
267
+
package/lib/express.js ADDED
@@ -0,0 +1,120 @@
1
+ /*
2
+ Copyright Netfoundry, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ https://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+ const net = require('./express-listener');
18
+
19
+ const { Server } = require('_http_server'); // from NodeJS internals
20
+
21
+
22
+
23
+
24
+ const getWrappedExpressApp = ( express, serviceName ) => {
25
+
26
+ var wrappedExpressApp = express();
27
+
28
+ /**
29
+ * Listen for connections.
30
+ *
31
+ * A node `http.Server` is returned, with this
32
+ * application (which is a `Function`) as its
33
+ * callback. If you wish to create both an HTTP
34
+ * and HTTPS server you may do so with the "http"
35
+ * and "https" modules as shown here:
36
+ *
37
+ * var http = require('http')
38
+ * , https = require('https')
39
+ * , express = require('express')
40
+ * , app = express();
41
+ *
42
+ * http.createServer(app).listen(80);
43
+ * https.createServer({ ... }, app).listen(443);
44
+ *
45
+ * @return {http.Server}
46
+ * @public
47
+ */
48
+ wrappedExpressApp.listen = function() {
49
+
50
+ console.log('=======================> wrappedExpressApp.listen() entered: arguments: ', arguments);
51
+
52
+ // var server = http.createServer(this);
53
+ // console.log('=======================> wrappedExpressApp.listen() 1 server: ', server);
54
+
55
+ Object.setPrototypeOf(Server.prototype, net.Server.prototype);
56
+ Object.setPrototypeOf(Server, net.Server);
57
+ var server = new Server(this);
58
+
59
+
60
+ net.Server.call(
61
+ server,
62
+ serviceName,
63
+ {
64
+ // allowHalfOpen: true,
65
+ // noDelay: options.noDelay,
66
+ // keepAlive: options.keepAlive,
67
+ // keepAliveInitialDelay: options.keepAliveInitialDelay
68
+ });
69
+
70
+
71
+ // zitiListen( serviceName, on_listen, on_listen_client, on_listen_client_connect, on_listen_client_data );
72
+
73
+ // return server.listen.apply(server, serviceName, arguments);
74
+ return server.listen(serviceName, arguments);
75
+
76
+ };
77
+
78
+ return wrappedExpressApp;
79
+
80
+ };
81
+
82
+
83
+ /**
84
+ * express()
85
+ *
86
+ * @param {*} express
87
+ * @param {*} serviceName
88
+ */
89
+ const express = ( express, serviceName ) => {
90
+
91
+ var app = getWrappedExpressApp( express, serviceName);
92
+
93
+ // console.log('wrappedExpressApp: ', app);
94
+
95
+ // const wrappedExpressResponse = Object.create( app.response, {
96
+
97
+ // data: {
98
+ // value: function(data) {
99
+ // return this.status(200).json({status: true, data: data});
100
+ // },
101
+ // },
102
+
103
+ // message: {
104
+ // value: function(msg) {
105
+ // return this.status(200).json({status: true, message: msg});
106
+ // },
107
+ // },
108
+
109
+ // });
110
+
111
+ // app.response = Object.create(wrappedExpressResponse);
112
+
113
+ return app;
114
+
115
+ };
116
+
117
+ exports.express = express;
118
+
119
+
120
+
package/lib/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/lib/init.js ADDED
@@ -0,0 +1,39 @@
1
+ /*
2
+ Copyright Netfoundry, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ https://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+
18
+ /**
19
+ * init()
20
+ *
21
+ * @param {*} identityPath
22
+ * @returns
23
+ */
24
+ const init = ( identityPath ) => {
25
+
26
+ return new Promise((resolve, reject) => {
27
+
28
+ let rc = ziti.ziti_init( identityPath, ( result ) => {
29
+ return resolve( result );
30
+ });
31
+
32
+ if (rc < 0) {
33
+ return reject(`ziti.init() failed with return code ${rc}`);
34
+ }
35
+
36
+ });
37
+ };
38
+
39
+ exports.init = init;
package/lib/listen.js ADDED
@@ -0,0 +1,30 @@
1
+ /*
2
+ Copyright Netfoundry, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ https://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+
18
+ /**
19
+ * listen()
20
+ *
21
+ * @param {*} identityPath
22
+ * @returns
23
+ */
24
+ const listen = ( serviceName, js_arb_data, on_listen, on_listen_client, on_client_connect, on_client_data ) => {
25
+
26
+ ziti.ziti_listen( serviceName, js_arb_data, on_listen, on_listen_client, on_client_connect, on_client_data );
27
+
28
+ };
29
+
30
+ exports.listen = listen;
package/lib/write.js ADDED
@@ -0,0 +1,31 @@
1
+ /*
2
+ Copyright Netfoundry, Inc.
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ https://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */
16
+
17
+
18
+ /**
19
+ * write()
20
+ *
21
+ * @param {*} conn
22
+ * @param {*} buf
23
+ * @param {*} on_write callback
24
+ */
25
+ const write = ( conn, buf, on_write ) => {
26
+
27
+ ziti.ziti_write( conn, buf, on_write );
28
+
29
+ };
30
+
31
+ exports.write = write;
package/lib/ziti.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ function importAll (r) {
25
25
 
26
26
  if (typeof require.context == 'function') {
27
27
 
28
- importAll( require.context("../build/", true, /\.node$/) );
28
+ importAll( require.context("../build/", true, /\.node$/) );
29
29
 
30
30
  } else {
31
31
 
@@ -37,4 +37,14 @@ if (typeof require.context == 'function') {
37
37
 
38
38
  }
39
39
 
40
- var ziti = module.exports = exports = binding;
40
+ ziti = module.exports = exports = binding;
41
+
42
+
43
+
44
+ /**
45
+ * Attach the external, app-facing, API to the 'ziti' object
46
+ */
47
+ exports.express = require('./express').express;
48
+ exports.init = require('./init').init;
49
+ exports.listen = require('./listen').listen;
50
+ exports.write = require('./write').write;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openziti/ziti-sdk-nodejs",
3
3
  "description": "A NodeJS-based SDK for delivering secure applications over a Ziti Network",
4
- "version": "0.7.0",
4
+ "version": "0.8.0",
5
5
  "main": "./lib/ziti",
6
6
  "scripts": {
7
7
  "build": "npm run build:init; npm run build:c-sdk; npm install --build-from-source --clang=1",
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -73,7 +73,7 @@ static void CallJs_on_req_body(napi_env env, napi_value js_cb, void* context, vo
73
73
  ZITI_NODEJS_LOG(DEBUG, "status: %zd", item->status);
74
74
 
75
75
  // obj.body = body
76
- rc = napi_create_int32(env, (int32_t)item->body, &js_body);
76
+ rc = napi_create_int32(env, (int64_t)item->body, &js_body);
77
77
  if (rc != napi_ok) {
78
78
  napi_throw_error(env, "EINVAL", "failure to create resp.body");
79
79
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/src/utils.c CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 NetFoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/src/utils.h CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 NetFoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
package/src/ziti-add-on.c CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -71,6 +71,7 @@ napi_value Init(napi_env env, napi_value exports) {
71
71
  expose_ziti_enroll(env, exports);
72
72
  expose_ziti_hello(env, exports);
73
73
  expose_ziti_init(env, exports);
74
+ expose_ziti_listen(env, exports);
74
75
  expose_ziti_service_available(env, exports);
75
76
  expose_ziti_shutdown(env, exports);
76
77
  expose_ziti_write(env, exports);
package/src/ziti-nodejs.h CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.
@@ -93,6 +93,20 @@ typedef struct {
93
93
  napi_threadsafe_function tsfn_on_service_available;
94
94
  } ConnAddonData;
95
95
 
96
+ /**
97
+ *
98
+ */
99
+ typedef struct {
100
+ char *service_name;
101
+ int64_t js_arb_data;
102
+ ziti_connection server;
103
+ napi_async_work work;
104
+ napi_threadsafe_function tsfn_on_listen;
105
+ napi_threadsafe_function tsfn_on_listen_client;
106
+ napi_threadsafe_function tsfn_on_listen_client_connect;
107
+ napi_threadsafe_function tsfn_on_listen_client_data;
108
+ } ListenAddonData;
109
+
96
110
  /**
97
111
  *
98
112
  */
@@ -189,6 +203,7 @@ extern void expose_ziti_dial(napi_env env, napi_value exports);
189
203
  extern void expose_ziti_enroll(napi_env env, napi_value exports);
190
204
  extern void expose_ziti_hello(napi_env env, napi_value exports);
191
205
  extern void expose_ziti_init(napi_env env, napi_value exports);
206
+ extern void expose_ziti_listen(napi_env env, napi_value exports);
192
207
  extern void expose_ziti_service_available(napi_env env, napi_value exports);
193
208
  extern void expose_ziti_shutdown(napi_env env, napi_value exports);
194
209
  extern void expose_ziti_write(napi_env env, napi_value exports);
package/src/ziti_close.c CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019-2020 Netfoundry, Inc.
2
+ Copyright Netfoundry, Inc.
3
3
 
4
4
  Licensed under the Apache License, Version 2.0 (the "License");
5
5
  you may not use this file except in compliance with the License.