promptgraph-mcp 2.4.7 → 2.5.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/README.md +3 -6
- package/ann.js +23 -51
- package/api.js +200 -0
- package/config.js +14 -0
- package/db.js +48 -0
- package/embedder.js +10 -0
- package/github-import.js +167 -27
- package/indexer.js +49 -12
- package/marketplace.js +130 -7
- package/package.json +9 -3
- package/search.js +86 -20
- package/src/filter/hard-filter.js +2 -0
- package/src/filter/train.js +3 -1
- package/src/reranker/reranker.js +27 -0
- package/src/store/flat-store.js +61 -0
- package/src/store/hnsw-store.js +187 -0
- package/src/store/index.js +19 -0
- package/src/store/vector-store.js +9 -0
- package/src/utils/rate-limiter.js +33 -0
- package/validator.js +31 -1
- package/registry/training/bad/accepts-HISTORY.md +0 -250
- package/registry/training/bad/argparse-CHANGELOG.md +0 -185
- package/registry/training/bad/balanced-match-LICENSE.md +0 -23
- package/registry/training/bad/better-sqlite3-README.md +0 -99
- package/registry/training/bad/bindings-LICENSE.md +0 -22
- package/registry/training/bad/bl-LICENSE.md +0 -13
- package/registry/training/bad/body-parser-README.md +0 -494
- package/registry/training/bad/bytes-HISTORY.md +0 -97
- package/registry/training/bad/camelcase-README.md +0 -135
- package/registry/training/bad/chai-README.md +0 -162
- package/registry/training/bad/cli-progress-LICENSE.md +0 -24
- package/registry/training/bad/content-type-HISTORY.md +0 -29
- package/registry/training/bad/cookie-SECURITY.md +0 -25
- package/registry/training/bad/cookie-signature-HISTORY.md +0 -70
- package/registry/training/bad/cors-README.md +0 -277
- package/registry/training/bad/cross-spawn-README.md +0 -89
- package/registry/training/bad/deep-extend-CHANGELOG.md +0 -46
- package/registry/training/bad/depd-HISTORY.md +0 -103
- package/registry/training/bad/esprima-README.md +0 -46
- package/registry/training/bad/etag-HISTORY.md +0 -83
- package/registry/training/bad/expect-type-SECURITY.md +0 -14
- package/registry/training/bad/finalhandler-HISTORY.md +0 -239
- package/registry/training/bad/fresh-HISTORY.md +0 -80
- package/registry/training/bad/glob-LICENSE.md +0 -63
- package/registry/training/bad/hono-README.md +0 -85
- package/registry/training/bad/http-errors-HISTORY.md +0 -186
- package/registry/training/bad/jose-LICENSE.md +0 -21
- package/registry/training/bad/jose-README.md +0 -153
- package/registry/training/bad/js-yaml-README.md +0 -299
- package/registry/training/bad/json-schema-typed-LICENSE.md +0 -57
- package/registry/training/bad/json-stringify-safe-CHANGELOG.md +0 -14
- package/registry/training/bad/lru-cache-LICENSE.md +0 -55
- package/registry/training/bad/media-typer-HISTORY.md +0 -50
- package/registry/training/bad/minimatch-LICENSE.md +0 -55
- package/registry/training/bad/minimist-CHANGELOG.md +0 -298
- package/registry/training/bad/minimist-README.md +0 -121
- package/registry/training/bad/ms-LICENSE.md +0 -21
- package/registry/training/bad/negotiator-HISTORY.md +0 -114
- package/registry/training/bad/on-finished-HISTORY.md +0 -98
- package/registry/training/bad/pkce-challenge-CHANGELOG.md +0 -114
- package/registry/training/bad/postcss-README.md +0 -28
- package/registry/training/bad/prebuild-install-CHANGELOG.md +0 -131
- package/registry/training/bad/proxy-addr-HISTORY.md +0 -161
- package/registry/training/bad/qs-CHANGELOG.md +0 -822
- package/registry/training/bad/rc-README.md +0 -227
- package/registry/training/bad/readable-stream-CONTRIBUTING.md +0 -38
- package/registry/training/bad/router-HISTORY.md +0 -228
- package/registry/training/bad/semver-README.md +0 -680
- package/registry/training/bad/send-README.md +0 -317
- package/registry/training/bad/serve-static-README.md +0 -253
- package/registry/training/bad/statuses-HISTORY.md +0 -87
- package/registry/training/bad/type-is-HISTORY.md +0 -292
- package/registry/training/bad/vary-HISTORY.md +0 -39
- package/registry/training/bad/vite-LICENSE.md +0 -2230
- package/registry/training/bad/which-CHANGELOG.md +0 -166
- package/registry/training/bad/zod-README.md +0 -191
- package/registry/training/good/skills-store-autopilot.md +0 -85
- package/registry/training/good/skills-store-bot-builder.md +0 -70
- package/registry/training/good/skills-store-chain.md +0 -136
- package/registry/training/good/skills-store-evolve.md +0 -100
- package/registry/training/good/skills-store-game.md +0 -27
- package/registry/training/good/skills-store-hunt.md +0 -102
- package/registry/training/good/skills-store-intel.md +0 -56
- package/registry/training/good/skills-store-memory-gc.md +0 -58
- package/registry/training/good/skills-store-pcsort.md +0 -207
- package/registry/training/good/skills-store-pickup.md +0 -60
- package/registry/training/good/skills-store-recon.md +0 -141
- package/registry/training/good/skills-store-remember.md +0 -64
- package/registry/training/good/skills-store-report.md +0 -117
- package/registry/training/good/skills-store-router.md +0 -225
- package/registry/training/good/skills-store-search.md +0 -168
- package/registry/training/good/skills-store-surface.md +0 -53
- package/registry/training/good/skills-store-token-scan.md +0 -141
- package/registry/training/good/skills-store-triage.md +0 -97
- package/registry/training/good/skills-store-unity.md +0 -733
- package/registry/training/good/skills-store-validate.md +0 -135
- package/registry/training/good/skills-store-web3-audit.md +0 -217
- package/src/filter/cluster.js +0 -52
- package/src/filter/dedup.js +0 -36
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { VectorStore } from './vector-store.js';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
const DIMS = 384;
|
|
6
|
+
const EF_SEARCH = 100;
|
|
7
|
+
|
|
8
|
+
let HierarchicalNSW = null;
|
|
9
|
+
let moduleError = null;
|
|
10
|
+
|
|
11
|
+
async function getHnswModule() {
|
|
12
|
+
if (HierarchicalNSW) return HierarchicalNSW;
|
|
13
|
+
if (moduleError) throw moduleError;
|
|
14
|
+
try {
|
|
15
|
+
const mod = await import('hnswlib-node');
|
|
16
|
+
HierarchicalNSW = mod.default.HierarchicalNSW;
|
|
17
|
+
return HierarchicalNSW;
|
|
18
|
+
} catch (e) {
|
|
19
|
+
moduleError = new Error(
|
|
20
|
+
'hnswlib-node not available. Run: npm install hnswlib-node'
|
|
21
|
+
);
|
|
22
|
+
throw moduleError;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function toArray(v) {
|
|
27
|
+
return Array.from(v);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class HNSWVectorStore extends VectorStore {
|
|
31
|
+
constructor() {
|
|
32
|
+
super();
|
|
33
|
+
this._index = null;
|
|
34
|
+
this._vectors = [];
|
|
35
|
+
this._idMap = [];
|
|
36
|
+
this._itemCount = 0;
|
|
37
|
+
this._maxElements = 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async add(id, vector) {
|
|
41
|
+
const HNSW = await getHnswModule();
|
|
42
|
+
const vec = toArray(vector);
|
|
43
|
+
if (!this._index) {
|
|
44
|
+
this._maxElements = 10000;
|
|
45
|
+
this._index = new HNSW('cosine', DIMS);
|
|
46
|
+
this._index.initIndex(this._maxElements, 200);
|
|
47
|
+
}
|
|
48
|
+
if (this._itemCount >= this._maxElements) {
|
|
49
|
+
await this._rebuild(this._maxElements * 2);
|
|
50
|
+
}
|
|
51
|
+
this._index.addPoint(vec, this._itemCount);
|
|
52
|
+
this._vectors.push(vec);
|
|
53
|
+
this._idMap.push(id);
|
|
54
|
+
this._itemCount++;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async addBatch(entries) {
|
|
58
|
+
for (const { id, vector } of entries) {
|
|
59
|
+
await this.add(id, vector);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async remove(id) {
|
|
64
|
+
const remainingVectors = [];
|
|
65
|
+
const remainingIds = [];
|
|
66
|
+
for (let i = 0; i < this._itemCount; i++) {
|
|
67
|
+
if (this._idMap[i] !== id) {
|
|
68
|
+
remainingVectors.push(this._vectors[i]);
|
|
69
|
+
remainingIds.push(this._idMap[i]);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this._index = null;
|
|
73
|
+
this._vectors = remainingVectors;
|
|
74
|
+
this._idMap = remainingIds;
|
|
75
|
+
this._itemCount = remainingVectors.length;
|
|
76
|
+
this._maxElements = 0;
|
|
77
|
+
if (this._itemCount > 0) {
|
|
78
|
+
await this._rebuild(this._itemCount + 1000);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async search(vector, topK = 20) {
|
|
83
|
+
await getHnswModule();
|
|
84
|
+
if (!this._index || this._itemCount === 0) return [];
|
|
85
|
+
|
|
86
|
+
const efSearch = Math.max(topK * 4, EF_SEARCH);
|
|
87
|
+
this._index.setEf(efSearch);
|
|
88
|
+
|
|
89
|
+
const numCandidates = Math.min(topK * 8, this._itemCount);
|
|
90
|
+
const result = this._index.searchKnn(toArray(vector), numCandidates);
|
|
91
|
+
|
|
92
|
+
const bestBySkill = new Map();
|
|
93
|
+
const neighbors = result.neighbors;
|
|
94
|
+
const distances = result.distances;
|
|
95
|
+
for (let i = 0; i < neighbors.length; i++) {
|
|
96
|
+
const idx = neighbors[i];
|
|
97
|
+
const score = 1 - distances[i];
|
|
98
|
+
const skillId = this._idMap[idx];
|
|
99
|
+
const prev = bestBySkill.get(skillId);
|
|
100
|
+
if (!prev || score > prev) bestBySkill.set(skillId, score);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return [...bestBySkill.entries()]
|
|
104
|
+
.sort((a, b) => b[1] - a[1])
|
|
105
|
+
.slice(0, topK)
|
|
106
|
+
.map(([skill_id, score]) => ({ skill_id, score }));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async build(entries) {
|
|
110
|
+
const HNSW = await getHnswModule();
|
|
111
|
+
const count = entries.length;
|
|
112
|
+
|
|
113
|
+
this._vectors = [];
|
|
114
|
+
this._idMap = [];
|
|
115
|
+
this._itemCount = 0;
|
|
116
|
+
this._maxElements = 0;
|
|
117
|
+
this._index = null;
|
|
118
|
+
|
|
119
|
+
if (count === 0) return;
|
|
120
|
+
|
|
121
|
+
this._maxElements = count + 1000;
|
|
122
|
+
this._index = new HNSW('cosine', DIMS);
|
|
123
|
+
this._index.initIndex(this._maxElements, 200);
|
|
124
|
+
|
|
125
|
+
for (let i = 0; i < count; i++) {
|
|
126
|
+
const { skill_id, vector } = entries[i];
|
|
127
|
+
const vec = toArray(vector);
|
|
128
|
+
this._index.addPoint(vec, i);
|
|
129
|
+
this._vectors.push(vec);
|
|
130
|
+
this._idMap.push(skill_id);
|
|
131
|
+
this._itemCount++;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async clear() {
|
|
136
|
+
this._index = null;
|
|
137
|
+
this._vectors = [];
|
|
138
|
+
this._idMap = [];
|
|
139
|
+
this._itemCount = 0;
|
|
140
|
+
this._maxElements = 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
get size() {
|
|
144
|
+
return this._itemCount;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async save(dir) {
|
|
148
|
+
const HNSW = await getHnswModule();
|
|
149
|
+
if (!this._index) return;
|
|
150
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
151
|
+
this._index.writeIndexSync(path.join(dir, 'index.bin'));
|
|
152
|
+
fs.writeFileSync(path.join(dir, 'vectors.json'), JSON.stringify(this._vectors), 'utf8');
|
|
153
|
+
fs.writeFileSync(path.join(dir, 'idmap.json'), JSON.stringify(this._idMap), 'utf8');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async load(dir) {
|
|
157
|
+
const HNSW = await getHnswModule();
|
|
158
|
+
const indexPath = path.join(dir, 'index.bin');
|
|
159
|
+
const vectorsPath = path.join(dir, 'vectors.json');
|
|
160
|
+
const idmapPath = path.join(dir, 'idmap.json');
|
|
161
|
+
if (!fs.existsSync(indexPath)) return false;
|
|
162
|
+
|
|
163
|
+
this._index = new HNSW('cosine', DIMS);
|
|
164
|
+
this._index.readIndexSync(indexPath);
|
|
165
|
+
this._vectors = JSON.parse(fs.readFileSync(vectorsPath, 'utf8'));
|
|
166
|
+
this._idMap = JSON.parse(fs.readFileSync(idmapPath, 'utf8'));
|
|
167
|
+
this._itemCount = this._idMap.length;
|
|
168
|
+
this._maxElements = this._index.getMaxElements();
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
static async fromDir(dir) {
|
|
173
|
+
const store = new HNSWVectorStore();
|
|
174
|
+
await store.load(dir);
|
|
175
|
+
return store;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async _rebuild(newMax) {
|
|
179
|
+
const HNSW = await getHnswModule();
|
|
180
|
+
this._maxElements = newMax;
|
|
181
|
+
this._index = new HNSW('cosine', DIMS);
|
|
182
|
+
this._index.initIndex(this._maxElements, 200);
|
|
183
|
+
for (let i = 0; i < this._itemCount; i++) {
|
|
184
|
+
this._index.addPoint(this._vectors[i], i);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FlatVectorStore } from './flat-store.js';
|
|
2
|
+
import { HNSWVectorStore } from './hnsw-store.js';
|
|
3
|
+
|
|
4
|
+
let _store = null;
|
|
5
|
+
|
|
6
|
+
export function getStore(type = null) {
|
|
7
|
+
if (_store) return _store;
|
|
8
|
+
|
|
9
|
+
if (!type) {
|
|
10
|
+
type = process.env.PG_VECTOR_STORE || 'flat';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
_store = type === 'hnsw' ? new HNSWVectorStore() : new FlatVectorStore();
|
|
14
|
+
return _store;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function resetStore() {
|
|
18
|
+
_store = null;
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export class VectorStore {
|
|
2
|
+
async add(id, vector) { throw new Error('not implemented'); }
|
|
3
|
+
async addBatch(entries) { throw new Error('not implemented'); }
|
|
4
|
+
async remove(id) { throw new Error('not implemented'); }
|
|
5
|
+
async search(vector, topK) { throw new Error('not implemented'); }
|
|
6
|
+
async build(entries) { throw new Error('not implemented'); }
|
|
7
|
+
async clear() { throw new Error('not implemented'); }
|
|
8
|
+
get size() { return 0; }
|
|
9
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class RateLimiter {
|
|
2
|
+
constructor({ maxRequests, windowMs }) {
|
|
3
|
+
this.maxRequests = maxRequests
|
|
4
|
+
this.windowMs = windowMs
|
|
5
|
+
this.timestamps = []
|
|
6
|
+
this._chain = Promise.resolve()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async acquire() {
|
|
10
|
+
const prev = this._chain
|
|
11
|
+
this._chain = prev.then(() => this._doAcquire())
|
|
12
|
+
return this._chain
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async _doAcquire() {
|
|
16
|
+
while (!this.tryAcquire()) {
|
|
17
|
+
const oldest = this.timestamps[0]
|
|
18
|
+
const waitMs = oldest
|
|
19
|
+
? Math.max(1, oldest + this.windowMs - Date.now())
|
|
20
|
+
: 100
|
|
21
|
+
await new Promise(r => setTimeout(r, Math.min(waitMs, this.windowMs)))
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
tryAcquire() {
|
|
26
|
+
const now = Date.now()
|
|
27
|
+
const cutoff = now - this.windowMs
|
|
28
|
+
this.timestamps = this.timestamps.filter(t => t > cutoff)
|
|
29
|
+
if (this.timestamps.length >= this.maxRequests) return false
|
|
30
|
+
this.timestamps.push(now)
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
33
|
+
}
|
package/validator.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
import matter from 'gray-matter';
|
|
4
|
+
import { MAX_DOWNLOAD_SIZE } from './config.js';
|
|
3
5
|
|
|
4
6
|
// patterns that indicate malicious or junk skills
|
|
5
7
|
const DANGEROUS_PATTERNS = [
|
|
@@ -15,7 +17,7 @@ const DANGEROUS_PATTERNS = [
|
|
|
15
17
|
];
|
|
16
18
|
|
|
17
19
|
const MIN_CONTENT_LENGTH = 200; // chars of actual instruction
|
|
18
|
-
const MAX_CONTENT_LENGTH =
|
|
20
|
+
const MAX_CONTENT_LENGTH = 5242880; // 5MB cap
|
|
19
21
|
const MIN_DESCRIPTION_LENGTH = 15;
|
|
20
22
|
const NAME_RE = /^[a-z0-9][a-z0-9-]{1,63}$/;
|
|
21
23
|
|
|
@@ -80,6 +82,25 @@ export function validateSkill(filePath) {
|
|
|
80
82
|
|
|
81
83
|
// junk filename heuristic
|
|
82
84
|
const base = filePath.split(/[\\/]/).pop().toLowerCase();
|
|
85
|
+
|
|
86
|
+
// path traversal check (must be an actual path component, not substring match)
|
|
87
|
+
const pathParts = filePath.split(/[\\/]/);
|
|
88
|
+
if (pathParts.includes('..')) {
|
|
89
|
+
errors.push('Path traversal detected: file path contains ".."');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// extension whitelist — reject unexpected file types
|
|
93
|
+
const ALLOWED_EXTENSIONS = new Set(['.md', '.json', '.yaml', '.yml', '.txt', '.js', '.ts', '.py', '.rs', '.toml']);
|
|
94
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
95
|
+
if (!ALLOWED_EXTENSIONS.has(ext)) {
|
|
96
|
+
errors.push(`File extension "${ext}" not allowed. Allowed: ${[...ALLOWED_EXTENSIONS].join(', ')}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// binary content detection — must be valid UTF-8 with no null bytes
|
|
100
|
+
if (raw.includes('\0')) {
|
|
101
|
+
errors.push('File contains null bytes (binary content)');
|
|
102
|
+
}
|
|
103
|
+
|
|
83
104
|
if (['readme.md', 'changelog.md', 'license.md', 'contributing.md'].includes(base)) {
|
|
84
105
|
warnings.push('Filename looks like a docs file, not a skill.');
|
|
85
106
|
}
|
|
@@ -136,6 +157,15 @@ export function validateBundle(def) {
|
|
|
136
157
|
return { ok: errors.length === 0, errors, warnings };
|
|
137
158
|
}
|
|
138
159
|
|
|
160
|
+
export function sanitizeExternalContent(content) {
|
|
161
|
+
if (typeof content !== 'string') return ''
|
|
162
|
+
let sanitized = content.replace(/\0/g, '')
|
|
163
|
+
if (Buffer.byteLength(sanitized, 'utf8') > MAX_DOWNLOAD_SIZE) {
|
|
164
|
+
sanitized = Buffer.from(sanitized, 'utf8').subarray(0, MAX_DOWNLOAD_SIZE).toString('utf8')
|
|
165
|
+
}
|
|
166
|
+
return sanitized
|
|
167
|
+
}
|
|
168
|
+
|
|
139
169
|
// CLI: node validator.js <file>
|
|
140
170
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
141
171
|
const file = process.argv[2];
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
2.0.0 / 2024-08-31
|
|
2
|
-
==================
|
|
3
|
-
|
|
4
|
-
* Drop node <18 support
|
|
5
|
-
* deps: mime-types@^3.0.0
|
|
6
|
-
* deps: negotiator@^1.0.0
|
|
7
|
-
|
|
8
|
-
1.3.8 / 2022-02-02
|
|
9
|
-
==================
|
|
10
|
-
|
|
11
|
-
* deps: mime-types@~2.1.34
|
|
12
|
-
- deps: mime-db@~1.51.0
|
|
13
|
-
* deps: negotiator@0.6.3
|
|
14
|
-
|
|
15
|
-
1.3.7 / 2019-04-29
|
|
16
|
-
==================
|
|
17
|
-
|
|
18
|
-
* deps: negotiator@0.6.2
|
|
19
|
-
- Fix sorting charset, encoding, and language with extra parameters
|
|
20
|
-
|
|
21
|
-
1.3.6 / 2019-04-28
|
|
22
|
-
==================
|
|
23
|
-
|
|
24
|
-
* deps: mime-types@~2.1.24
|
|
25
|
-
- deps: mime-db@~1.40.0
|
|
26
|
-
|
|
27
|
-
1.3.5 / 2018-02-28
|
|
28
|
-
==================
|
|
29
|
-
|
|
30
|
-
* deps: mime-types@~2.1.18
|
|
31
|
-
- deps: mime-db@~1.33.0
|
|
32
|
-
|
|
33
|
-
1.3.4 / 2017-08-22
|
|
34
|
-
==================
|
|
35
|
-
|
|
36
|
-
* deps: mime-types@~2.1.16
|
|
37
|
-
- deps: mime-db@~1.29.0
|
|
38
|
-
|
|
39
|
-
1.3.3 / 2016-05-02
|
|
40
|
-
==================
|
|
41
|
-
|
|
42
|
-
* deps: mime-types@~2.1.11
|
|
43
|
-
- deps: mime-db@~1.23.0
|
|
44
|
-
* deps: negotiator@0.6.1
|
|
45
|
-
- perf: improve `Accept` parsing speed
|
|
46
|
-
- perf: improve `Accept-Charset` parsing speed
|
|
47
|
-
- perf: improve `Accept-Encoding` parsing speed
|
|
48
|
-
- perf: improve `Accept-Language` parsing speed
|
|
49
|
-
|
|
50
|
-
1.3.2 / 2016-03-08
|
|
51
|
-
==================
|
|
52
|
-
|
|
53
|
-
* deps: mime-types@~2.1.10
|
|
54
|
-
- Fix extension of `application/dash+xml`
|
|
55
|
-
- Update primary extension for `audio/mp4`
|
|
56
|
-
- deps: mime-db@~1.22.0
|
|
57
|
-
|
|
58
|
-
1.3.1 / 2016-01-19
|
|
59
|
-
==================
|
|
60
|
-
|
|
61
|
-
* deps: mime-types@~2.1.9
|
|
62
|
-
- deps: mime-db@~1.21.0
|
|
63
|
-
|
|
64
|
-
1.3.0 / 2015-09-29
|
|
65
|
-
==================
|
|
66
|
-
|
|
67
|
-
* deps: mime-types@~2.1.7
|
|
68
|
-
- deps: mime-db@~1.19.0
|
|
69
|
-
* deps: negotiator@0.6.0
|
|
70
|
-
- Fix including type extensions in parameters in `Accept` parsing
|
|
71
|
-
- Fix parsing `Accept` parameters with quoted equals
|
|
72
|
-
- Fix parsing `Accept` parameters with quoted semicolons
|
|
73
|
-
- Lazy-load modules from main entry point
|
|
74
|
-
- perf: delay type concatenation until needed
|
|
75
|
-
- perf: enable strict mode
|
|
76
|
-
- perf: hoist regular expressions
|
|
77
|
-
- perf: remove closures getting spec properties
|
|
78
|
-
- perf: remove a closure from media type parsing
|
|
79
|
-
- perf: remove property delete from media type parsing
|
|
80
|
-
|
|
81
|
-
1.2.13 / 2015-09-06
|
|
82
|
-
===================
|
|
83
|
-
|
|
84
|
-
* deps: mime-types@~2.1.6
|
|
85
|
-
- deps: mime-db@~1.18.0
|
|
86
|
-
|
|
87
|
-
1.2.12 / 2015-07-30
|
|
88
|
-
===================
|
|
89
|
-
|
|
90
|
-
* deps: mime-types@~2.1.4
|
|
91
|
-
- deps: mime-db@~1.16.0
|
|
92
|
-
|
|
93
|
-
1.2.11 / 2015-07-16
|
|
94
|
-
===================
|
|
95
|
-
|
|
96
|
-
* deps: mime-types@~2.1.3
|
|
97
|
-
- deps: mime-db@~1.15.0
|
|
98
|
-
|
|
99
|
-
1.2.10 / 2015-07-01
|
|
100
|
-
===================
|
|
101
|
-
|
|
102
|
-
* deps: mime-types@~2.1.2
|
|
103
|
-
- deps: mime-db@~1.14.0
|
|
104
|
-
|
|
105
|
-
1.2.9 / 2015-06-08
|
|
106
|
-
==================
|
|
107
|
-
|
|
108
|
-
* deps: mime-types@~2.1.1
|
|
109
|
-
- perf: fix deopt during mapping
|
|
110
|
-
|
|
111
|
-
1.2.8 / 2015-06-07
|
|
112
|
-
==================
|
|
113
|
-
|
|
114
|
-
* deps: mime-types@~2.1.0
|
|
115
|
-
- deps: mime-db@~1.13.0
|
|
116
|
-
* perf: avoid argument reassignment & argument slice
|
|
117
|
-
* perf: avoid negotiator recursive construction
|
|
118
|
-
* perf: enable strict mode
|
|
119
|
-
* perf: remove unnecessary bitwise operator
|
|
120
|
-
|
|
121
|
-
1.2.7 / 2015-05-10
|
|
122
|
-
==================
|
|
123
|
-
|
|
124
|
-
* deps: negotiator@0.5.3
|
|
125
|
-
- Fix media type parameter matching to be case-insensitive
|
|
126
|
-
|
|
127
|
-
1.2.6 / 2015-05-07
|
|
128
|
-
==================
|
|
129
|
-
|
|
130
|
-
* deps: mime-types@~2.0.11
|
|
131
|
-
- deps: mime-db@~1.9.1
|
|
132
|
-
* deps: negotiator@0.5.2
|
|
133
|
-
- Fix comparing media types with quoted values
|
|
134
|
-
- Fix splitting media types with quoted commas
|
|
135
|
-
|
|
136
|
-
1.2.5 / 2015-03-13
|
|
137
|
-
==================
|
|
138
|
-
|
|
139
|
-
* deps: mime-types@~2.0.10
|
|
140
|
-
- deps: mime-db@~1.8.0
|
|
141
|
-
|
|
142
|
-
1.2.4 / 2015-02-14
|
|
143
|
-
==================
|
|
144
|
-
|
|
145
|
-
* Support Node.js 0.6
|
|
146
|
-
* deps: mime-types@~2.0.9
|
|
147
|
-
- deps: mime-db@~1.7.0
|
|
148
|
-
* deps: negotiator@0.5.1
|
|
149
|
-
- Fix preference sorting to be stable for long acceptable lists
|
|
150
|
-
|
|
151
|
-
1.2.3 / 2015-01-31
|
|
152
|
-
==================
|
|
153
|
-
|
|
154
|
-
* deps: mime-types@~2.0.8
|
|
155
|
-
- deps: mime-db@~1.6.0
|
|
156
|
-
|
|
157
|
-
1.2.2 / 2014-12-30
|
|
158
|
-
==================
|
|
159
|
-
|
|
160
|
-
* deps: mime-types@~2.0.7
|
|
161
|
-
- deps: mime-db@~1.5.0
|
|
162
|
-
|
|
163
|
-
1.2.1 / 2014-12-30
|
|
164
|
-
==================
|
|
165
|
-
|
|
166
|
-
* deps: mime-types@~2.0.5
|
|
167
|
-
- deps: mime-db@~1.3.1
|
|
168
|
-
|
|
169
|
-
1.2.0 / 2014-12-19
|
|
170
|
-
==================
|
|
171
|
-
|
|
172
|
-
* deps: negotiator@0.5.0
|
|
173
|
-
- Fix list return order when large accepted list
|
|
174
|
-
- Fix missing identity encoding when q=0 exists
|
|
175
|
-
- Remove dynamic building of Negotiator class
|
|
176
|
-
|
|
177
|
-
1.1.4 / 2014-12-10
|
|
178
|
-
==================
|
|
179
|
-
|
|
180
|
-
* deps: mime-types@~2.0.4
|
|
181
|
-
- deps: mime-db@~1.3.0
|
|
182
|
-
|
|
183
|
-
1.1.3 / 2014-11-09
|
|
184
|
-
==================
|
|
185
|
-
|
|
186
|
-
* deps: mime-types@~2.0.3
|
|
187
|
-
- deps: mime-db@~1.2.0
|
|
188
|
-
|
|
189
|
-
1.1.2 / 2014-10-14
|
|
190
|
-
==================
|
|
191
|
-
|
|
192
|
-
* deps: negotiator@0.4.9
|
|
193
|
-
- Fix error when media type has invalid parameter
|
|
194
|
-
|
|
195
|
-
1.1.1 / 2014-09-28
|
|
196
|
-
==================
|
|
197
|
-
|
|
198
|
-
* deps: mime-types@~2.0.2
|
|
199
|
-
- deps: mime-db@~1.1.0
|
|
200
|
-
* deps: negotiator@0.4.8
|
|
201
|
-
- Fix all negotiations to be case-insensitive
|
|
202
|
-
- Stable sort preferences of same quality according to client order
|
|
203
|
-
|
|
204
|
-
1.1.0 / 2014-09-02
|
|
205
|
-
==================
|
|
206
|
-
|
|
207
|
-
* update `mime-types`
|
|
208
|
-
|
|
209
|
-
1.0.7 / 2014-07-04
|
|
210
|
-
==================
|
|
211
|
-
|
|
212
|
-
* Fix wrong type returned from `type` when match after unknown extension
|
|
213
|
-
|
|
214
|
-
1.0.6 / 2014-06-24
|
|
215
|
-
==================
|
|
216
|
-
|
|
217
|
-
* deps: negotiator@0.4.7
|
|
218
|
-
|
|
219
|
-
1.0.5 / 2014-06-20
|
|
220
|
-
==================
|
|
221
|
-
|
|
222
|
-
* fix crash when unknown extension given
|
|
223
|
-
|
|
224
|
-
1.0.4 / 2014-06-19
|
|
225
|
-
==================
|
|
226
|
-
|
|
227
|
-
* use `mime-types`
|
|
228
|
-
|
|
229
|
-
1.0.3 / 2014-06-11
|
|
230
|
-
==================
|
|
231
|
-
|
|
232
|
-
* deps: negotiator@0.4.6
|
|
233
|
-
- Order by specificity when quality is the same
|
|
234
|
-
|
|
235
|
-
1.0.2 / 2014-05-29
|
|
236
|
-
==================
|
|
237
|
-
|
|
238
|
-
* Fix interpretation when header not in request
|
|
239
|
-
* deps: pin negotiator@0.4.5
|
|
240
|
-
|
|
241
|
-
1.0.1 / 2014-01-18
|
|
242
|
-
==================
|
|
243
|
-
|
|
244
|
-
* Identity encoding isn't always acceptable
|
|
245
|
-
* deps: negotiator@~0.4.0
|
|
246
|
-
|
|
247
|
-
1.0.0 / 2013-12-27
|
|
248
|
-
==================
|
|
249
|
-
|
|
250
|
-
* Genesis
|