oracledb 6.7.2 → 6.9.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/LICENSE.txt +1 -1
- package/NOTICE.txt +1 -1
- package/README.md +39 -3
- package/build/Release/oracledb-6.9.0-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.9.0-darwin-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-darwin-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-js-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.9.0-linux-arm64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-linux-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-linux-x64.node-buildinfo.txt +1 -0
- package/build/Release/oracledb-6.9.0-win32-x64.node +0 -0
- package/build/Release/oracledb-6.9.0-win32-x64.node-buildinfo.txt +1 -0
- package/lib/aqMessage.js +10 -1
- package/lib/configProviders/file.js +72 -0
- package/lib/connection.js +153 -4
- package/lib/dbObject.js +51 -10
- package/lib/errors.js +144 -36
- package/lib/impl/connection.js +24 -1
- package/lib/impl/datahandlers/buffer.js +92 -1
- package/lib/impl/datahandlers/constants.js +2 -0
- package/lib/impl/datahandlers/oson.js +15 -1
- package/lib/impl/datahandlers/vector.js +72 -27
- package/lib/impl/pool.js +10 -1
- package/lib/impl/resultset.js +5 -4
- package/lib/lob.js +9 -1
- package/lib/oracledb.js +209 -20
- package/lib/pool.js +12 -1
- package/lib/poolStatistics.js +3 -1
- package/lib/settings.js +5 -1
- package/lib/thin/connection.js +130 -12
- package/lib/thin/dbObject.js +46 -13
- package/lib/thin/lob.js +2 -3
- package/lib/thin/pool.js +112 -31
- package/lib/thin/protocol/capabilities.js +8 -4
- package/lib/thin/protocol/constants.js +31 -1
- package/lib/thin/protocol/messages/auth.js +42 -6
- package/lib/thin/protocol/messages/base.js +98 -9
- package/lib/thin/protocol/messages/dataType.js +2 -1
- package/lib/thin/protocol/messages/execute.js +46 -4
- package/lib/thin/protocol/messages/fastAuth.js +6 -1
- package/lib/thin/protocol/messages/lobOp.js +5 -22
- package/lib/thin/protocol/messages/logOff.js +0 -1
- package/lib/thin/protocol/messages/sessionRelease.js +0 -1
- package/lib/thin/protocol/messages/transactionSwitch.js +12 -4
- package/lib/thin/protocol/messages/withData.js +10 -1
- package/lib/thin/protocol/packet.js +1 -1
- package/lib/thin/protocol/protocol.js +2 -1
- package/lib/thin/sqlnet/ANO.js +438 -0
- package/lib/thin/sqlnet/connStrategy.js +2 -1
- package/lib/thin/sqlnet/constants.js +5 -1
- package/lib/thin/sqlnet/ezConnectResolver.js +4 -2
- package/lib/thin/sqlnet/navNodes.js +22 -3
- package/lib/thin/sqlnet/networkSession.js +94 -16
- package/lib/thin/sqlnet/ntTcp.js +50 -3
- package/lib/thin/sqlnet/packet.js +32 -4
- package/lib/thin/sqlnet/sessionAtts.js +24 -2
- package/lib/thin/util.js +3 -8
- package/lib/transformer.js +13 -2
- package/lib/types.js +220 -8
- package/lib/util.js +77 -3
- package/lib/version.js +2 -2
- package/package/install.js +3 -3
- package/package/prunebinaries.js +6 -12
- package/package.json +2 -2
- package/{lib/configProviders/azure.js → plugins/configProviders/azure/index.js} +70 -63
- package/plugins/configProviders/azurevault/index.js +84 -0
- package/{lib → plugins}/configProviders/base.js +13 -3
- package/{lib/configProviders/ociobject.js → plugins/configProviders/ociobject/index.js} +43 -78
- package/plugins/configProviders/ocivault/index.js +100 -0
- package/plugins/token/extensionAzure/index.js +101 -0
- package/plugins/token/extensionOci/index.js +210 -0
- package/build/Release/oracledb-6.7.2-darwin-arm64.node +0 -0
- package/build/Release/oracledb-6.7.2-darwin-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-darwin-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-darwin-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-js-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-linux-arm64.node +0 -0
- package/build/Release/oracledb-6.7.2-linux-arm64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-linux-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-linux-x64.node-buildinfo.txt +0 -1
- package/build/Release/oracledb-6.7.2-win32-x64.node +0 -0
- package/build/Release/oracledb-6.7.2-win32-x64.node-buildinfo.txt +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright (c) 2025, Oracle and/or its affiliates.
|
|
2
|
+
|
|
3
|
+
//-----------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// This software is dual-licensed to you under the Universal Permissive License
|
|
6
|
+
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
|
7
|
+
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
|
8
|
+
// either license.
|
|
9
|
+
//
|
|
10
|
+
// If you elect to accept the software under the Apache License, Version 2.0,
|
|
11
|
+
// the following applies:
|
|
12
|
+
//
|
|
13
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
+
// you may not use this file except in compliance with the License.
|
|
15
|
+
// You may obtain a copy of the License at
|
|
16
|
+
//
|
|
17
|
+
// https://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
+
//
|
|
19
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
// See the License for the specific language governing permissions and
|
|
23
|
+
// limitations under the License.
|
|
24
|
+
//
|
|
25
|
+
//-----------------------------------------------------------------------------
|
|
26
|
+
'use strict';
|
|
27
|
+
const oracledb = require('oracledb');
|
|
28
|
+
const msal = require('@azure/msal-node');
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async function getToken(params) {
|
|
32
|
+
switch (params.authType.toLowerCase()) {
|
|
33
|
+
case 'azureserviceprincipal':
|
|
34
|
+
return await servicePrincipalCredentials(params);
|
|
35
|
+
default:
|
|
36
|
+
throwErr(`Invalid authentication type ${params.authType} in extensionAzure plugins.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//---------------------------------------------------------------------------
|
|
41
|
+
// throwErr()
|
|
42
|
+
//---------------------------------------------------------------------------
|
|
43
|
+
function throwErr(message) {
|
|
44
|
+
throw new Error(message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//---------------------------------------------------------------------------
|
|
48
|
+
// Returns the access token for authentication as a service principal. This
|
|
49
|
+
// authentication method requires a client ID along with either a secret or
|
|
50
|
+
// certificate. These values may be provided as config parameters read by
|
|
51
|
+
// the Azure SDK.
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
async function servicePrincipalCredentials(params) {
|
|
54
|
+
const clientId = params.clientId ??
|
|
55
|
+
throwErr("Token based authentication config parameter clientId is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
56
|
+
const authority = params.authority ??
|
|
57
|
+
throwErr("Token based authentication config parameter authority is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
58
|
+
const clientSecret = params.clientSecret ??
|
|
59
|
+
throwErr("Token based authentication config parameter clientSecret is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
60
|
+
const msalConfig = {
|
|
61
|
+
auth: {
|
|
62
|
+
clientId: clientId,
|
|
63
|
+
authority: authority,
|
|
64
|
+
clientSecret: clientSecret,
|
|
65
|
+
},
|
|
66
|
+
system: {
|
|
67
|
+
// Use it while generating azure tokens behind proxy
|
|
68
|
+
// Otherwise can remove this option
|
|
69
|
+
networkClient: params.proxy,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if (!msalConfig.system.networkClient) {
|
|
74
|
+
delete msalConfig.system.networkClient;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const scopes = params.scopes ??
|
|
78
|
+
throwErr("Token based authentication config parameter scopes is missing for azureServicePrincipal in extensionAzure plugins.");
|
|
79
|
+
const tokenRequest = {
|
|
80
|
+
scopes: [scopes],
|
|
81
|
+
};
|
|
82
|
+
const cca = new msal.ConfidentialClientApplication(msalConfig);
|
|
83
|
+
const authResponse = await cca.acquireTokenByClientCredential(tokenRequest);
|
|
84
|
+
return authResponse.accessToken;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// hookFn()
|
|
89
|
+
// hookFn is registered to driver while loading plugins.
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
|
|
92
|
+
function hookFn(options) {
|
|
93
|
+
if (options.tokenAuthConfigAzure) {
|
|
94
|
+
// eslint-disable-next-line no-unused-vars
|
|
95
|
+
options.accessToken = async function callbackFn(refresh, config) {
|
|
96
|
+
return await getToken(config);
|
|
97
|
+
};
|
|
98
|
+
options.accessTokenConfig = options.tokenAuthConfigAzure;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
oracledb.registerProcessConfigurationHook(hookFn);
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// Copyright (c) 2025, Oracle and/or its affiliates.
|
|
2
|
+
|
|
3
|
+
//-----------------------------------------------------------------------------
|
|
4
|
+
//
|
|
5
|
+
// This software is dual-licensed to you under the Universal Permissive License
|
|
6
|
+
// (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License
|
|
7
|
+
// 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose
|
|
8
|
+
// either license.
|
|
9
|
+
//
|
|
10
|
+
// If you elect to accept the software under the Apache License, Version 2.0,
|
|
11
|
+
// the following applies:
|
|
12
|
+
//
|
|
13
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
14
|
+
// you may not use this file except in compliance with the License.
|
|
15
|
+
// You may obtain a copy of the License at
|
|
16
|
+
//
|
|
17
|
+
// https://www.apache.org/licenses/LICENSE-2.0
|
|
18
|
+
//
|
|
19
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
20
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
+
// See the License for the specific language governing permissions and
|
|
23
|
+
// limitations under the License.
|
|
24
|
+
//
|
|
25
|
+
//-----------------------------------------------------------------------------
|
|
26
|
+
'use strict';
|
|
27
|
+
const oracledb = require('oracledb');
|
|
28
|
+
const identitydataplane = require("oci-identitydataplane");
|
|
29
|
+
const common = require("oci-common");
|
|
30
|
+
const { generateKeyPair } = require('crypto');
|
|
31
|
+
const fs = require('fs');
|
|
32
|
+
|
|
33
|
+
async function getToken(params) {
|
|
34
|
+
switch (params.authType.toLowerCase()) {
|
|
35
|
+
case 'configfilebasedauthentication':
|
|
36
|
+
return await configFileBasedAuthentication(params);
|
|
37
|
+
case 'simpleauthentication':
|
|
38
|
+
return await simpleAuthentication(params);
|
|
39
|
+
case 'instanceprincipal':
|
|
40
|
+
return await instancePrincipalAuthentication(params);
|
|
41
|
+
default:
|
|
42
|
+
throwErr(`Invalid authentication type ${params.authType} in extensionOci plugins.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//---------------------------------------------------------------------------
|
|
47
|
+
// throwErr()
|
|
48
|
+
//---------------------------------------------------------------------------
|
|
49
|
+
function throwErr(message) {
|
|
50
|
+
throw new Error(message);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//---------------------------------------------------------------------------
|
|
54
|
+
// Requests an access token from the dataplane service
|
|
55
|
+
// Generating security token
|
|
56
|
+
//---------------------------------------------------------------------------
|
|
57
|
+
async function generateAccessToken(provider, scope) {
|
|
58
|
+
// Scope uses the * character to identify all databases in the cloud
|
|
59
|
+
// tenancy of the authenticated user. urn:oracle:db::id::*, default
|
|
60
|
+
|
|
61
|
+
// A scope that authorizes access to all databases within a compartment has
|
|
62
|
+
// the form: urn:oracle:db::id::<compartment-ocid>
|
|
63
|
+
// String scope = "urn:oracle:db::id::ocid1.compartment.oc1..xxxxxxxx"
|
|
64
|
+
|
|
65
|
+
// A scope that authorizes access to a single database within a compartment
|
|
66
|
+
// has the form: urn:oracle:db::id::<compartment-ocid>::<database-ocid>
|
|
67
|
+
// String scope = "urn:oracle:db::id::ocid1.compartment.oc1..xxxxxx::ocid1.autonomousdatabase.oc1.phx.xxxxxx"
|
|
68
|
+
|
|
69
|
+
const client = new identitydataplane.DataplaneClient({
|
|
70
|
+
authenticationDetailsProvider: provider
|
|
71
|
+
});
|
|
72
|
+
const keyPair = await _getKeyPair();
|
|
73
|
+
|
|
74
|
+
const generateScopedAccessTokenRequest = {
|
|
75
|
+
generateScopedAccessTokenDetails: {
|
|
76
|
+
scope: scope ?? "urn:oracle:db::id::*",
|
|
77
|
+
publicKey: keyPair.publicKey
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const generateScopedAccessTokenResponse =
|
|
82
|
+
await client.generateScopedAccessToken(generateScopedAccessTokenRequest);
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
token: generateScopedAccessTokenResponse.securityToken.token,
|
|
86
|
+
privateKey: keyPair.privateKey
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
//---------------------------------------------------------------------------
|
|
91
|
+
// Generates a public-private key pair for proof of possession when token
|
|
92
|
+
// requested by this provider is presented for validation.
|
|
93
|
+
//---------------------------------------------------------------------------
|
|
94
|
+
async function _getKeyPair() {
|
|
95
|
+
return await new Promise((resolve, reject) => {
|
|
96
|
+
generateKeyPair('rsa', {
|
|
97
|
+
modulusLength: 4096,
|
|
98
|
+
publicKeyEncoding: {
|
|
99
|
+
type: 'spki',
|
|
100
|
+
format: 'pem'
|
|
101
|
+
},
|
|
102
|
+
privateKeyEncoding: {
|
|
103
|
+
type: 'pkcs8',
|
|
104
|
+
format: 'pem',
|
|
105
|
+
}
|
|
106
|
+
}, (err, publicKey, privateKey) => {
|
|
107
|
+
if (err) return reject(err);
|
|
108
|
+
resolve({publicKey, privateKey});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//---------------------------------------------------------------------------
|
|
114
|
+
// User defined function for reading token and private key values
|
|
115
|
+
// generated by the OCI SDK.
|
|
116
|
+
// Returns the OCI SDK's token request details object for the given
|
|
117
|
+
// config parameters, where a scope parameter specifies the
|
|
118
|
+
// scope of requested access. The request will specify a public key
|
|
119
|
+
// as being paired with a private key that the presenter of the token must
|
|
120
|
+
// prove to be in possession of.
|
|
121
|
+
//
|
|
122
|
+
// The path and profile of the config file may be configured by optional
|
|
123
|
+
// parameters in object accessTokenConfig. If values not provided in
|
|
124
|
+
// accessTokenConfig then this method will read the DEFAULT
|
|
125
|
+
// profile from $HOME/.oci/config.
|
|
126
|
+
// accessTokenConfig.configFileLocation, Not null.
|
|
127
|
+
// accessTokenConfig.profile, Not null.
|
|
128
|
+
//
|
|
129
|
+
// Return API Key-Based Authentication.
|
|
130
|
+
//---------------------------------------------------------------------------
|
|
131
|
+
async function configFileBasedAuthentication(accessTokenConfig) {
|
|
132
|
+
const provider =
|
|
133
|
+
new common.ConfigFileAuthenticationDetailsProvider(accessTokenConfig.configFileLocation, accessTokenConfig.profile);
|
|
134
|
+
|
|
135
|
+
return await generateAccessToken(provider, accessTokenConfig.scope);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//---------------------------------------------------------------------------
|
|
139
|
+
// simpleAuthentication()
|
|
140
|
+
// Returns authentication details for the provided credentials.
|
|
141
|
+
// tenancy: OCID of the tenancy
|
|
142
|
+
// user: OCID of the user
|
|
143
|
+
// fingerprint: Fingerprint of the public key
|
|
144
|
+
// privateKey: Private key
|
|
145
|
+
// passPhrase: Passphrase that is used to encrypt the private key.
|
|
146
|
+
// null if not used.
|
|
147
|
+
// Return API Key-Based Authentication.
|
|
148
|
+
//---------------------------------------------------------------------------
|
|
149
|
+
async function simpleAuthentication(accessTokenConfig) {
|
|
150
|
+
const tenancy = accessTokenConfig.tenancy ??
|
|
151
|
+
throwErr("Token based authentication config parameter tenancy is missing for simpleauthentication in extensionOci plugins.");
|
|
152
|
+
const user = accessTokenConfig.user ??
|
|
153
|
+
throwErr("Token based authentication config parameter user is missing for simpleauthentication in extensionOci plugins.");
|
|
154
|
+
const fingerprint = accessTokenConfig.fingerprint ??
|
|
155
|
+
throwErr("Token based authentication config parameter fingerprint is missing for simpleauthentication in extensionOci plugins.");
|
|
156
|
+
const passphrase = accessTokenConfig.passphrase |= null; // optional
|
|
157
|
+
const privateKeyLocation = accessTokenConfig.privateKeyLocation ??
|
|
158
|
+
throwErr("Token based authentication config parameter privateKeyLocation is missing for simpleauthentication in extensionOci plugins.");
|
|
159
|
+
const privateKey = fs.readFileSync(privateKeyLocation, 'utf-8'); // ~/.oci/oci_api_key.pem
|
|
160
|
+
const regionId = accessTokenConfig.regionId ?? // ex : us-ashburn-1
|
|
161
|
+
throwErr("Token based authentication config parameter regionId is missing for simpleauthentication in extensionOci plugins.");
|
|
162
|
+
|
|
163
|
+
let region;
|
|
164
|
+
const regionsList = common.Region.values();
|
|
165
|
+
regionsList.forEach(regions => {
|
|
166
|
+
if (regions.regionId === regionId) {
|
|
167
|
+
region = regions;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
const provider = new common.SimpleAuthenticationDetailsProvider(
|
|
172
|
+
tenancy,
|
|
173
|
+
user,
|
|
174
|
+
fingerprint,
|
|
175
|
+
privateKey,
|
|
176
|
+
passphrase,
|
|
177
|
+
region
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
return await generateAccessToken(provider, accessTokenConfig.scope);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//---------------------------------------------------------------------------
|
|
184
|
+
// instancePrincipalAuthentication()
|
|
185
|
+
//
|
|
186
|
+
// Authentication in a Compute Instance, without credentials, as an instance
|
|
187
|
+
// principal. This authentication method should only work on compute
|
|
188
|
+
// instances where internal network endpoints are reachable.
|
|
189
|
+
// Return Instance Principal Authentication.
|
|
190
|
+
//---------------------------------------------------------------------------
|
|
191
|
+
async function instancePrincipalAuthentication(accessTokenConfig) {
|
|
192
|
+
const provider = await new common.InstancePrincipalsAuthenticationDetailsProviderBuilder().build();
|
|
193
|
+
|
|
194
|
+
return await generateAccessToken(provider, accessTokenConfig.scope);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
//---------------------------------------------------------------------------
|
|
198
|
+
// hookFn()
|
|
199
|
+
// hookFn will get registerd to driver while loading plugins.
|
|
200
|
+
//---------------------------------------------------------------------------
|
|
201
|
+
function hookFn(options) {
|
|
202
|
+
if (options.tokenAuthConfigOci) {
|
|
203
|
+
// eslint-disable-next-line no-unused-vars
|
|
204
|
+
options.accessToken = async function callbackFn(refresh, config) {
|
|
205
|
+
return await getToken(config);
|
|
206
|
+
};
|
|
207
|
+
options.accessTokenConfig = options.tokenAuthConfigOci;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
oracledb.registerProcessConfigurationHook(hookFn);
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-darwin-arm64.node v22.2.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:55:05 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-darwin-x64.node v20.11.1 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 14:37:36 GMT
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
d813e9fe939a65599afab84c08ad9fcea51718d5
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-linux-arm64.node v20.16.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:48:03 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-linux-x64.node v20.16.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:47:00 GMT
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
oracledb-6.7.2-win32-x64.node v20.0.0 d813e9fe939a65599afab84c08ad9fcea51718d5 ca4b004c471033328549f8b4d461cb5985fe2230 Fri, 07 Feb 2025 13:46:32 GMT
|