Comparing version 0.4.7 to 0.4.8
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
BlobHttpProperties = require('./../model/BlobHttpProperties'); | ||
Blob = require('./../model/Blob'); | ||
@@ -10,6 +10,5 @@ class CreateBlockBlob { | ||
process(req, res, container, blob) { | ||
const httpProps = this._buildHttpProps(req.headers); | ||
const metaProps = this._buildMetaProps(req.headers); | ||
storageManager.createBlockBlob(container, blob, req.body, httpProps, metaProps) | ||
process(req, res, containerName, blobName) { | ||
const blob = new Blob(blobName, req.headers); | ||
storageManager.createBlockBlob(containerName, blob, req.body) | ||
.then((result) => { | ||
@@ -21,9 +20,6 @@ this._addResponseHeaders(res, result) | ||
if (e.code === 'ENOENT') { | ||
console.error(`Container ${container} does not exist.`); | ||
res.status(404).send(); | ||
} else if (e.code === 'EACCES') { | ||
console.error(`Azurite failed to create blob in local file system due to missing permissions.`); | ||
res.status(404).send(); | ||
} else if (e.name === 'md5') { | ||
console.error(e.message); | ||
res.status(400).send(e.message); | ||
@@ -37,25 +33,2 @@ } else { | ||
_buildHttpProps(httpHeader) { | ||
return new BlobHttpProperties( | ||
null, // ETag will be overwritten by most recent value in DB if this is an update of an existing blob | ||
null, | ||
// x-ms-* attributes have precedence over according HTTP-Headers | ||
httpHeader['x-ms-blob-content-type'] || httpHeader['Content-Type'] || 'application/octet-stream', | ||
httpHeader['x-ms-blob-content-encoding'] || httpHeader['Content-Encoding'] || 'utf8', | ||
httpHeader['x-ms-blob-content-language'] || httpHeader['Content-Language'], | ||
httpHeader['x-ms-blob-content-md5'] || httpHeader['Content-MD5'], | ||
httpHeader['x-ms-blob-cache-control'] || httpHeader['Cache-Control']); | ||
} | ||
_buildMetaProps(httpHeader) { | ||
let metaProps = {}; | ||
Object.keys(httpHeader).forEach((key) => { | ||
const value = httpHeader[key]; | ||
if (key.indexOf('x-ms-meta-') !== -1) { | ||
metaProps[key] = value; | ||
} | ||
}); | ||
return metaProps; | ||
} | ||
_addResponseHeaders(res, props) { | ||
@@ -68,3 +41,3 @@ res.set({ | ||
'Content-MD5': props.md5 | ||
}); | ||
}); | ||
} | ||
@@ -71,0 +44,0 @@ } |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
Container = require('./../model/Container'), | ||
ContainerHttpProperties = require('./../model/ContainerHttpProperties'); | ||
Container = require('./../model/Container'); | ||
@@ -11,9 +10,7 @@ class CreateContainer { | ||
process(req, res) { | ||
const containerName = req.params.container; | ||
let containerModel = this._buildContainerModel(req, containerName); | ||
storageManager.createContainer(containerModel) | ||
process(req, res, containerName) { | ||
const container = new Container(containerName, req.headers) | ||
storageManager.createContainer(container) | ||
.then((result) => { | ||
console.log(`Successfully created container "${containerName}"`); | ||
this._addResponseHeaders(res, containerModel.httpProps) | ||
this._addResponseHeaders(res, container.httpProps) | ||
res.status(200).send(); | ||
@@ -23,3 +20,2 @@ }) | ||
if (e.code === "EEXIST") { | ||
console.error(`Container ${containerName} already exists.`); | ||
res.status(409).send(); | ||
@@ -34,17 +30,2 @@ } else { | ||
_buildContainerModel(req, containerName) { | ||
let optional = {}; | ||
if(req.headers['x-ms-blob-public-access']) { | ||
optional.access = req.headers['x-ms-blob-public-access']; | ||
} | ||
let container = new Container(containerName, new ContainerHttpProperties(), {}, optional); | ||
Object.keys(req.headers).forEach((key) => { | ||
let value = req.headers[key]; | ||
if (key.indexOf('x-ms-meta') !== -1) { | ||
container.metaProps[key] = value; | ||
} | ||
}); | ||
return container; | ||
} | ||
_addResponseHeaders(res, props) { | ||
@@ -51,0 +32,0 @@ res.set({ |
@@ -12,3 +12,2 @@ 'use strict'; | ||
.then((result) => { | ||
console.log(`Successfully deleted ${container}/${blob}`); | ||
res.status(202).send(); | ||
@@ -18,3 +17,2 @@ }) | ||
if (e.code === "ENOENT") { | ||
console.error(`Blob ${container}/${blob} does not exist.`); | ||
res.status(404).send('BlobNotFound'); | ||
@@ -21,0 +19,0 @@ } else { |
'use strict'; | ||
const storageManager = require('./../StorageManager'); | ||
const storageManager = require('./../StorageManager'), | ||
Container = require('./../model/Container'); | ||
@@ -9,7 +10,5 @@ class DeleteContainer { | ||
process(req, res) { | ||
const containerName = req.params.container | ||
process(req, res, containerName) { | ||
storageManager.deleteContainer(containerName) | ||
.then((result) => { | ||
console.log(`Successfully deleted container "${containerName}"`); | ||
res.status(200).send(); | ||
@@ -19,3 +18,2 @@ }) | ||
if (e.code === "ENOENT") { | ||
console.error(`Container ${containerName} does not exist.`); | ||
res.status(404).send(); | ||
@@ -22,0 +20,0 @@ } else { |
@@ -75,4 +75,4 @@ 'use strict'; | ||
header['x-ms-version'] = '2013-08-15'; | ||
header['Last-Modified'] = httpProps.lastModified; | ||
header['Content-MD5'] = httpProps.ContentMD5; | ||
header['Last-Modified'] = httpProps['Last-Modified']; | ||
header['Content-MD5'] = httpProps['Content-MD5']; | ||
header['Accept-Ranges'] = 'bytes'; | ||
@@ -79,0 +79,0 @@ res.set(header); |
@@ -0,0 +0,0 @@ 'use strict'; |
@@ -0,0 +0,0 @@ 'use strict'; |
@@ -5,3 +5,3 @@ 'use strict'; | ||
js2xmlparser = require("js2xmlparser"), | ||
model = require('./../model/ContainerList'); | ||
model = require('./../model/ContainerListXmlModel'); | ||
@@ -25,3 +25,2 @@ class ListContainers { | ||
.catch((e) => { | ||
console.error('ListContainers operation failed.\n' + JSON.stringify(e)); | ||
res.status(500).send(); | ||
@@ -55,3 +54,2 @@ }); | ||
let value = metaProps[key]; | ||
key = key.replace('x-ms-meta-', ''); | ||
key = 'metadata-' + key; | ||
@@ -58,0 +56,0 @@ modelContainer.metadata[key] = value; |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
BlobHttpProperties = require('./../model/BlobHttpProperties'); | ||
Blob = require('./../model/Blob'); | ||
@@ -12,11 +12,6 @@ class PutBlock { | ||
blockId: blockId, | ||
contentLength: req.headers['content-length'], | ||
contentLength: req.headers['content-length'] || req.headers['Content-Length'], | ||
fileName: `${containerName}-${blobName}-${blockId}`, | ||
parent: `${containerName}-${blobName}`, | ||
httpProps: new BlobHttpProperties(null, | ||
null, | ||
null, | ||
req.headers['x-ms-blob-content-encoding'] || 'utf8', | ||
null, | ||
req.headers['content-mD5']) | ||
blob: new Blob(blobName, req.headers) | ||
} | ||
@@ -43,2 +38,5 @@ // Content-Length is required. The length of the block content in bytes. | ||
res.status(400).send(e.message); | ||
} else { | ||
res.status(500).send(); | ||
throw e; | ||
} | ||
@@ -45,0 +43,0 @@ }); |
'use strict'; | ||
const storageManager = require('./../StorageManager'), | ||
BlobHttpProperties = require('./../model/BlobHttpProperties'), | ||
Blob = require('./../model/Blob'), | ||
BbPromise = require('bluebird'), | ||
@@ -14,29 +14,26 @@ xml2jsAsync = BbPromise.promisify(require('xml2js').parseString), | ||
process(req, res, containerName, blobName, xmlDoc) { | ||
let httpProps; | ||
let metaProps; | ||
const blob = new Blob(blobName, req.headers); | ||
let md5RequestBody; | ||
BbPromise.try(() => { | ||
httpProps = this._buildHttpProps(req.headers); | ||
metaProps = this._buildMetaProps(req.headers); | ||
md5RequestBody = md5(xmlDoc); | ||
return this._deserializeBlockList(xmlDoc) | ||
}) | ||
.then((blocklist) => { | ||
return storageManager.putBlockList(containerName, blobName, blocklist, httpProps, metaProps) | ||
}) | ||
.then((response) => { | ||
response.contentMD5 = md5RequestBody; | ||
this._addResponseHeaders(res, response); | ||
res.status(201).send(); | ||
}) | ||
.catch((e) => { | ||
if (e.code === 'xml') { | ||
res.status(400).send('UnsupportedXmlNode'); | ||
} else if (e.code === 'ENOENT'){ | ||
res.status(400).send('InvalidBlockList'); | ||
} else { | ||
res.status(500).send(); | ||
throw e; | ||
} | ||
}); | ||
.then((blocklist) => { | ||
return storageManager.putBlockList(containerName, blob, blocklist) | ||
}) | ||
.then((response) => { | ||
response.contentMD5 = md5RequestBody; | ||
this._addResponseHeaders(res, response); | ||
res.status(201).send(); | ||
}) | ||
.catch((e) => { | ||
if (e.code === 'ENOENT') { | ||
res.status(404).send(); | ||
} else if (e.code === 'xml') { | ||
res.status(400).send('UnsupportedXmlNode'); | ||
} else { | ||
res.status(500).send(); | ||
throw e; | ||
} | ||
}); | ||
} | ||
@@ -75,27 +72,4 @@ | ||
} | ||
_buildHttpProps(httpHeader) { | ||
return new BlobHttpProperties( | ||
null, // ETag will be overwritten by most recent value in DB if this is an update of an existing blob | ||
null, | ||
// x-ms-* attributes have precedence over according HTTP-Headers | ||
httpHeader['x-ms-blob-content-type'] || httpHeader['Content-Type'] || 'application/octet-stream', | ||
httpHeader['x-ms-blob-content-encoding'] || httpHeader['Content-Encoding'] || 'utf8', | ||
httpHeader['x-ms-blob-content-language'] || httpHeader['Content-Language'], | ||
httpHeader['x-ms-blob-content-md5'] || httpHeader['Content-MD5'], | ||
httpHeader['x-ms-blob-cache-control'] || httpHeader['Cache-Control']); | ||
} | ||
_buildMetaProps(httpHeader) { | ||
let metaProps = {}; | ||
Object.keys(httpHeader).forEach((key) => { | ||
const value = httpHeader[key]; | ||
if (key.indexOf('x-ms-meta-') !== -1) { | ||
metaProps[key] = value; | ||
} | ||
}); | ||
return metaProps; | ||
} | ||
} | ||
module.exports = new PutBlockList(); |
@@ -10,2 +10,3 @@ 'use strict'; | ||
fs = BbPromise.promisifyAll(require("fs")), | ||
morgan = require('morgan'), | ||
cli = require('./cli'); | ||
@@ -15,3 +16,3 @@ | ||
BbPromise.onPossiblyUnhandledRejection((err) => { | ||
console.log('**PANIC** Something unexpected happened! Emulator may be in an inconsistent state!'); | ||
console.error('**PANIC** Something unexpected happened! Emulator may be in an inconsistent state!'); | ||
process.stderr.write(err.stack); | ||
@@ -24,2 +25,3 @@ process.abort(); | ||
constructor() { | ||
this.server; | ||
} | ||
@@ -34,6 +36,5 @@ | ||
let app = express(); | ||
app.use((req, res, next) => { | ||
// TODO: Log sensible information about the request | ||
next(); | ||
}); | ||
if (!env.silent) { | ||
app.use(morgan('dev')); | ||
} | ||
app.use(bodyParser.raw({ | ||
@@ -48,9 +49,17 @@ inflate: true, | ||
require('./routes/BlobRoute')(app); | ||
app.listen(env.port, () => { | ||
cli.asciiGreeting(); | ||
this.server = app.listen(env.port, () => { | ||
if (!env.silent) { | ||
cli.asciiGreeting(); | ||
} | ||
}); | ||
}); | ||
} | ||
close() { | ||
return BbPromise.try(() => { | ||
this.server.close(); | ||
}) | ||
} | ||
} | ||
module.exports = Azurite; |
@@ -0,0 +0,0 @@ 'use strict'; |
@@ -14,7 +14,8 @@ 'use strict'; | ||
init(options) { | ||
if (initialized) { | ||
return; | ||
if (initialized && !options.overwrite) { | ||
return BbPromise.resolve(); | ||
} | ||
initialized = true; | ||
this.azuriteRootPath = options.l || options.location || './'; | ||
this.silent = options.s || options.silent; | ||
this.dbName = '__azurite_db__.json'; | ||
@@ -21,0 +22,0 @@ this.localStoragePath = path.join(this.azuriteRootPath, '__blobstorage__'); |
@@ -0,0 +0,0 @@ 'use strict'; |
@@ -0,0 +0,0 @@ 'use strict'; |
'use strict'; | ||
class Container { | ||
constructor(name, props, metaProps, optional) { | ||
this.name = name; | ||
this.httpProps = props || {}; | ||
this.metaProps = metaProps || {}; | ||
if (optional) { | ||
this.access = optional.access || 'private' | ||
} | ||
const StorageItem = require('./StorageItem'); | ||
class Container extends StorageItem { | ||
constructor(name, httpHeader) { | ||
super(name, httpHeader); | ||
this.access = httpHeader['x-ms-blob-public-access'] || 'private'; | ||
} | ||
@@ -12,0 +10,0 @@ } |
@@ -0,0 +0,0 @@ 'use strict'; |
@@ -9,3 +9,4 @@ 'use strict'; | ||
putBlockListHandler = require('./../api/PutBlockList'), | ||
getBlockListHandler = require('./../api/GetBlockList'); | ||
getBlockListHandler = require('./../api/GetBlockList'), | ||
setBlobMetadataHandler = require('./../api/SetBlobMetadata'); | ||
@@ -32,6 +33,4 @@ /* | ||
const blobType = req.headers['x-ms-blob-type']; | ||
// PUT Block | ||
if (req.query.comp === 'block') { | ||
putBlockHandler.process(req, res, req.params.container, req.params.blob, req.query.blockid); | ||
// PUT Blob | ||
} else if (req.query.comp === 'blocklist') { | ||
@@ -41,3 +40,7 @@ putBlockListHandler.process(req, res, req.params.container, req.params.blob, req.body); | ||
createBlockBlobHandler.process(req, res, req.params.container, req.params.blob); | ||
} else { | ||
} else if (req.query.comp === 'metadata') { | ||
// Set Blob Metadata | ||
setBlobMetadataHandler.process(req, res, req.params.container, req.params.blob); | ||
} | ||
else { | ||
res.status(500).send('Not supported yet. Azurite only supports Block Blobs.'); | ||
@@ -44,0 +47,0 @@ } |
@@ -31,5 +31,5 @@ 'use strict'; | ||
if (req.query.restype === 'container') { | ||
deleteContainerHandler.process(req, res); | ||
deleteContainerHandler.process(req, res, req.params.container); | ||
} | ||
}); | ||
} |
@@ -9,4 +9,3 @@ 'use strict'; | ||
md5 = require('md5'), | ||
CombinedStream = require('combined-stream'), | ||
BlobHttpProperties = require('./model/BlobHttpProperties'); | ||
CombinedStream = require('combined-stream'); | ||
@@ -81,11 +80,11 @@ const CONTAINERS_COL_NAME = 'Containers', | ||
createBlockBlob(container, blobName, body, httpProps, metaProps) { | ||
createBlockBlob(container, blob, body) { | ||
let containerPath = path.join(env.localStoragePath, container); | ||
let blobPath = path.join(containerPath, blobName); | ||
let blobPath = path.join(containerPath, blob.name); | ||
let response = {}; | ||
const targetMD5 = md5(body); | ||
httpProps.ContentMD5 = targetMD5; | ||
return fs.statAsync(containerPath) | ||
.then((stat) => { | ||
const sourceMD5 = httpProps['Content-MD5']; | ||
const sourceMD5 = blob.httpProps['Content-MD5']; | ||
blob.httpProps['Content-MD5'] = targetMD5; | ||
response.md5 = targetMD5; | ||
@@ -102,3 +101,3 @@ if (sourceMD5) { | ||
// Container exists, otherwise fs.statAsync throws error | ||
return fs.outputFileAsync(blobPath, body, { encoding: httpProps['Content-Encoding'] }); | ||
return fs.outputFileAsync(blobPath, body, { encoding: blob.httpProps['Content-Encoding'] }); | ||
}) | ||
@@ -111,3 +110,3 @@ .then(() => { | ||
const blobResult = coll.chain() | ||
.find({ 'name': { '$eq': blobName } }) | ||
.find({ 'name': { '$eq': blob.name } }) | ||
.data(); | ||
@@ -117,17 +116,17 @@ | ||
const newBlob = coll.insert({ | ||
name: blobName, | ||
http_props: httpProps, | ||
meta_props: metaProps, | ||
name: blob.name, | ||
http_props: blob.httpProps, | ||
meta_props: blob.metaProps, | ||
size: body.length | ||
}); | ||
response.ETag = newBlob.meta.revision; | ||
response.lastModified = httpProps.lastModified; | ||
response.lastModified = blob.httpProps.lastModified; | ||
} else { | ||
const updateBlob = blobResult[0]; | ||
updateBlob.http_props = httpProps; | ||
updateBlob.meta_props = metaProps; | ||
updateBlob.http_props = blob.httpProps; | ||
updateBlob.meta_props = blob.metaProps; | ||
updateBlob.size = body.length; | ||
coll.update(updateBlob); | ||
response.ETag = updateBlob.meta.revision; | ||
response.lastModified = httpProps.lastModified; | ||
response.lastModified = blob.httpProps.lastModified; | ||
} | ||
@@ -208,6 +207,5 @@ }) | ||
if (blobResult.length === 0) { | ||
const httpProps = new BlobHttpProperties(); | ||
coll.insert({ | ||
name: blobName, | ||
http_props: httpProps, | ||
http_props: options.blob.httpProps, | ||
committed: false, | ||
@@ -219,3 +217,3 @@ size: 0 | ||
// Checking MD5 in case 'Content-MD5' header was set. | ||
const sourceMD5 = options.httpProps['Content-MD5']; | ||
const sourceMD5 = options.blob.httpProps['Content-MD5']; | ||
const targetMD5 = md5(body); | ||
@@ -234,3 +232,3 @@ response['Content-MD5'] = targetMD5; | ||
const blockPath = path.join(env.commitsPath, options.fileName); | ||
return fs.outputFileAsync(blockPath, body, { encoding: options.httpProps['Content-Encoding'] }); | ||
return fs.outputFileAsync(blockPath, body, { encoding: options.blob.httpProps['Content-Encoding'] }); | ||
}) | ||
@@ -249,17 +247,17 @@ .then(() => { | ||
parent: options.parent, | ||
http_props: options.httpProps, | ||
http_props: options.blob.httpProps, | ||
size: body.length, // in bytes | ||
committed: false | ||
}); | ||
response.ETag = newBlob.meta.revision; | ||
response.lastModified = options.httpProps.lastModified; | ||
response.lastModified = options.blob.httpProps['Last-Modified']; | ||
} else { | ||
const updateBlob = blobResult[0]; | ||
updateBlob.http_props = options.httpProps; | ||
updateBlob.http_props = options.blob.httpProps; | ||
updateBlob.size = body.length; | ||
updatedBlob.committed = false; | ||
updateBlob.committed = false; | ||
coll.update(updateBlob); | ||
response.ETag = updateBlob.meta.revision; | ||
response.lastModified = options.httpProps.lastModified; | ||
response.lastModified = options.blob.httpProps['Last-Modified']; | ||
} | ||
@@ -270,27 +268,37 @@ return response; | ||
putBlockList(containerName, blobName, blockList, httpProps, metaProps) { | ||
putBlockList(containerName, blob, blockList) { | ||
const response = {}; | ||
let blocks = []; | ||
return BbPromise.try(() => { | ||
const combinedStream = CombinedStream.create(); | ||
let promises = []; | ||
for (const block of blockList) { | ||
const blockName = `${containerName}-${blobName}-${block.id}`; | ||
const blockName = `${containerName}-${blob.name}-${block.id}`; | ||
const blockPath = path.join(env.commitsPath, blockName); | ||
combinedStream.append(fs.createReadStream(blockPath)); | ||
blocks.push(blockPath); | ||
promises.push(fs.statAsync(blockPath)); | ||
} | ||
const blobPath = path.join(env.localStoragePath, containerName, blobName); | ||
combinedStream.pipe(fs.createWriteStream(blobPath)); | ||
// In case a block does not exists this will throw | ||
return BbPromise.all(promises); | ||
}) | ||
.then(() => { | ||
const combinedStream = CombinedStream.create(); | ||
for (const block of blocks) { | ||
combinedStream.append(fs.createReadStream(block)); | ||
} | ||
const blobPath = path.join(env.localStoragePath, containerName, blob.name); | ||
combinedStream.pipe(fs.createWriteStream(blobPath)); | ||
const coll = this.db.getCollection(containerName); | ||
const blobResult = coll.chain() | ||
.find({ 'name': { '$eq': blobName } }) | ||
.data(); | ||
const coll = this.db.getCollection(containerName); | ||
const blobResult = coll.chain() | ||
.find({ 'name': { '$eq': blob.name } }) | ||
.data(); | ||
// Blob must exist in DB since preceding calls to "PUT Block" | ||
const updateBlob = blobResult[0]; | ||
updateBlob.http_props = httpProps; | ||
updateBlob.meta_props = metaProps; | ||
coll.update(updateBlob); | ||
response.ETag = updateBlob.meta.revision; | ||
response.lastModified = httpProps.lastModified; | ||
}) | ||
// Blob must exist in DB since preceding calls to "PUT Block" | ||
const updateBlob = blobResult[0]; | ||
updateBlob.http_props = blob.httpProps; | ||
updateBlob.meta_props = blob.metaProps; | ||
coll.update(updateBlob); | ||
response.ETag = updateBlob.meta.revision; | ||
response.lastModified = blob.httpProps.lastModified; | ||
}) | ||
.then(() => { | ||
@@ -301,3 +309,3 @@ // Set Blocks in DB to committed = true, delete blocks not in BlockList | ||
const blocks = coll.chain() | ||
.find({ parent: `${containerName}-${blobName}` }) | ||
.find({ parent: `${containerName}-${blob.name}` }) | ||
.data(); | ||
@@ -321,3 +329,3 @@ for (const block of blocks) { | ||
getBlockList(containerName, blobName, blockListType) { | ||
let response ={}; | ||
let response = {}; | ||
return fs.statAsync(path.join(env.localStoragePath, containerName)) | ||
@@ -341,6 +349,35 @@ .then(() => { | ||
response.parentBlob = parentBlob[0]; | ||
return response; | ||
return response; | ||
}); | ||
} | ||
setBlobMetadata(containerName, blob) { | ||
return BbPromise.try(() => { | ||
const coll = this.db.getCollection(containerName); | ||
if (!coll) { | ||
const err = new Error('Container does not exist.'); | ||
err.code = 'NO_CONTAINER'; | ||
throw err; | ||
} | ||
const result = coll.chain() | ||
.find({ name: blob.name }) | ||
.data(); | ||
if (result.length === 0) { | ||
const err = new Error('Blob does not exist.'); | ||
err.code = 'NO_BLOB'; | ||
throw err; | ||
} | ||
const blobToUpdate = result[0]; | ||
blobToUpdate.meta_props = blob.metaProps; | ||
blobToUpdate.http_props['Last-Modified'] = blob.httpProps['Last-Modified']; | ||
coll.update(blobToUpdate); | ||
return { | ||
ETag: blobToUpdate.meta.revision, | ||
'Last-Modified': blobToUpdate.http_props['Last-Modified'] | ||
}; | ||
}); | ||
} | ||
_buildBlockListQuery(containerName, blobName, blockListType) { | ||
@@ -347,0 +384,0 @@ let query = { |
{ | ||
"name": "azurite", | ||
"version": "0.4.7", | ||
"version": "0.4.8", | ||
"description": "A lightweight server clone of Azure Blob Storage that simulates most of the commands supported by it with minimal dependencies.", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"pretest": "npm run clean", | ||
"test": "cross-env AZURITE_LOCATION=azurite-testdrive mocha --timeout 10000", | ||
"start": "bin/azurite -l azurite-testdrive", | ||
"clean": "rimraf azurite-testdrive" | ||
}, | ||
@@ -45,5 +48,14 @@ "engines": { | ||
"minimist": "^1.2.0", | ||
"morgan": "^1.7.0", | ||
"request": "^2.79.0", | ||
"xml2js": "^0.4.17" | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"chai-http": "^3.0.0", | ||
"cross-env": "^3.1.3", | ||
"mocha": "^3.2.0", | ||
"request-promise": "^4.1.1", | ||
"rimraf": "^2.5.4" | ||
} | ||
} |
# Azurite | ||
[![npm version](https://badge.fury.io/js/azurite.svg)](https://badge.fury.io/js/azurite) | ||
[![license](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=2592000)]() | ||
[![Build Status](https://travis-ci.org/arafato/azurite.svg?branch=master)](https://travis-ci.org/arafato/azurite) | ||
@@ -14,8 +15,7 @@ A lightweight server clone of Azure Blob Storage that simulates most of the commands supported by it with minimal dependencies. | ||
Standard Emulator Connection String: | ||
DefaultEndpointsProtocol=http;AccountName=devstoreaccount1; | ||
AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==; | ||
BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1; | ||
TableEndpoint=http://127.0.0.1:10002/devstoreaccount1; | ||
QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1; | ||
You do not need to provide an account key. | ||
# REST APIs | ||
@@ -22,0 +22,0 @@ https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/blob-service-rest-api |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
64060
33
1401
1
13
6
7
+ Addedmorgan@^1.7.0
+ Addedbasic-auth@2.0.1(transitive)
+ Addedmorgan@1.10.0(transitive)
+ Addedon-finished@2.3.0(transitive)
+ Addedon-headers@1.0.2(transitive)
+ Addedsafe-buffer@5.1.2(transitive)