Schema-based slug plugin for Mongoose - single/compound - unique over collection/group - nested docs/arrays - relative/abs paths - sync on change: create/save/update/updateOne/updateMany/findOneAndUpdate tracked - $set operator - counter/shortId
Installations
npm install mongoose-slug-updater
Developer Guide
Typescript
No
Module System
CommonJS
Min. Node Version
>= 8.3.0
Node Version
14.0.0
NPM Version
6.14.8
Score
78.8
Supply Chain
100
Quality
76
Maintenance
100
Vulnerability
98.9
License
Releases
Unable to fetch releases
Contributors
Unable to fetch Contributors
Languages
JavaScript (100%)
Developer
YuriGor
Download Statistics
Total Downloads
487,128
Last Day
357
Last Week
1,681
Last Month
7,918
Last Year
91,984
GitHub Statistics
40 Stars
142 Commits
13 Forks
1 Watching
5 Branches
8 Contributors
Bundle Size
109.58 kB
Minified
38.17 kB
Minified + Gzipped
Package Meta Information
Latest Version
3.3.0
Package Id
mongoose-slug-updater@3.3.0
Unpacked Size
276.17 kB
Size
41.52 kB
File Count
44
NPM Version
6.14.8
Node Version
14.0.0
Total Downloads
Cumulative downloads
Total Downloads
487,128
Last day
-9.6%
357
Compared to previous day
Last week
-22.6%
1,681
Compared to previous week
Last month
7.7%
7,918
Compared to previous month
Last year
-7.7%
91,984
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
mongoose-slug-updater
Sophisticated slugifier plugin for Mongoose.
Features:
- Intuitive schema-based declaration
- Single or compound slugs, based on any fields of the document
- Nested docs and arrays support
- Relative or absolute paths to the related fields
- Initial generation and updating (or not if permanent) on any change of related fields,
create
,save
,update
,updateOne
,updateMany
orfindOneAndUpdate
methods supported, and you can switch them on/off.- $set update operator support with deep modification paths to any nested doc or array.
- Unique slugs (with unique index or not), collection-wide or by group, nested too.
- Updating of unique slugs in case of changed related fields or group criteria.
- Counter and shortId styles of duplication conflict resolving.
- Autoloading of missing related data required to build slug correctly.
Installation
The best way to install it is using npm
1npm install mongoose-slug-updater --save
Loading
1var slug = require('mongoose-slug-updater');
Initialization
1var mongoose = require('mongoose'); 2mongoose.plugin(slug);
Usage
This plugin is based on the idea of using the mongoose schema as the way to check the use of slug fields.
The plugin checks and updates automatically the slug field with the correct slug.
Basic Usage
If you only want to create the slug based on a simple field.
1var mongoose = require('mongoose'), 2 slug = require('mongoose-slug-updater'), 3 mongoose.plugin(slug), 4 Schema = mongoose.Schema, 5 schema = new Schema({ 6 title: String, 7 slug: { type: String, slug: "title" } 8});
Multiple slug fields
You can add as many slug fields as you wish
1var mongoose = require('mongoose'), 2 slug = require('mongoose-slug-updater'), 3 mongoose.plugin(slug), 4 Schema = mongoose.Schema, 5 schema = new Schema({ 6 title: String, 7 subtitle: String, 8 slug: { type: String, slug: "title" }, 9 slug2: { type: String, slug: "title" }, 10 slug3: { type: String, slug: "subtitle" } 11});
Multiple fields to create the slug
If you want, you can use more than one field in order to create a new slug field.
1var mongoose = require('mongoose'), 2 slug = require('mongoose-slug-updater'), 3 mongoose.plugin(slug), 4 Schema = mongoose.Schema, 5 schema = new Schema({ 6 title: String, 7 subtitle: String, 8 slug: { type: String, slug: ["title", "subtitle"] } 9});
Transform Slug
This option accepts a funtion which receives actual field value and can be used to tranform value before generating slug.
1var mongoose = require('mongoose'), 2 slug = require('mongoose-slug-updater'), 3 mongoose.plugin(slug), 4 Schema = mongoose.Schema, 5 schema = new Schema({ 6 title: String, 7 subtitle: String, 8 slug: { type: String, slug: ["title", "subtitle"], transform: v => stripHtmlTags(v) } 9});
Unique slug field
To create a unique slug field, you must only add add the unique: true parameter in the path (also, this way the default mongo unique index gets created)
1var mongoose = require('mongoose'), 2 slug = require('mongoose-slug-updater'), 3 mongoose.plugin(slug), 4 Schema = mongoose.Schema, 5 schema = new Schema({ 6 title: String, 7 subtitle: String, 8 slug: { type: String, slug: ["title", "subtitle"], unique: true } 9});
If unique
or uniqueSlug
is set, the plugin searches in the mongo database, and if the slug already exists in the collection, it appends to the slug a separator (default: "-") and a random string (generated with the shortid module).
example random
1mongoose.model('Resource').create({ 2 title: "Am I wrong, fallin' in love with you!", 3 subtitle: "tell me am I wrong, well, fallin' in love with you", 4}); // slug -> 'am-i-wrong-fallin-in-love-with-you' 5 6mongoose.model('Resource').create({ 7 title: "Am I wrong, fallin' in love with you!", 8 subtitle: "tell me am I wrong, well, fallin' in love with you", 9}); // slug -> 'am-i-wrong-fallin-in-love-with-you-Nyiy4wW9l' 10 11mongoose.model('Resource').create({ 12 title: "Am I wrong, fallin' in love with you!", 13 subtitle: "tell me am I wrong, well, fallin' in love with you", 14}); // slug -> 'am-i-wrong-fallin-in-love-with-you-NJeskEPb5e'
Alternatively you can modify this behaviour and instead of appending a random string, an incremental counter will be used. For that to happen, you must use the parameter slugPaddingSize
specifying the total length of the counter:
example counter
1var mongoose = require('mongoose'), 2 slug = require('mongoose-slug-updater'), 3 mongoose.plugin(slug), 4 Schema = mongoose.Schema, 5 schema = new Schema({ 6 title: String, 7 subtitle: String, 8 slug: { type: String, slug: ["title", "subtitle"], slugPaddingSize: 4, unique: true } 9}); 10 11mongoose.model('Resource').create({ 12 title: 'Am I wrong, fallin\' in love with you!', 13 subtitle: "tell me am I wrong, well, fallin' in love with you" 14}) // slug -> 'am-i-wrong-fallin-in-love-with-you' 15 16mongoose.model('Resource').create({ 17 title: 'Am I wrong, fallin\' in love with you!', 18 subtitle: "tell me am I wrong, well, fallin' in love with you" 19}) // slug -> 'am-i-wrong-fallin-in-love-with-you-0001' 20 21mongoose.model('Resource').create({ 22 title: 'Am I wrong, fallin\' in love with you!', 23 subtitle: "tell me am I wrong, well, fallin' in love with you" 24}) // slug -> 'am-i-wrong-fallin-in-love-with-you-0002'
If you don't want to define your field as unique for some reasons, but still need slug to be unique,
you can use uniqueSlug:true
option instead of unique
.
This option will not cause index creation, but still will be considered by the plugin.
forceIdSlug
option will append shortId even if no duplicates were found.
This is useful for applications with high chance of concurrent modification of unique fields.
Check for conflict made by plugin is not atomic with subsequent insert/update operation,
so there is a possibility of external change of data in the moment between check and write.
If this happened, mongo will throw unique index violation error.
Chances of such case higher for counter unique mode, but with shortId this is possible too.
You can just retry operation, so plugin will check collection again and regenerate correct unique slug.
Or you can set forceIdSlug
option - this will solve the problem completely, but you will pay for this by less readabilty of your slugs, because they will always be appended with random string.
In most cases write operations not so frequent to care about possible conflicts.
note: forceIdSlug
option will also overwite unique
to the true
, and slugPaddingSize
option will be ignored.
Unique slug within a group
Sometimes you only want slugs to be unique within a specific group.
This is done with the uniqueGroupSlug
property which is an array of fields to group by:
example unique per group (using the field named 'group')
1ResourceGroupedUnique = new mongoose.Schema({ 2 title: { type: String }, 3 subtitle: { type: String }, 4 group: { type: String }, 5 uniqueSlug: { 6 type: String, 7 uniqueGroupSlug: ['group'], 8 slugPaddingSize: 4, 9 slug: 'title', 10 index: true, 11 }, 12}); 13 14mongoose.model('ResourceGroupedUnique').create({ 15 title: "Am I wrong, fallin' in love with you!", 16 subtitle: "tell me am I wrong, well, fallin' in love with you", 17 group: 'group 1', 18}); // slug -> 'am-i-wrong-fallin-in-love-with-you' 19 20mongoose.model('ResourceGroupedUnique').create({ 21 title: "Am I wrong, fallin' in love with you!", 22 subtitle: "tell me am I wrong, well, fallin' in love with you", 23 group: 'group 2', 24}); // slug -> 'am-i-wrong-fallin-in-love-with-you' 25 26mongoose.model('ResourceGroupedUnique').create({ 27 title: "Am I wrong, fallin' in love with you!", 28 subtitle: "tell me am I wrong, well, fallin' in love with you", 29 group: 'group 1', 30}); // slug -> 'am-i-wrong-fallin-in-love-with-you-0001' 31 32mongoose.model('ResourceGroupedUnique').create({ 33 title: "Am I wrong, fallin' in love with you!", 34 subtitle: "tell me am I wrong, well, fallin' in love with you", 35 group: 'group 2', 36}); // slug -> 'am-i-wrong-fallin-in-love-with-you-0001'
Important: you must not have a unique: true
option, but it's a good idea to have an index: true
option.
Nested unique slugs
MongoDB supports unique index for nested arrays elements, but he checks for duplication conflicts only on per-document basis, so inside document duplicate nested array's elements are still allowed.
mongoose-slug-updater works differently. It checks slug for duplicates both in current documentts's nested array and in other documents, considering uniqueGroupSlug option, if specified.
example of nested unique slugs
1const UniqueNestedSchema = new mongoose.Schema({ 2 children: [ 3 { 4 subchildren: [ 5 { 6 title: { type: String }, 7 slug: { 8 type: String, 9 slug: 'title', 10 unique: true // 'global' unique slug 11 slugPaddingSize: 4, 12 }, 13 slugLocal: { 14 type: String, 15 slug: 'title', 16 index: true, 17 slugPaddingSize: 4, 18 uniqueGroupSlug: '/_id',// slug unique within current document 19 }, 20 }, 21 ], 22 }, 23 ], 24});
1mongoose.model('UniqueNestedSchema').create({ 2 children:[ 3 { 4 subchildren:[ 5 { 6 title: "Am I wrong, fallin' in love with you!" 7 // slug -> 'am-i-wrong-fallin-in-love-with-you' 8 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you' 9 }, 10 { 11 title: "Am I wrong, fallin' in love with you!" 12 // slug -> 'am-i-wrong-fallin-in-love-with-you-0001' 13 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you-0001' 14 }, 15 ] 16 }, 17 { 18 subchildren:[ 19 { 20 title: "Am I wrong, fallin' in love with you!" 21 // slug -> 'am-i-wrong-fallin-in-love-with-you-0002' 22 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you-0002' 23 }, 24 { 25 title: "Am I wrong, fallin' in love with you!" 26 // slug -> 'am-i-wrong-fallin-in-love-with-you-0003' 27 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you-0003' 28 }, 29 ] 30 }, 31 ] 32}); 33mongoose.model('UniqueNestedSchema').create({ 34 children:[ 35 { 36 subchildren:[ 37 { 38 title: "Am I wrong, fallin' in love with you!" 39 // slug -> 'am-i-wrong-fallin-in-love-with-you-0004' 40 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you' 41 }, 42 { 43 title: "Am I wrong, fallin' in love with you!" 44 // slug -> 'am-i-wrong-fallin-in-love-with-you-0005' 45 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you-0001' 46 }, 47 ] 48 }, 49 { 50 subchildren:[ 51 { 52 title: "Am I wrong, fallin' in love with you!" 53 // slug -> 'am-i-wrong-fallin-in-love-with-you-0006' 54 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you-0002' 55 }, 56 { 57 title: "Am I wrong, fallin' in love with you!" 58 // slug -> 'am-i-wrong-fallin-in-love-with-you-0007' 59 // slugLocal -> 'am-i-wrong-fallin-in-love-with-you-0003' 60 }, 61 ] 62 }, 63 ] 64});
In case of change unique slug related fields (source fields from slug
option or group criteria from uniqueGroupSlug
)
slug will be regenerated considering latest existing duplicate. Presence or lack of the older duplicates, including original slug, will not be taken into account.
Updating slug or keeping it permanent
By default slugs will be created/updated for any related fields changed by any of create
(it's actually a save
too), save
, update
, updateOne
, updateMany
and findOneAndUpdate
operations.
You can specify which of supported methods should be watched:
1const HooksSchema = new mongoose.Schema({
2 title: { type: String },
3 slug: {
4 type: String,
5 slug: 'title',
6 //by default all hooks are enabled
7 //slugOn:{ save: true, update: true, updateOne: true, updateMany: true, findOneAndUpdate: true }
8 },
9 slugNoSave: { type: String, slug: 'title', slugOn: { save: false } },
10 slugNoUpdate: { type: String, slug: 'title', slugOn: { update: false } },
11 slugNoUpdateOne: { type: String, slug: 'title', slugOn: { updateOne: false } },
12 slugNoUpdateMany: {
13 type: String,
14 slug: 'title',
15 slugOn: { updateMany: false },
16 },
17 slugNoFindOneAndUpdate: {
18 type: String,
19 slug: 'title',
20 slugOn: { findOneAndUpdate: false },
21 },
22});
Note, that flags will affect both creation and updating of documents.
If you disabled save
and still want slug to be generated initially, create
method will not work,
becacuse mongoose emits save
event both for save
and create
methods.
Use upsert
option of update***
methods instead.
For update
and updateMany
methods multiply affected records also handled, but be careful with performance,
because one-by-one iteration over affected documents may happen in case of unique slugs.
In this case _id
field is required.
For update*
family of operations additional queries may be performed, to retrieve data missing in the query (fields not listed in the query but needed for compound or grouped unique slugs).
permanent
option
If you want to generate slug initially, but keep it unchanged during further modifications of related fields, use permanent
flag like this:
1ResourcePermanent = new mongoose.Schema({ 2 title: { type: String }, 3 subtitle: { type: String }, 4 otherField: { type: String }, 5 slug: { type: String, slug: ['title', 'subtitle'] }, //normal slug 6 titleSlug: { type: String, slug: 'title', permanent: true }, //permanent slug 7 subtitleSlug: { 8 type: String, 9 slug: 'subtitle', 10 permanent: true, //permanent option 11 slugPaddingSize: 4, 12 }, 13});
Nested docs. Relative and absolute paths.
Nested docs and arrays declared inline right in the scheme or as a nested schemas declared separately are also supported.
Slug fields can be declared as relative or absolute(starting with slash) path to any point of current document.
Since MongoDB uses dot path notation, colon :
symbol used for relative paths as a reference to the parent, same as double dot ..
for file system paths.
Example of scheme with inline nested docs:
1const InlineSchema = new mongoose.Schema({ 2 // root title 3 title: { type: String }, 4 // root slug with relative path to root title 5 slug: { type: String, slug: 'title' }, 6 // root slug with absolute path to root title 7 absoluteSlug: { type: String, slug: '/title' }, 8 // root slug with relative path to child title 9 childSlug: { type: String, slug: 'child.title' }, 10 // root slug with absolute path to child title 11 absoluteChildSlug: { type: String, slug: '/child.title' }, 12 // root slug with relative path to child's subchild title 13 subChildSlug: { type: String, slug: 'child.subChild.title' }, 14 // root slug with relative path to the title of first children array element 15 childrenSlug0: { type: String, slug: 'children.0.title' }, 16 // root slug with relative path to the title of 5th children array element 17 childrenSlug4: { type: String, slug: 'children.4.title' }, 18 // root slug with relative path to the title of 4th subChildren' element of first children array element 19 subChildrenSlug3: { type: String, slug: 'children.0.subChildren.3.title' }, 20 // root slug with relative path to the title of 8th subChildren' element of first children array element 21 subChildrenSlug7: { type: String, slug: 'children.0.subChildren.7.title' }, 22 subChildrenSlug5SubChild: { 23 type: String, 24 // well, you see) 25 slug: 'children.0.subChildren.5.subChild.title', 26 }, 27 subChildrenSlug2SubChild: { 28 type: String, 29 slug: 'children.0.subChildren.2.subChild.title', 30 }, 31 child: { 32 title: { type: String }, 33 // inside nested doc relative path starts from current object, 34 // so this is slug for child's title 35 slug: { type: String, slug: 'title' }, 36 // absolute variant of path above, starting from root 37 absoluteSlug: { type: String, slug: '/child.title' }, 38 // child's slug field generated for root title, absolute path 39 absoluteParentSlug: { type: String, slug: '/title' }, 40 // relative path with parent reference `:`, so here root title will be used again. 41 relativeParentSlug: { type: String, slug: ':title' }, 42 subChild: { 43 title: { type: String }, 44 // relative path to the title of current nested doc, 45 // in absolute form it wil be /child.subChild.title 46 slug: { type: String, slug: 'title' }, 47 // absolute path to the root title 48 absoluteParentSlug: { type: String, slug: '/title' }, 49 // relative path to the parent title, /child.title in this case 50 relativeParentSlug: { type: String, slug: ':title' }, 51 // parent of the parent is root, so ::title = /title here 52 relativeGrandParentSlug: { type: String, slug: '::title' }, 53 }, 54 }, 55 // nested arrays work too 56 children: [ 57 { 58 title: { type: String }, 59 // title of current array element 60 slug: { type: String, slug: 'title' }, 61 // root title 62 absoluteRootSlug: { type: String, slug: '/title' }, 63 // child's title 64 absoluteChildSlug: { type: String, slug: '/child.title' }, 65 // root title. Array itself not counted as a parent and skipped. 66 relativeRootSlug: { type: String, slug: ':title' }, 67 // absolute path to 4th element of array 68 absoluteSiblingSlug: { type: String, slug: '/children.3.title' }, 69 // same in relative form for 5th element 70 relativeSiblingSlug: { type: String, slug: ':children.4.title' }, 71 subChild: { 72 title: { type: String }, 73 // current title 74 slug: { type: String, slug: 'title' }, 75 // root title 76 absoluteParentSlug: { type: String, slug: '/title' }, 77 // child title 78 absoluteChildSlug: { type: String, slug: '/child.title' }, 79 // title of current array element, because its a parent of this subChild 80 relativeParentSlug: { type: String, slug: ':title' }, 81 // two parents up is a root 82 relativeGrandParentSlug: { type: String, slug: '::title' }, 83 }, 84 // arrays nested into array elements, welcome to the depth 85 subChildren: [ 86 { 87 title: { type: String }, 88 // current title 89 slug: { type: String, slug: 'title' }, 90 // root title 91 absoluteRootSlug: { type: String, slug: '/title' }, 92 // child title 93 absoluteChildSlug: { type: String, slug: '/child.title' }, 94 // :--> children :--> root 95 relativeRootSlug: { type: String, slug: '::title' }, 96 absoluteSiblingSlug: { 97 type: String, 98 // I don't know who will need it but it works, check yourself in /test 99 slug: '/children.0.subChildren.5.title', 100 }, 101 // relative ref to another subChildren's element from current children's element 102 relativeSiblingSlug: { type: String, slug: ':subChildren.6.title' }, 103 // hope you got it. 104 subChild: { 105 title: { type: String }, 106 slug: { type: String, slug: 'title' }, 107 absoluteParentSlug: { type: String, slug: '/title' }, 108 absoluteChildSlug: { type: String, slug: '/child.title' }, 109 relativeParentSlug: { type: String, slug: ':title' }, 110 relativeGrandParentSlug: { type: String, slug: '::title' }, 111 }, 112 }, 113 ], 114 }, 115 ], 116});
Example of nested schemas declared separately:
1const SubChildSchema = new mongoose.Schema({
2 title: { type: String },
3 slug: { type: String, slug: 'title' },
4 absoluteRootSlug: { type: String, slug: '/title' },
5 absoluteChildSlug: { type: String, slug: '/child.title' },
6 relativeParentSlug: { type: String, slug: ':title' },// child's title
7 relativeGrandParentSlug: { type: String, slug: '::title' },//parent's title
8});
9
10const ChildSchema = new mongoose.Schema({
11 title: { type: String },
12 subChild: SubChildSchema,
13 subChildren: [SubChildSchema],
14 slug: { type: String, slug: 'title' },
15 subChildSlug: { type: String, slug: 'subChild.title' },
16 absoluteSlug: { type: String, slug: '/child.title' },
17 absoluteRootSlug: { type: String, slug: '/title' },
18 relativeParentSlug: { type: String, slug: ':title' },//Parent
19 subChildrenSlug2: { type: String, slug: 'subChildren.2.title' },
20 subChildrenSlug3: { type: String, slug: 'subChildren.3.title' },
21});
22
23const ParentSchema = new mongoose.Schema({
24 title: { type: String },
25 child: ChildSchema,
26 children: [ChildSchema],
27 slug: { type: String, slug: 'title' },
28 absoluteSlug: { type: String, slug: '/title' },
29 childSlug: { type: String, slug: 'child.title' },
30 absoluteChildSlug: { type: String, slug: '/child.title' },
31 subChildSlug: { type: String, slug: 'child.subChild.title' },
32 childrenSlug0: { type: String, slug: 'children.0.title' },
33 childrenSlug4: { type: String, slug: 'children.4.title' },
34 subChildrenSlug3: { type: String, slug: 'children.7.subChildren.3.title' },
35 subChildrenSlug7: { type: String, slug: 'children.3.subChildren.7.title' },
36});
Updating by deep path via $set operator
This will work too:
1 await SimpleInline.findOneAndUpdate(
2 {/*some criteria*/},
3 {
4 $set: {
5 title: 'New root title',
6 'child.title': 'New nested title',
7 'children.2.title': 'New title for the 3d item of nested array',
8 },
9 }
10 );
All the slugs which depend on modified titles will be found and regenerated.
This is recommended way to do partial modifications.
When you perform updates by object value instead of path:value list,
unobvious data loss may happen for nested docs or arrays, if they contain slugs affected by your modification.
Plugin always checks will current update operation be made with $set operator or not, and adds extra slug fields to the query as an object fields or $set paths accordingly.
So if you do have whole document you want to change - better use save
,
but if you dont have it, but you need to update some particular fields - it's more safe to use $set and paths:values.
Choose your own options
You can change any options adding to the plugin
1var mongoose = require('mongoose'), 2 slug = require('mongoose-slug-updater'), 3 options = { 4 separator: "-", 5 lang: "en", 6 truncate: 120, 7 backwardCompatible: true//support for the old options names used in the mongoose-slug-generator 8 }, 9 mongoose.plugin(slug, options), 10 Schema = mongoose.Schema, 11 schema = new Schema({ 12 title: String, 13 subtitle: String, 14 slug: { type: String, slug: ["title", "subtitle"], unique: true } 15});
You can find more options in the speakingURL's npm page
Support
This plugin is supported by Yuri Gor
About
This plugin was initially forked from mongoose-slug-generator, which is not maintained currently.
Merged and fixed uniqueGroupSlug
feature by rickogden.
update
, updateOne
, updateMany
and findOneAndUpdate
operations support implemented.
Nested docs and arrays support implemented.
Absolute and relative paths added.
Updating with $set operator and deep paths now works too.
All the update operators will be implemented soon.
Plugin rewritten with modern js and a lot of tests were added.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 4/24 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 10 are checked with a SAST tool
Score
3.2
/10
Last Scanned on 2025-02-03
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More