warehouse.ai-status-models
Advanced tools
Comparing version 1.2.0 to 2.0.0
21
index.js
@@ -1,2 +0,1 @@ | ||
/** | ||
@@ -12,10 +11,10 @@ * StatusModels class which contains all the initialized models wrapped with | ||
* | ||
* @param {Datastar} datastar Datastar instance | ||
* @param {Object} dynamodb Dyanmo object model | ||
* @constructor | ||
*/ | ||
constructor(datastar) { | ||
this.Status = require('./status')(datastar, this); | ||
this.StatusHead = require('./status-head')(datastar, this); | ||
this.StatusEvent = require('./status-event')(datastar, this); | ||
this.StatusCounter = require('./status-counter')(datastar, this); | ||
constructor(dynamodb) { | ||
this.Status = require('./status')(dynamodb); | ||
this.StatusHead = require('./status-head')(dynamodb); | ||
this.StatusEvent = require('./status-event')(dynamodb); | ||
this.StatusCounter = require('./status-counter')(dynamodb); | ||
} | ||
@@ -56,7 +55,7 @@ | ||
* @function models | ||
* @param {Datastar} datastar Datastar instance | ||
* @returns {StatusModels} to be used | ||
* @param {Object} dynamodb Dyanmo object model | ||
* @returns {StatusModels} warehouse status models | ||
*/ | ||
module.exports = function models(datastar) { | ||
return new StatusModels(datastar); | ||
module.exports = function models(dynamodb) { | ||
return new StatusModels(dynamodb); | ||
}; |
{ | ||
"name": "warehouse.ai-status-models", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"description": "models for warehouse.ai-status-api", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "nyc mocha test/*.test.js", | ||
"localstack": "docker run -it -p 4569:4569 --rm localstack/localstack:0.8.6", | ||
"test": "DYNAMO_ENDPOINT= nyc mocha test/*.test.js --timeout 10000", | ||
"lint": "eslint-godaddy *.js test/*.js", | ||
@@ -17,3 +18,4 @@ "pretest": "npm run lint" | ||
"warehouse.ai-status-api", | ||
"datastar", | ||
"dynastar", | ||
"dynamo", | ||
"warehouse.ai" | ||
@@ -28,16 +30,19 @@ ], | ||
"devDependencies": { | ||
"assume": "^2.1.0", | ||
"datastar": "^1.5.0", | ||
"datastar-test-tools": "^1.0.0", | ||
"eslint": "^4.19.1", | ||
"eslint-config-godaddy": "^2.1.0", | ||
"eslint-plugin-json": "^1.2.0", | ||
"eslint-plugin-mocha": "^5.0.0", | ||
"assume": "^2.2.0", | ||
"aws-liveness": "^1.1.0", | ||
"aws-sdk": "^2.559.0", | ||
"dynamodb-x": "^1.2.3", | ||
"eslint": "^5.16.0", | ||
"eslint-config-godaddy": "^3.0.0", | ||
"eslint-plugin-json": "^1.4.0", | ||
"eslint-plugin-mocha": "^5.3.0", | ||
"mocha": "^5.2.0", | ||
"nyc": "^12.0.2", | ||
"uuid": "^3.2.1" | ||
"nyc": "^14.0.0", | ||
"uuid": "^3.3.2" | ||
}, | ||
"dependencies": { | ||
"dynastar": "^1.0.0", | ||
"joi": "^14.3.1", | ||
"tinythen": "^1.0.1" | ||
} | ||
} |
113
README.md
# warehouse.ai-status-models | ||
[](https://travis-ci.org/warehouseai/warehouse.ai-status-models) | ||
Datastar models for the warehouse.ai-status-api | ||
[](https://www.npmjs.com/package/warehouse.ai-status-models) | ||
[](https://github.com/warehouseai/warehouse.ai-status-models/blob/master/LICENSE) | ||
[](https://npmcharts.com/compare/warehouse.ai-status-models?minimal=true) | ||
[](https://travis-ci.org/warehouseai/warehouse.ai-status-models) | ||
[](https://github.com/warehouseai/warehouse.ai-status-models/blob/master/package.json) | ||
## models | ||
[Datastar][dynastar] models for the [Warehouse.ai-status-api]. | ||
- `Status` - Generic status information, stores total number of builds for a given | ||
pkg, env, version in order to compute progress in combination with | ||
`StatusCounter`. | ||
- `StatusHead` - Same as above, just the latest version for a given `pkg`, | ||
`env`. | ||
- `StatusEvent` - A detailed event for the various stages of a build process | ||
containing `message` and optional `details` properties as well as `locale` and | ||
whether it is an error or not. | ||
- `StatusCounter` - A simple distributed counter model that is incremented when | ||
a `locale` build has completed in order to compute progress based on total. | ||
## Install | ||
## test | ||
```bash | ||
npm install warehouse.ai-status-models --save | ||
``` | ||
Running tests assumes you have java installed and a local cassandra installed | ||
and running for your given operating system. Once that is complete, just run: | ||
## Usage | ||
``` | ||
const dynamoClient = new AWS.DynamoDB({ /* connection config */ }); | ||
const dynamodb = require('dynamodb'); | ||
dynamodb.dynamoDriver(dynamoClient); | ||
const models = require('warehouse.ai-status-models')(dynamodb); | ||
// from dynastar.define we get... | ||
const Status = models.Status; | ||
Status.findOne({ ... }).then(res => { ... }).catch(err => { ... }); | ||
``` | ||
## API | ||
All schemas for the API documentation are written using | ||
[Joi][joi] notation. | ||
### Schemas | ||
### Status (`Status`) | ||
Generic status information | ||
Column | Type | Summary | ||
------------------ | ---------------- | ------------ | ||
pkg (pk) | string | Name of a package | ||
env (pk) | string | What environment is this build made for (dev, test, etc.) | ||
version (pk) | string | What version of a package does this status represent | ||
previousVersion | string | The previous version number | ||
total | number | Total progress as percentage | ||
error | boolean | Did the build error | ||
createdAt | timestamp | Time of creation | ||
updatedAt | timestamp | Time of last update | ||
complete | boolean | Did the build complete | ||
### StatusHead (`StatusHead`) | ||
Generic status information but just for he latest version for a given | ||
`pkg` and `env`. Refer to the table above for details. The properties | ||
`error` and `complete` do not exist on this table. | ||
### StatusEvent (`StatusEvent`) | ||
A detailed event for the various stages of a build process containing `message` | ||
and optional `details` properties as well as `locale` and whether it is and | ||
error or not. | ||
Column | Type | Summary | ||
------------------ | ---------------- | ------------ | ||
pkg (pk) | string | Name of a package | ||
env (pk) | string | What environment is this build made for (dev, test, etc.) | ||
version (pk) | string | What version of a package does this status represent | ||
locale | string | Build locale | ||
error | boolean | Is the status event an error | ||
message | string | Status message | ||
details | string | Message details | ||
createdAt | timestamp | Time of creation | ||
eventId | string (timeUUID)| Unique id sortable by time | ||
### StatusCounter (`StatusCounter`) | ||
A simple distributed counter model that is incremented when a `locale` build | ||
has completed in order to compute progress based on total amount of `locales`. | ||
Column | Type | Summary | ||
------------------ | ---------------- | ------------ | ||
pkg (pk) | string | Name of a package | ||
env (pk) | string | What environment is this build made for (dev, test, etc.) | ||
version (pk) | string | What version of a package does this status represent | ||
count | counter | Incrementable counter | ||
## Test | ||
Before running tests, spin up an instance of localstack by running | ||
```sh | ||
npm run localstack | ||
``` | ||
Then run: | ||
```sh | ||
npm test | ||
``` | ||
[dynastar]: https://github.com/godaddy/dynastar | ||
[Warehouse.ai-status-api]: https://github.com/godaddy/warehouse.ai-status-api | ||
[joi]: https://github.com/hapijs/joi |
@@ -1,5 +0,7 @@ | ||
const Wrap = require('./wrap'); | ||
const { AwaitWrap, Dynastar } = require('dynastar'); | ||
const Joi = require('joi'); | ||
/** | ||
* Extends the Wrap class to add an increment function in order to do the | ||
* Extends the AwaitWrap class to add an increment function in order to do the | ||
* single operation it permits | ||
@@ -9,3 +11,3 @@ * | ||
*/ | ||
class CounterWrap extends Wrap { | ||
class CounterWrap extends AwaitWrap { | ||
/** | ||
@@ -16,6 +18,3 @@ * Increment the given counter for this table in the manual way with the | ||
* @function increment | ||
* @param {Object} params Parameters for performing increment | ||
* @param {String} params.env Env for Counter table | ||
* @param {String} params.pkg Pkg for Counter table | ||
* @param {String} params.version Version for counter table | ||
* @param {Object} key Object containing key of item to increment | ||
* @param {Number} amount Number to increment | ||
@@ -25,6 +24,4 @@ * @returns {Promise} when operation complete | ||
*/ | ||
async increment(params, amount = 1) { | ||
const client = await this._getConnection(); | ||
const query = `UPDATE status_counter SET count=count+${amount} WHERE pkg=:pkg AND env=:env AND version=:version`; | ||
return client.execute(query, params, { prepare: true, counter: true }); | ||
async increment(key, amount = 1) { | ||
return this.update({ ...key, count: { $add: amount } }); | ||
} | ||
@@ -36,6 +33,3 @@ /** | ||
* @function increment | ||
* @param {Object} params Parameters for performing increment | ||
* @param {String} params.env Env for Counter table | ||
* @param {String} params.pkg Pkg for Counter table | ||
* @param {String} params.version Version for counter table | ||
* @param {Object} key Object containing key of item to increment | ||
* @param {Number} amount Number to increment | ||
@@ -45,6 +39,4 @@ * @returns {Promise} when operation complete | ||
*/ | ||
async decrement(params, amount = 1) { | ||
const client = await this._getConnection(); | ||
const query = `UPDATE status_counter SET count=count-${amount} WHERE pkg=:pkg AND env=:env AND version=:version`; | ||
return client.execute(query, params, { prepare: true, counter: true }); | ||
async decrement(key, amount = 1) { | ||
return this.update({ ...key, count: { $add: -1 * amount } }); | ||
} | ||
@@ -54,3 +46,3 @@ } | ||
/** | ||
* Returns the wrapped Datastar model for status_counter | ||
* Returns a Wrapped Dynastar model for status_counter | ||
* This model is used for counting the completions of each locale for a given | ||
@@ -60,25 +52,25 @@ * build so we can track overall progress | ||
* @function statcount | ||
* @param {Datastar} datastar Datastar instance | ||
* @param {Object} dynamo Dynamo object model | ||
* @returns {CounterWrap} model for StatusCounter | ||
* @private | ||
*/ | ||
module.exports = function statcount(datastar) { | ||
const cql = datastar.schema.cql; | ||
const StatusCounter = datastar.define('status_counter', { | ||
schema: datastar.schema.object({ | ||
pkg: cql.text(), | ||
env: cql.text(), | ||
version: cql.text(), | ||
count: cql.counter() | ||
}).partitionKey(['pkg', 'env', 'version']), | ||
with: { | ||
compaction: { | ||
class: 'LeveledCompactionStrategy' | ||
} | ||
module.exports = function statcount(dynamo) { | ||
const hashKey = 'key'; | ||
const createKey = (data) => { | ||
return `${data.pkg}!${data.env}!${data.version}`; | ||
}; | ||
const model = dynamo.define('StatusCounter', { | ||
hashKey, | ||
tableName: 'WrhsStatusCounter', | ||
schema: { | ||
key: Joi.string(), | ||
pkg: Joi.string(), | ||
env: Joi.string(), | ||
version: Joi.string(), | ||
count: Joi.number() | ||
} | ||
}); | ||
return new CounterWrap(StatusCounter); | ||
return new CounterWrap(new Dynastar({ model, hashKey, createKey })); | ||
}; | ||
module.exports.CounterWrap = CounterWrap; |
@@ -1,34 +0,37 @@ | ||
const Wrap = require('./wrap'); | ||
const { AwaitWrap, Dynastar } = require('dynastar'); | ||
const Joi = require('joi'); | ||
/** | ||
* Returns the wrapped status event model used for storing each event for the | ||
* Returns a Wrapped Dynastar model used for storing each event for the | ||
* various stages of a build process within the warehouse system. | ||
* | ||
* @function statevent | ||
* @param {Datastar} datastar Datastar instance | ||
* @returns {Wrap} StatusEvent | ||
* @param {Object} dynamo Dynamo object model | ||
* @returns {AwaitWrap} StatusEvent | ||
*/ | ||
module.exports = function statevent(datastar) { | ||
const cql = datastar.schema.cql; | ||
const StatusEvent = datastar.define('status_event', { | ||
schema: datastar.schema.object({ | ||
pkg: cql.text(), | ||
env: cql.text(), | ||
version: cql.text(), | ||
locale: cql.text(), | ||
error: cql.boolean(), | ||
message: cql.text(), | ||
details: cql.text(), | ||
create_date: cql.timestamp({ default: 'create' }), | ||
event_id: cql.timeuuid() | ||
}).partitionKey(['pkg', 'env', 'version']) | ||
.clusteringKey('event_id'), | ||
with: { | ||
compaction: { | ||
class: 'TimeWindowCompactionStrategy' | ||
} | ||
module.exports = function statevent(dynamo) { | ||
const hashKey = 'key'; | ||
const rangeKey = 'eventId'; | ||
const createKey = (data) => { | ||
return `${data.pkg}!${data.env}!${data.version}`; | ||
}; | ||
const model = dynamo.define('StatusEvent', { | ||
hashKey, | ||
rangeKey, | ||
timestamps: true, | ||
updatedAt: false, | ||
tableName: 'WrhsStatusEvent', | ||
schema: { | ||
key: Joi.string(), | ||
pkg: Joi.string(), | ||
env: Joi.string(), | ||
version: Joi.string(), | ||
locale: Joi.string(), | ||
error: Joi.boolean(), | ||
message: Joi.string(), | ||
details: Joi.string(), | ||
eventId: dynamo.types.timeUUID() | ||
} | ||
}); | ||
return new Wrap(StatusEvent); | ||
return new AwaitWrap(new Dynastar({ model, hashKey, rangeKey, createKey })); | ||
}; |
@@ -1,31 +0,31 @@ | ||
const Wrap = require('./wrap'); | ||
const { AwaitWrap, Dynastar } = require('dynastar'); | ||
const Joi = require('joi'); | ||
/** | ||
* Returns a wrapped StatusHead model which is used for storing the latest | ||
* Returns a wrapped Dynastar model which is used for storing the latest | ||
* status for a given pkg, env without needing to specify the version | ||
* | ||
* @function stathead | ||
* @param {Datastar} datastar Datastar instance | ||
* @returns {Wrap} StatusHead | ||
* @function statushead | ||
* @param {Object} dynamo Dynamo object model | ||
* @returns {AwaitWrap} StatusHead | ||
*/ | ||
module.exports = function stathead(datastar) { | ||
const cql = datastar.schema.cql; | ||
const StatusHead = datastar.define('status_head', { | ||
schema: datastar.schema.object({ | ||
pkg: cql.text(), | ||
env: cql.text(), | ||
version: cql.text(), | ||
previous_version: cql.text(), | ||
total: cql.int(), | ||
create_date: cql.timestamp({ default: 'create' }), | ||
update_date: cql.timestamp({ default: 'update' }) | ||
}).partitionKey(['pkg', 'env']), | ||
with: { | ||
compaction: { | ||
class: 'LeveledCompactionStrategy' | ||
} | ||
module.exports = function statushead(dynamo) { | ||
const hashKey = 'key'; | ||
const createKey = (data) => { | ||
return `${data.pkg}!${data.env}!${data.version}`; | ||
}; | ||
const model = dynamo.define('StatusHead', { | ||
hashKey, | ||
timestamps: true, | ||
tableName: 'WhrsStatusHead', | ||
schema: { | ||
key: Joi.string(), | ||
pkg: Joi.string(), | ||
env: Joi.string(), | ||
version: Joi.string(), | ||
previousVersion: Joi.string(), | ||
total: Joi.number() | ||
} | ||
}); | ||
return new Wrap(StatusHead); | ||
return new AwaitWrap(new Dynastar({ model, hashKey, createKey })); | ||
}; |
@@ -1,5 +0,6 @@ | ||
const Wrap = require('./wrap'); | ||
const { AwaitWrap, Dynastar } = require('dynastar'); | ||
const Joi = require('joi'); | ||
/** | ||
* Returns wrapped Status model that is used for storing the general status for | ||
* Returns a Wrapped Dynastar model that is used for storing the general status for | ||
* a given pkg, env, version. This is used for computing progress in | ||
@@ -9,27 +10,26 @@ * conjunction with StatusCounter using the `total` field | ||
* @function status | ||
* @param {Datastar} datastar Datastar instance | ||
* @returns {Wrap} Status | ||
* @param {Object} dynamo Dynamo object model | ||
* @returns {AwaitWrap} Status | ||
*/ | ||
module.exports = function status(datastar) { | ||
const cql = datastar.schema.cql; | ||
const Status = datastar.define('status', { | ||
schema: datastar.schema.object({ | ||
pkg: cql.text(), | ||
env: cql.text(), | ||
version: cql.text(), | ||
previous_version: cql.text(), | ||
total: cql.int(), | ||
error: cql.boolean(), | ||
create_date: cql.timestamp({ default: 'create' }), | ||
update_date: cql.timestamp({ default: 'update' }), | ||
complete: cql.boolean() | ||
}).partitionKey(['pkg', 'env', 'version']), | ||
with: { | ||
compaction: { | ||
class: 'TimeWindowCompactionStrategy' | ||
} | ||
module.exports = function status(dynamo) { | ||
const hashKey = 'key'; | ||
const createKey = (data) => { | ||
return `${data.pkg}!${data.env}!${data.version}`; | ||
}; | ||
const model = dynamo.define('Status', { | ||
hashKey, | ||
timestamps: true, | ||
tableName: 'WrhsStatus', | ||
schema: { | ||
key: Joi.string(), | ||
pkg: Joi.string(), | ||
env: Joi.string(), | ||
version: Joi.string(), | ||
previousVersion: Joi.string(), | ||
total: Joi.number(), | ||
error: Joi.boolean(), | ||
complete: Joi.boolean() | ||
} | ||
}); | ||
return new Wrap(Status); | ||
return new AwaitWrap(new Dynastar({ model, createKey, hashKey })); | ||
}; |
@@ -9,4 +9,4 @@ const uuid = require('uuid'); | ||
total: 10, | ||
createDate: new Date(), | ||
updateDate: new Date(), | ||
createdAt: new Date(), | ||
updatedAt: new Date(), | ||
complete: false, | ||
@@ -22,4 +22,4 @@ error: false | ||
total: 10, | ||
createDate: new Date(), | ||
updateDate: new Date() | ||
createdAt: new Date(), | ||
updatedAt: new Date() | ||
}; | ||
@@ -26,0 +26,0 @@ |
@@ -1,6 +0,7 @@ | ||
const thenify = require('tinythen'); | ||
const Datastar = require('datastar'); | ||
const AWS = require('aws-sdk'); | ||
const dynamoObjectModel = require('dynamodb-x'); | ||
const assume = require('assume'); | ||
const statusModels = require('..'); | ||
const uuid = require('uuid'); | ||
const AwsLiveness = require('aws-liveness'); | ||
const modelsFactory = require('..'); | ||
@@ -12,5 +13,19 @@ const { StatusFixture, | ||
const datastar = new Datastar(require('./config')); | ||
const models = statusModels(datastar); | ||
/* eslint-disable no-process-env */ | ||
const dynamoEndpoint = process.env.DYNAMO_ENDPOINT || 'http://localhost:4569'; | ||
const dynamoRegion = process.env.AWS_REGION || 'us-west-2'; | ||
const dynamoApiVersion = process.env.DYNAMO_API_VERSION || '2012-08-10'; | ||
// Need to set some values for these so localstack works in Travis | ||
process.env.AWS_ACCESS_KEY_ID = 'foobar'; | ||
process.env.AWS_SECRET_ACCESS_KEY = 'foobar'; | ||
/* eslint-enable no-process-env */ | ||
const dynamoClient = new AWS.DynamoDB({ | ||
apiVersion: dynamoApiVersion, | ||
endpoint: dynamoEndpoint, | ||
region: dynamoRegion | ||
}); | ||
dynamoObjectModel.dynamoDriver(dynamoClient); | ||
const models = modelsFactory(dynamoObjectModel); | ||
const { Status, StatusHead, StatusCounter, StatusEvent } = models; | ||
@@ -24,4 +39,4 @@ | ||
assume(result.total).equals(fixture.total); | ||
assume(result.createDate).is.a('date'); | ||
assume(result.updateDate).is.a('date'); | ||
assume(Date.parse(result.createdAt)).is.truthy(); | ||
assume(Date.parse(result.updatedAt)).is.truthy(); | ||
if (result.complete) assume(result.complete).equals(fixture.complete); | ||
@@ -38,3 +53,3 @@ } | ||
assume(result.details).equals(fixture.details); | ||
assume(result.createDate).is.a('date'); | ||
assume(Date.parse(result.createdAt)).is.truthy(); | ||
assume(result.eventId).equals(fixture.eventId); | ||
@@ -53,17 +68,12 @@ } | ||
} | ||
describe('warehouse.ai-status-models (integration)', function () { | ||
this.timeout(6E4); | ||
before(async function () { | ||
if (process.env.DEBUG) { // eslint-disable-line no-process-env | ||
datastar.connection.on('queryStarted', function () { | ||
console.log.apply(console, arguments); // eslint-disable-line no-console | ||
}); | ||
} | ||
await thenify(datastar, 'connect'); | ||
const liveness = new AwsLiveness(); | ||
await liveness.waitForServices({ | ||
clients: [dynamoClient], | ||
waitSeconds: 60 | ||
}); | ||
}); | ||
after(async function () { | ||
await thenify(datastar, 'close'); | ||
}); | ||
describe('models', function () { | ||
@@ -98,11 +108,10 @@ it('should ensure and drop all models', async function () { | ||
it('should create, find, update and remove a status record', async function () { | ||
const key = { pkg: StatusFixture.pkg, env: StatusFixture.env, version: StatusFixture.version }; | ||
await Status.create(StatusFixture); | ||
const result = await Status.findOne(StatusFixture); | ||
assertStatus(result); | ||
const modified = { ...StatusFixture, complete: true }; | ||
const { pkg, env, version, complete } = modified; | ||
await Status.update({ pkg, env, version, complete }); | ||
const result2 = await Status.findOne({ pkg, env, version }); | ||
assertStatus(result2, modified); | ||
await Status.remove(modified); | ||
await Status.update({ ...key, complete: true }); | ||
const result2 = await Status.findOne({ ...key }); | ||
assertStatus(result2, { ...StatusFixture, complete: true }); | ||
await Status.remove({ ...key }); | ||
}); | ||
@@ -109,0 +118,0 @@ }); |
const assume = require('assume'); | ||
const ModelWrap = require('../wrap'); | ||
const models = require('..'); | ||
const { AwaitWrap } = require('dynastar'); | ||
const dynamodb = require('dynamodb-x'); | ||
const models = require('..')(dynamodb); | ||
const { mocks, helpers } = require('datastar-test-tools'); | ||
describe('warehouse.ai-status-models (unit)', function () { | ||
let dal; | ||
beforeEach(function () { | ||
const datastar = helpers.connectDatastar({ mock: true }, mocks.datastar()); | ||
dal = models(datastar); | ||
}); | ||
it('should return the appropriate object', function () { | ||
assume(dal.Status).is.instanceof(ModelWrap); | ||
assume(dal.StatusCounter).is.instanceof(ModelWrap); | ||
assume(dal.StatusEvent).is.instanceof(ModelWrap); | ||
assume(dal.StatusHead).is.instanceof(ModelWrap); | ||
assume(models.Status).is.instanceof(AwaitWrap); | ||
assume(models.StatusCounter).is.instanceof(AwaitWrap); | ||
assume(models.StatusEvent).is.instanceof(AwaitWrap); | ||
assume(models.StatusHead).is.instanceof(AwaitWrap); | ||
}); | ||
it('should have an ensure and drop functions', function () { | ||
assume(dal.ensure).is.a('function'); | ||
assume(dal.drop).is.a('function'); | ||
assume(models.ensure).is.a('function'); | ||
assume(models.drop).is.a('function'); | ||
}); | ||
it('StatusCounter model should have increment function', function () { | ||
assume(dal.StatusCounter.increment).is.an('asyncfunction'); | ||
it('StatusCounter model should have increment and decrement function', function () { | ||
assume(models.StatusCounter.increment).is.an('asyncfunction'); | ||
assume(models.StatusCounter.decrement).is.an('asyncfunction'); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 5 instances in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
33402
23
107
3
11
1
70
480
5
+ Addeddynastar@^1.0.0
+ Addedjoi@^14.3.1
+ Addeddynastar@1.3.1(transitive)
+ Addedhoek@6.1.3(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedisemail@3.2.0(transitive)
+ Addedjoi@14.3.1(transitive)
+ Addedlist-stream@2.1.0(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedreadable-stream@3.4.0(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedstring_decoder@1.3.0(transitive)
+ Addedthrough2@3.0.2(transitive)
+ Addedtopo@3.0.3(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
+ Addedwrappy@1.0.2(transitive)