commit
2c872fd354
13
README.md
13
README.md
|
@ -143,21 +143,26 @@ IDBFS based file systems can acquire new functionality by using adapters. These
|
||||||
of storage providers without altering them in anway. An adapter can be used with any provider, and multiple
|
of storage providers without altering them in anway. An adapter can be used with any provider, and multiple
|
||||||
adapters can be used together in order to compose complex functionality on top of a provider.
|
adapters can be used together in order to compose complex functionality on top of a provider.
|
||||||
|
|
||||||
There are currently 4 adapters available:
|
There are currently 5 adapters available:
|
||||||
|
* `FileSystem.adapters.Compression(provider)` - a default compression adapter that uses [Zlib](https://github.com/imaya/zlib.js)
|
||||||
|
* `FileSystem.adapters.Encryption(passphrase, provider)` - a default encryption adapter that uses [AES encryption](http://code.google.com/p/crypto-js/#AES)
|
||||||
|
|
||||||
|
You can also pick from other encryption cipher algorithms:
|
||||||
* `FileSystem.adapters.AES(passphrase, provider)` - extends a provider with [AES encryption](http://code.google.com/p/crypto-js/#AES)
|
* `FileSystem.adapters.AES(passphrase, provider)` - extends a provider with [AES encryption](http://code.google.com/p/crypto-js/#AES)
|
||||||
* `FileSystem.adapters.TripleDES(passphrase, provider)` - extends a provider with [TripleDES encryption](http://code.google.com/p/crypto-js/#DES,_Triple_DES)
|
* `FileSystem.adapters.TripleDES(passphrase, provider)` - extends a provider with [TripleDES encryption](http://code.google.com/p/crypto-js/#DES,_Triple_DES)
|
||||||
* `FileSystem.adapters.Rabbit(passphrase, provider)` - extends a provider with [Rabbit encryption](http://code.google.com/p/crypto-js/#Rabbit)
|
* `FileSystem.adapters.Rabbit(passphrase, provider)` - extends a provider with [Rabbit encryption](http://code.google.com/p/crypto-js/#Rabbit)
|
||||||
* `FileSystem.adapters.Encryption(passphrase, provider)` - a default encryption adapter that uses [AES encryption](http://code.google.com/p/crypto-js/#AES)
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var FileSystem = IDBFS.FileSystem;
|
var FileSystem = IDBFS.FileSystem;
|
||||||
var providers = FileSystem.providers;
|
var providers = FileSystem.providers;
|
||||||
var adapters = FileSystem.adapters;
|
var adapters = FileSystem.adapters;
|
||||||
|
|
||||||
// Create a WebSQL-based, Encrypted File System.
|
// Create a WebSQL-based, Encrypted, Compressed File System by
|
||||||
|
// composing a provider and adatpers.
|
||||||
var webSQLProvider = new providers.WebSQL();
|
var webSQLProvider = new providers.WebSQL();
|
||||||
var encryptionAdatper = new adapters.Encryption('super-secret-passphrase', webSQLProvider);
|
var encryptionAdatper = new adapters.Encryption('super-secret-passphrase', webSQLProvider);
|
||||||
var fs1 = new FileSystem({ provider: encryptionAdapter });
|
var compressionAdatper = new adatpers.Compression(encryptionAdapter);
|
||||||
|
var fs = new FileSystem({ provider: compressionAdapter });
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also write your own adapter if you need to add new capabilities to the providers. Adapters share the same
|
You can also write your own adapter if you need to add new capabilities to the providers. Adapters share the same
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use strict';function l(d){throw d;}var u=void 0,x=!0,aa=this;function z(d,a){var c=d.split("."),f=aa;!(c[0]in f)&&f.execScript&&f.execScript("var "+c[0]);for(var b;c.length&&(b=c.shift());)!c.length&&a!==u?f[b]=a:f=f[b]?f[b]:f[b]={}};var E="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array;function G(d,a){this.index="number"===typeof a?a:0;this.i=0;this.buffer=d instanceof(E?Uint8Array:Array)?d:new (E?Uint8Array:Array)(32768);2*this.buffer.length<=this.index&&l(Error("invalid index"));this.buffer.length<=this.index&&this.f()}G.prototype.f=function(){var d=this.buffer,a,c=d.length,f=new (E?Uint8Array:Array)(c<<1);if(E)f.set(d);else for(a=0;a<c;++a)f[a]=d[a];return this.buffer=f};
|
||||||
|
G.prototype.d=function(d,a,c){var f=this.buffer,b=this.index,e=this.i,g=f[b],h;c&&1<a&&(d=8<a?(N[d&255]<<24|N[d>>>8&255]<<16|N[d>>>16&255]<<8|N[d>>>24&255])>>32-a:N[d]>>8-a);if(8>a+e)g=g<<a|d,e+=a;else for(h=0;h<a;++h)g=g<<1|d>>a-h-1&1,8===++e&&(e=0,f[b++]=N[g],g=0,b===f.length&&(f=this.f()));f[b]=g;this.buffer=f;this.i=e;this.index=b};G.prototype.finish=function(){var d=this.buffer,a=this.index,c;0<this.i&&(d[a]<<=8-this.i,d[a]=N[d[a]],a++);E?c=d.subarray(0,a):(d.length=a,c=d);return c};
|
||||||
|
var fa=new (E?Uint8Array:Array)(256),O;for(O=0;256>O;++O){for(var P=O,Q=P,ga=7,P=P>>>1;P;P>>>=1)Q<<=1,Q|=P&1,--ga;fa[O]=(Q<<ga&255)>>>0}var N=fa;function ha(d){this.buffer=new (E?Uint16Array:Array)(2*d);this.length=0}ha.prototype.getParent=function(d){return 2*((d-2)/4|0)};ha.prototype.push=function(d,a){var c,f,b=this.buffer,e;c=this.length;b[this.length++]=a;for(b[this.length++]=d;0<c;)if(f=this.getParent(c),b[c]>b[f])e=b[c],b[c]=b[f],b[f]=e,e=b[c+1],b[c+1]=b[f+1],b[f+1]=e,c=f;else break;return this.length};
|
||||||
|
ha.prototype.pop=function(){var d,a,c=this.buffer,f,b,e;a=c[0];d=c[1];this.length-=2;c[0]=c[this.length];c[1]=c[this.length+1];for(e=0;;){b=2*e+2;if(b>=this.length)break;b+2<this.length&&c[b+2]>c[b]&&(b+=2);if(c[b]>c[e])f=c[e],c[e]=c[b],c[b]=f,f=c[e+1],c[e+1]=c[b+1],c[b+1]=f;else break;e=b}return{index:d,value:a,length:this.length}};function R(d){var a=d.length,c=0,f=Number.POSITIVE_INFINITY,b,e,g,h,k,n,q,r,p;for(r=0;r<a;++r)d[r]>c&&(c=d[r]),d[r]<f&&(f=d[r]);b=1<<c;e=new (E?Uint32Array:Array)(b);g=1;h=0;for(k=2;g<=c;){for(r=0;r<a;++r)if(d[r]===g){n=0;q=h;for(p=0;p<g;++p)n=n<<1|q&1,q>>=1;for(p=n;p<b;p+=k)e[p]=g<<16|r;++h}++g;h<<=1;k<<=1}return[e,c,f]};function ia(d,a){this.h=ma;this.w=0;this.input=E&&d instanceof Array?new Uint8Array(d):d;this.b=0;a&&(a.lazy&&(this.w=a.lazy),"number"===typeof a.compressionType&&(this.h=a.compressionType),a.outputBuffer&&(this.a=E&&a.outputBuffer instanceof Array?new Uint8Array(a.outputBuffer):a.outputBuffer),"number"===typeof a.outputIndex&&(this.b=a.outputIndex));this.a||(this.a=new (E?Uint8Array:Array)(32768))}var ma=2,na={NONE:0,r:1,k:ma,N:3},oa=[],S;
|
||||||
|
for(S=0;288>S;S++)switch(x){case 143>=S:oa.push([S+48,8]);break;case 255>=S:oa.push([S-144+400,9]);break;case 279>=S:oa.push([S-256+0,7]);break;case 287>=S:oa.push([S-280+192,8]);break;default:l("invalid literal: "+S)}
|
||||||
|
ia.prototype.j=function(){var d,a,c,f,b=this.input;switch(this.h){case 0:c=0;for(f=b.length;c<f;){a=E?b.subarray(c,c+65535):b.slice(c,c+65535);c+=a.length;var e=a,g=c===f,h=u,k=u,n=u,q=u,r=u,p=this.a,m=this.b;if(E){for(p=new Uint8Array(this.a.buffer);p.length<=m+e.length+5;)p=new Uint8Array(p.length<<1);p.set(this.a)}h=g?1:0;p[m++]=h|0;k=e.length;n=~k+65536&65535;p[m++]=k&255;p[m++]=k>>>8&255;p[m++]=n&255;p[m++]=n>>>8&255;if(E)p.set(e,m),m+=e.length,p=p.subarray(0,m);else{q=0;for(r=e.length;q<r;++q)p[m++]=
|
||||||
|
e[q];p.length=m}this.b=m;this.a=p}break;case 1:var s=new G(E?new Uint8Array(this.a.buffer):this.a,this.b);s.d(1,1,x);s.d(1,2,x);var w=pa(this,b),y,ja,B;y=0;for(ja=w.length;y<ja;y++)if(B=w[y],G.prototype.d.apply(s,oa[B]),256<B)s.d(w[++y],w[++y],x),s.d(w[++y],5),s.d(w[++y],w[++y],x);else if(256===B)break;this.a=s.finish();this.b=this.a.length;break;case ma:var D=new G(E?new Uint8Array(this.a.buffer):this.a,this.b),Da,M,U,V,W,gb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],ba,Ea,ca,Fa,ka,ra=Array(19),
|
||||||
|
Ga,X,la,A,Ha;Da=ma;D.d(1,1,x);D.d(Da,2,x);M=pa(this,b);ba=qa(this.L,15);Ea=sa(ba);ca=qa(this.K,7);Fa=sa(ca);for(U=286;257<U&&0===ba[U-1];U--);for(V=30;1<V&&0===ca[V-1];V--);var Ia=U,Ja=V,I=new (E?Uint32Array:Array)(Ia+Ja),t,J,v,da,H=new (E?Uint32Array:Array)(316),F,C,K=new (E?Uint8Array:Array)(19);for(t=J=0;t<Ia;t++)I[J++]=ba[t];for(t=0;t<Ja;t++)I[J++]=ca[t];if(!E){t=0;for(da=K.length;t<da;++t)K[t]=0}t=F=0;for(da=I.length;t<da;t+=J){for(J=1;t+J<da&&I[t+J]===I[t];++J);v=J;if(0===I[t])if(3>v)for(;0<
|
||||||
|
v--;)H[F++]=0,K[0]++;else for(;0<v;)C=138>v?v:138,C>v-3&&C<v&&(C=v-3),10>=C?(H[F++]=17,H[F++]=C-3,K[17]++):(H[F++]=18,H[F++]=C-11,K[18]++),v-=C;else if(H[F++]=I[t],K[I[t]]++,v--,3>v)for(;0<v--;)H[F++]=I[t],K[I[t]]++;else for(;0<v;)C=6>v?v:6,C>v-3&&C<v&&(C=v-3),H[F++]=16,H[F++]=C-3,K[16]++,v-=C}d=E?H.subarray(0,F):H.slice(0,F);ka=qa(K,7);for(A=0;19>A;A++)ra[A]=ka[gb[A]];for(W=19;4<W&&0===ra[W-1];W--);Ga=sa(ka);D.d(U-257,5,x);D.d(V-1,5,x);D.d(W-4,4,x);for(A=0;A<W;A++)D.d(ra[A],3,x);A=0;for(Ha=d.length;A<
|
||||||
|
Ha;A++)if(X=d[A],D.d(Ga[X],ka[X],x),16<=X){A++;switch(X){case 16:la=2;break;case 17:la=3;break;case 18:la=7;break;default:l("invalid code: "+X)}D.d(d[A],la,x)}var Ka=[Ea,ba],La=[Fa,ca],L,Ma,ea,ua,Na,Oa,Pa,Qa;Na=Ka[0];Oa=Ka[1];Pa=La[0];Qa=La[1];L=0;for(Ma=M.length;L<Ma;++L)if(ea=M[L],D.d(Na[ea],Oa[ea],x),256<ea)D.d(M[++L],M[++L],x),ua=M[++L],D.d(Pa[ua],Qa[ua],x),D.d(M[++L],M[++L],x);else if(256===ea)break;this.a=D.finish();this.b=this.a.length;break;default:l("invalid compression type")}return this.a};
|
||||||
|
function ta(d,a){this.length=d;this.G=a}
|
||||||
|
var va=function(){function d(b){switch(x){case 3===b:return[257,b-3,0];case 4===b:return[258,b-4,0];case 5===b:return[259,b-5,0];case 6===b:return[260,b-6,0];case 7===b:return[261,b-7,0];case 8===b:return[262,b-8,0];case 9===b:return[263,b-9,0];case 10===b:return[264,b-10,0];case 12>=b:return[265,b-11,1];case 14>=b:return[266,b-13,1];case 16>=b:return[267,b-15,1];case 18>=b:return[268,b-17,1];case 22>=b:return[269,b-19,2];case 26>=b:return[270,b-23,2];case 30>=b:return[271,b-27,2];case 34>=b:return[272,
|
||||||
|
b-31,2];case 42>=b:return[273,b-35,3];case 50>=b:return[274,b-43,3];case 58>=b:return[275,b-51,3];case 66>=b:return[276,b-59,3];case 82>=b:return[277,b-67,4];case 98>=b:return[278,b-83,4];case 114>=b:return[279,b-99,4];case 130>=b:return[280,b-115,4];case 162>=b:return[281,b-131,5];case 194>=b:return[282,b-163,5];case 226>=b:return[283,b-195,5];case 257>=b:return[284,b-227,5];case 258===b:return[285,b-258,0];default:l("invalid length: "+b)}}var a=[],c,f;for(c=3;258>=c;c++)f=d(c),a[c]=f[2]<<24|f[1]<<
|
||||||
|
16|f[0];return a}(),wa=E?new Uint32Array(va):va;
|
||||||
|
function pa(d,a){function c(b,c){var a=b.G,d=[],e=0,f;f=wa[b.length];d[e++]=f&65535;d[e++]=f>>16&255;d[e++]=f>>24;var g;switch(x){case 1===a:g=[0,a-1,0];break;case 2===a:g=[1,a-2,0];break;case 3===a:g=[2,a-3,0];break;case 4===a:g=[3,a-4,0];break;case 6>=a:g=[4,a-5,1];break;case 8>=a:g=[5,a-7,1];break;case 12>=a:g=[6,a-9,2];break;case 16>=a:g=[7,a-13,2];break;case 24>=a:g=[8,a-17,3];break;case 32>=a:g=[9,a-25,3];break;case 48>=a:g=[10,a-33,4];break;case 64>=a:g=[11,a-49,4];break;case 96>=a:g=[12,a-
|
||||||
|
65,5];break;case 128>=a:g=[13,a-97,5];break;case 192>=a:g=[14,a-129,6];break;case 256>=a:g=[15,a-193,6];break;case 384>=a:g=[16,a-257,7];break;case 512>=a:g=[17,a-385,7];break;case 768>=a:g=[18,a-513,8];break;case 1024>=a:g=[19,a-769,8];break;case 1536>=a:g=[20,a-1025,9];break;case 2048>=a:g=[21,a-1537,9];break;case 3072>=a:g=[22,a-2049,10];break;case 4096>=a:g=[23,a-3073,10];break;case 6144>=a:g=[24,a-4097,11];break;case 8192>=a:g=[25,a-6145,11];break;case 12288>=a:g=[26,a-8193,12];break;case 16384>=
|
||||||
|
a:g=[27,a-12289,12];break;case 24576>=a:g=[28,a-16385,13];break;case 32768>=a:g=[29,a-24577,13];break;default:l("invalid distance")}f=g;d[e++]=f[0];d[e++]=f[1];d[e++]=f[2];var h,k;h=0;for(k=d.length;h<k;++h)p[m++]=d[h];w[d[0]]++;y[d[3]]++;s=b.length+c-1;r=null}var f,b,e,g,h,k={},n,q,r,p=E?new Uint16Array(2*a.length):[],m=0,s=0,w=new (E?Uint32Array:Array)(286),y=new (E?Uint32Array:Array)(30),ja=d.w,B;if(!E){for(e=0;285>=e;)w[e++]=0;for(e=0;29>=e;)y[e++]=0}w[256]=1;f=0;for(b=a.length;f<b;++f){e=h=0;
|
||||||
|
for(g=3;e<g&&f+e!==b;++e)h=h<<8|a[f+e];k[h]===u&&(k[h]=[]);n=k[h];if(!(0<s--)){for(;0<n.length&&32768<f-n[0];)n.shift();if(f+3>=b){r&&c(r,-1);e=0;for(g=b-f;e<g;++e)B=a[f+e],p[m++]=B,++w[B];break}0<n.length?(q=xa(a,f,n),r?r.length<q.length?(B=a[f-1],p[m++]=B,++w[B],c(q,0)):c(r,-1):q.length<ja?r=q:c(q,0)):r?c(r,-1):(B=a[f],p[m++]=B,++w[B])}n.push(f)}p[m++]=256;w[256]++;d.L=w;d.K=y;return E?p.subarray(0,m):p}
|
||||||
|
function xa(d,a,c){var f,b,e=0,g,h,k,n,q=d.length;h=0;n=c.length;a:for(;h<n;h++){f=c[n-h-1];g=3;if(3<e){for(k=e;3<k;k--)if(d[f+k-1]!==d[a+k-1])continue a;g=e}for(;258>g&&a+g<q&&d[f+g]===d[a+g];)++g;g>e&&(b=f,e=g);if(258===g)break}return new ta(e,a-b)}
|
||||||
|
function qa(d,a){var c=d.length,f=new ha(572),b=new (E?Uint8Array:Array)(c),e,g,h,k,n;if(!E)for(k=0;k<c;k++)b[k]=0;for(k=0;k<c;++k)0<d[k]&&f.push(k,d[k]);e=Array(f.length/2);g=new (E?Uint32Array:Array)(f.length/2);if(1===e.length)return b[f.pop().index]=1,b;k=0;for(n=f.length/2;k<n;++k)e[k]=f.pop(),g[k]=e[k].value;h=ya(g,g.length,a);k=0;for(n=e.length;k<n;++k)b[e[k].index]=h[k];return b}
|
||||||
|
function ya(d,a,c){function f(b){var c=k[b][n[b]];c===a?(f(b+1),f(b+1)):--g[c];++n[b]}var b=new (E?Uint16Array:Array)(c),e=new (E?Uint8Array:Array)(c),g=new (E?Uint8Array:Array)(a),h=Array(c),k=Array(c),n=Array(c),q=(1<<c)-a,r=1<<c-1,p,m,s,w,y;b[c-1]=a;for(m=0;m<c;++m)q<r?e[m]=0:(e[m]=1,q-=r),q<<=1,b[c-2-m]=(b[c-1-m]/2|0)+a;b[0]=e[0];h[0]=Array(b[0]);k[0]=Array(b[0]);for(m=1;m<c;++m)b[m]>2*b[m-1]+e[m]&&(b[m]=2*b[m-1]+e[m]),h[m]=Array(b[m]),k[m]=Array(b[m]);for(p=0;p<a;++p)g[p]=c;for(s=0;s<b[c-1];++s)h[c-
|
||||||
|
1][s]=d[s],k[c-1][s]=s;for(p=0;p<c;++p)n[p]=0;1===e[c-1]&&(--g[0],++n[c-1]);for(m=c-2;0<=m;--m){w=p=0;y=n[m+1];for(s=0;s<b[m];s++)w=h[m+1][y]+h[m+1][y+1],w>d[p]?(h[m][s]=w,k[m][s]=a,y+=2):(h[m][s]=d[p],k[m][s]=p,++p);n[m]=0;1===e[m]&&f(m)}return g}
|
||||||
|
function sa(d){var a=new (E?Uint16Array:Array)(d.length),c=[],f=[],b=0,e,g,h,k;e=0;for(g=d.length;e<g;e++)c[d[e]]=(c[d[e]]|0)+1;e=1;for(g=16;e<=g;e++)f[e]=b,b+=c[e]|0,b<<=1;e=0;for(g=d.length;e<g;e++){b=f[d[e]];f[d[e]]+=1;h=a[e]=0;for(k=d[e];h<k;h++)a[e]=a[e]<<1|b&1,b>>>=1}return a};function T(d,a){this.l=[];this.m=32768;this.e=this.g=this.c=this.q=0;this.input=E?new Uint8Array(d):d;this.s=!1;this.n=za;this.B=!1;if(a||!(a={}))a.index&&(this.c=a.index),a.bufferSize&&(this.m=a.bufferSize),a.bufferType&&(this.n=a.bufferType),a.resize&&(this.B=a.resize);switch(this.n){case Aa:this.b=32768;this.a=new (E?Uint8Array:Array)(32768+this.m+258);break;case za:this.b=0;this.a=new (E?Uint8Array:Array)(this.m);this.f=this.J;this.t=this.H;this.o=this.I;break;default:l(Error("invalid inflate mode"))}}
|
||||||
|
var Aa=0,za=1,Ba={D:Aa,C:za};
|
||||||
|
T.prototype.p=function(){for(;!this.s;){var d=Y(this,3);d&1&&(this.s=x);d>>>=1;switch(d){case 0:var a=this.input,c=this.c,f=this.a,b=this.b,e=u,g=u,h=u,k=f.length,n=u;this.e=this.g=0;e=a[c++];e===u&&l(Error("invalid uncompressed block header: LEN (first byte)"));g=e;e=a[c++];e===u&&l(Error("invalid uncompressed block header: LEN (second byte)"));g|=e<<8;e=a[c++];e===u&&l(Error("invalid uncompressed block header: NLEN (first byte)"));h=e;e=a[c++];e===u&&l(Error("invalid uncompressed block header: NLEN (second byte)"));h|=
|
||||||
|
e<<8;g===~h&&l(Error("invalid uncompressed block header: length verify"));c+g>a.length&&l(Error("input buffer is broken"));switch(this.n){case Aa:for(;b+g>f.length;){n=k-b;g-=n;if(E)f.set(a.subarray(c,c+n),b),b+=n,c+=n;else for(;n--;)f[b++]=a[c++];this.b=b;f=this.f();b=this.b}break;case za:for(;b+g>f.length;)f=this.f({v:2});break;default:l(Error("invalid inflate mode"))}if(E)f.set(a.subarray(c,c+g),b),b+=g,c+=g;else for(;g--;)f[b++]=a[c++];this.c=c;this.b=b;this.a=f;break;case 1:this.o(Ca,Ra);break;
|
||||||
|
case 2:Sa(this);break;default:l(Error("unknown BTYPE: "+d))}}return this.t()};
|
||||||
|
var Ta=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],Ua=E?new Uint16Array(Ta):Ta,Va=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],Wa=E?new Uint16Array(Va):Va,Xa=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],Ya=E?new Uint8Array(Xa):Xa,Za=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],$a=E?new Uint16Array(Za):Za,ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,
|
||||||
|
10,11,11,12,12,13,13],bb=E?new Uint8Array(ab):ab,cb=new (E?Uint8Array:Array)(288),Z,db;Z=0;for(db=cb.length;Z<db;++Z)cb[Z]=143>=Z?8:255>=Z?9:279>=Z?7:8;var Ca=R(cb),eb=new (E?Uint8Array:Array)(30),fb,hb;fb=0;for(hb=eb.length;fb<hb;++fb)eb[fb]=5;var Ra=R(eb);function Y(d,a){for(var c=d.g,f=d.e,b=d.input,e=d.c,g;f<a;)g=b[e++],g===u&&l(Error("input buffer is broken")),c|=g<<f,f+=8;g=c&(1<<a)-1;d.g=c>>>a;d.e=f-a;d.c=e;return g}
|
||||||
|
function ib(d,a){for(var c=d.g,f=d.e,b=d.input,e=d.c,g=a[0],h=a[1],k,n,q;f<h;){k=b[e++];if(k===u)break;c|=k<<f;f+=8}n=g[c&(1<<h)-1];q=n>>>16;d.g=c>>q;d.e=f-q;d.c=e;return n&65535}
|
||||||
|
function Sa(d){function a(a,b,c){var d,f,e,g;for(g=0;g<a;)switch(d=ib(this,b),d){case 16:for(e=3+Y(this,2);e--;)c[g++]=f;break;case 17:for(e=3+Y(this,3);e--;)c[g++]=0;f=0;break;case 18:for(e=11+Y(this,7);e--;)c[g++]=0;f=0;break;default:f=c[g++]=d}return c}var c=Y(d,5)+257,f=Y(d,5)+1,b=Y(d,4)+4,e=new (E?Uint8Array:Array)(Ua.length),g,h,k,n;for(n=0;n<b;++n)e[Ua[n]]=Y(d,3);g=R(e);h=new (E?Uint8Array:Array)(c);k=new (E?Uint8Array:Array)(f);d.o(R(a.call(d,c,g,h)),R(a.call(d,f,g,k)))}
|
||||||
|
T.prototype.o=function(d,a){var c=this.a,f=this.b;this.u=d;for(var b=c.length-258,e,g,h,k;256!==(e=ib(this,d));)if(256>e)f>=b&&(this.b=f,c=this.f(),f=this.b),c[f++]=e;else{g=e-257;k=Wa[g];0<Ya[g]&&(k+=Y(this,Ya[g]));e=ib(this,a);h=$a[e];0<bb[e]&&(h+=Y(this,bb[e]));f>=b&&(this.b=f,c=this.f(),f=this.b);for(;k--;)c[f]=c[f++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=f};
|
||||||
|
T.prototype.I=function(d,a){var c=this.a,f=this.b;this.u=d;for(var b=c.length,e,g,h,k;256!==(e=ib(this,d));)if(256>e)f>=b&&(c=this.f(),b=c.length),c[f++]=e;else{g=e-257;k=Wa[g];0<Ya[g]&&(k+=Y(this,Ya[g]));e=ib(this,a);h=$a[e];0<bb[e]&&(h+=Y(this,bb[e]));f+k>b&&(c=this.f(),b=c.length);for(;k--;)c[f]=c[f++-h]}for(;8<=this.e;)this.e-=8,this.c--;this.b=f};
|
||||||
|
T.prototype.f=function(){var d=new (E?Uint8Array:Array)(this.b-32768),a=this.b-32768,c,f,b=this.a;if(E)d.set(b.subarray(32768,d.length));else{c=0;for(f=d.length;c<f;++c)d[c]=b[c+32768]}this.l.push(d);this.q+=d.length;if(E)b.set(b.subarray(a,a+32768));else for(c=0;32768>c;++c)b[c]=b[a+c];this.b=32768;return b};
|
||||||
|
T.prototype.J=function(d){var a,c=this.input.length/this.c+1|0,f,b,e,g=this.input,h=this.a;d&&("number"===typeof d.v&&(c=d.v),"number"===typeof d.F&&(c+=d.F));2>c?(f=(g.length-this.c)/this.u[2],e=258*(f/2)|0,b=e<h.length?h.length+e:h.length<<1):b=h.length*c;E?(a=new Uint8Array(b),a.set(h)):a=h;return this.a=a};
|
||||||
|
T.prototype.t=function(){var d=0,a=this.a,c=this.l,f,b=new (E?Uint8Array:Array)(this.q+(this.b-32768)),e,g,h,k;if(0===c.length)return E?this.a.subarray(32768,this.b):this.a.slice(32768,this.b);e=0;for(g=c.length;e<g;++e){f=c[e];h=0;for(k=f.length;h<k;++h)b[d++]=f[h]}e=32768;for(g=this.b;e<g;++e)b[d++]=a[e];this.l=[];return this.buffer=b};
|
||||||
|
T.prototype.H=function(){var d,a=this.b;E?this.B?(d=new Uint8Array(a),d.set(this.a.subarray(0,a))):d=this.a.subarray(0,a):(this.a.length>a&&(this.a.length=a),d=this.a);return this.buffer=d};function jb(d){if("string"===typeof d){var a=d.split(""),c,f;c=0;for(f=a.length;c<f;c++)a[c]=(a[c].charCodeAt(0)&255)>>>0;d=a}for(var b=1,e=0,g=d.length,h,k=0;0<g;){h=1024<g?1024:g;g-=h;do b+=d[k++],e+=b;while(--h);b%=65521;e%=65521}return(e<<16|b)>>>0};function kb(d,a){var c,f;this.input=d;this.c=0;if(a||!(a={}))a.index&&(this.c=a.index),a.verify&&(this.M=a.verify);c=d[this.c++];f=d[this.c++];switch(c&15){case lb:this.method=lb;break;default:l(Error("unsupported compression method"))}0!==((c<<8)+f)%31&&l(Error("invalid fcheck flag:"+((c<<8)+f)%31));f&32&&l(Error("fdict flag is not supported"));this.A=new T(d,{index:this.c,bufferSize:a.bufferSize,bufferType:a.bufferType,resize:a.resize})}
|
||||||
|
kb.prototype.p=function(){var d=this.input,a,c;a=this.A.p();this.c=this.A.c;this.M&&(c=(d[this.c++]<<24|d[this.c++]<<16|d[this.c++]<<8|d[this.c++])>>>0,c!==jb(a)&&l(Error("invalid adler-32 checksum")));return a};var lb=8;function mb(d,a){this.input=d;this.a=new (E?Uint8Array:Array)(32768);this.h=$.k;var c={},f;if((a||!(a={}))&&"number"===typeof a.compressionType)this.h=a.compressionType;for(f in a)c[f]=a[f];c.outputBuffer=this.a;this.z=new ia(this.input,c)}var $=na;
|
||||||
|
mb.prototype.j=function(){var d,a,c,f,b,e,g,h=0;g=this.a;d=lb;switch(d){case lb:a=Math.LOG2E*Math.log(32768)-8;break;default:l(Error("invalid compression method"))}c=a<<4|d;g[h++]=c;switch(d){case lb:switch(this.h){case $.NONE:b=0;break;case $.r:b=1;break;case $.k:b=2;break;default:l(Error("unsupported compression type"))}break;default:l(Error("invalid compression method"))}f=b<<6|0;g[h++]=f|31-(256*c+f)%31;e=jb(this.input);this.z.b=h;g=this.z.j();h=g.length;E&&(g=new Uint8Array(g.buffer),g.length<=
|
||||||
|
h+4&&(this.a=new Uint8Array(g.length+4),this.a.set(g),g=this.a),g=g.subarray(0,h+4));g[h++]=e>>24&255;g[h++]=e>>16&255;g[h++]=e>>8&255;g[h++]=e&255;return g};function nb(d,a){var c,f,b,e;if(Object.keys)c=Object.keys(a);else for(f in c=[],b=0,a)c[b++]=f;b=0;for(e=c.length;b<e;++b)f=c[b],z(d+"."+f,a[f])};z("Zlib.Inflate",kb);z("Zlib.Inflate.prototype.decompress",kb.prototype.p);nb("Zlib.Inflate.BufferType",{ADAPTIVE:Ba.C,BLOCK:Ba.D});z("Zlib.Deflate",mb);z("Zlib.Deflate.compress",function(d,a){return(new mb(d,a)).j()});z("Zlib.Deflate.prototype.compress",mb.prototype.j);nb("Zlib.Deflate.CompressionType",{NONE:$.NONE,FIXED:$.r,DYNAMIC:$.k});}).call(this);
|
|
@ -1,6 +1,7 @@
|
||||||
define(function(require) {
|
define(function(require) {
|
||||||
|
|
||||||
var CryptoAdapters = require('src/adapters/crypto');
|
var CryptoAdapters = require('src/adapters/crypto');
|
||||||
|
var ZlibAdapter = require('src/adapters/zlib');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
|
@ -8,7 +9,12 @@ define(function(require) {
|
||||||
AES: CryptoAdapters.AES,
|
AES: CryptoAdapters.AES,
|
||||||
TripleDES: CryptoAdapters.TripleDES,
|
TripleDES: CryptoAdapters.TripleDES,
|
||||||
Rabbit: CryptoAdapters.Rabbit,
|
Rabbit: CryptoAdapters.Rabbit,
|
||||||
// Convenience encryption wrapper (default to AES)
|
|
||||||
|
// Compression Adapters
|
||||||
|
Zlib: ZlibAdapter,
|
||||||
|
|
||||||
|
// Convenience adapters (provide default choices)
|
||||||
|
Compression: ZlibAdapter,
|
||||||
Encryption: CryptoAdapters.AES
|
Encryption: CryptoAdapters.AES
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,41 @@ define(function(require) {
|
||||||
require("crypto-js/rollups/rabbit");
|
require("crypto-js/rollups/rabbit");
|
||||||
|
|
||||||
|
|
||||||
|
// Move back and forth from Uint8Arrays and CryptoJS WordArray
|
||||||
|
// See http://code.google.com/p/crypto-js/#The_Cipher_Input and
|
||||||
|
// https://groups.google.com/forum/#!topic/crypto-js/TOb92tcJlU0
|
||||||
|
var WordArray = CryptoJS.lib.WordArray;
|
||||||
|
function fromWordArray(wordArray) {
|
||||||
|
var words = wordArray.words;
|
||||||
|
var sigBytes = wordArray.sigBytes;
|
||||||
|
var u8 = new Uint8Array(sigBytes);
|
||||||
|
var b;
|
||||||
|
for (var i = 0; i < sigBytes; i++) {
|
||||||
|
b = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
|
||||||
|
u8[i] = b;
|
||||||
|
}
|
||||||
|
return u8;
|
||||||
|
}
|
||||||
|
function toWordArray(u8arr) {
|
||||||
|
var len = u8arr.length;
|
||||||
|
var words = [];
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
|
||||||
|
}
|
||||||
|
return WordArray.create(words, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// UTF8 Text De/Encoders
|
||||||
|
require('encoding');
|
||||||
|
function encode(str) {
|
||||||
|
return (new TextEncoder('utf-8')).encode(str);
|
||||||
|
}
|
||||||
|
function decode(u8arr) {
|
||||||
|
return (new TextDecoder('utf-8')).decode(u8arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function CryptoContext(context, encrypt, decrypt) {
|
function CryptoContext(context, encrypt, decrypt) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.encrypt = encrypt;
|
this.encrypt = encrypt;
|
||||||
|
@ -43,13 +78,34 @@ define(function(require) {
|
||||||
// prompting the user to enter it when the file system is being opened.
|
// prompting the user to enter it when the file system is being opened.
|
||||||
function CryptoAdapter(passphrase, provider) {
|
function CryptoAdapter(passphrase, provider) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.encrypt = function(plain) {
|
|
||||||
return CryptoJS[encryptionType].encrypt(plain, passphrase)
|
// Cache cipher algorithm we'll use in encrypt/decrypt
|
||||||
.toString();
|
var cipher = CryptoJS[encryptionType];
|
||||||
|
|
||||||
|
// To encrypt:
|
||||||
|
// 1) accept a buffer (Uint8Array) containing binary data
|
||||||
|
// 2) convert the buffer to a CipherJS WordArray
|
||||||
|
// 3) encrypt the WordArray using the chosen cipher algorithm + passphrase
|
||||||
|
// 4) convert the resulting ciphertext to a UTF8 encoded Uint8Array and return
|
||||||
|
this.encrypt = function(buffer) {
|
||||||
|
var wordArray = toWordArray(buffer);
|
||||||
|
var encrypted = cipher.encrypt(wordArray, passphrase);
|
||||||
|
var utf8EncodedBuf = encode(encrypted);
|
||||||
|
return utf8EncodedBuf;
|
||||||
};
|
};
|
||||||
this.decrypt = function(encrypted) {
|
|
||||||
return CryptoJS[encryptionType].decrypt(encrypted, passphrase)
|
// To decrypt:
|
||||||
.toString(CryptoJS.enc.Utf8);
|
// 1) accept a buffer (Uint8Array) containing a UTF8 encoded Uint8Array
|
||||||
|
// 2) convert the buffer to string (i.e., the ciphertext we got from encrypting)
|
||||||
|
// 3) decrypt the ciphertext string
|
||||||
|
// 4) convert the decrypted cipherParam object to a UTF8 string
|
||||||
|
// 5) encode the UTF8 string to a Uint8Array buffer and return
|
||||||
|
this.decrypt = function(buffer) {
|
||||||
|
var encryptedStr = decode(buffer);
|
||||||
|
var decrypted = cipher.decrypt(encryptedStr, passphrase);
|
||||||
|
var decryptedUtf8 = decrypted.toString(CryptoJS.enc.Utf8);
|
||||||
|
var utf8EncodedBuf = encode(decryptedUtf8);
|
||||||
|
return utf8EncodedBuf;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
CryptoAdapter.isSupported = function() {
|
CryptoAdapter.isSupported = function() {
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
define(function(require) {
|
||||||
|
|
||||||
|
// Zlib compression, see
|
||||||
|
// https://github.com/imaya/zlib.js/blob/master/bin/zlib.min.js
|
||||||
|
require("zlib");
|
||||||
|
|
||||||
|
var Inflate = Zlib.Inflate;
|
||||||
|
function inflate(compressed) {
|
||||||
|
return (new Inflate(compressed)).decompress();
|
||||||
|
}
|
||||||
|
|
||||||
|
var Deflate = Zlib.Deflate;
|
||||||
|
function deflate(buffer) {
|
||||||
|
return (new Deflate(buffer)).compress();
|
||||||
|
}
|
||||||
|
|
||||||
|
function ZlibContext(context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
ZlibContext.prototype.clear = function(callback) {
|
||||||
|
this.context.clear(callback);
|
||||||
|
};
|
||||||
|
ZlibContext.prototype.get = function(key, callback) {
|
||||||
|
this.context.get(key, function(err, result) {
|
||||||
|
if(err) {
|
||||||
|
callback(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Deal with result being null
|
||||||
|
if(result) {
|
||||||
|
result = inflate(result);
|
||||||
|
}
|
||||||
|
callback(null, result);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
ZlibContext.prototype.put = function(key, value, callback) {
|
||||||
|
value = deflate(value);
|
||||||
|
this.context.put(key, value, callback);
|
||||||
|
};
|
||||||
|
ZlibContext.prototype.delete = function(key, callback) {
|
||||||
|
this.context.delete(key, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function ZlibAdapter(provider, inflate, deflate) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
ZlibAdapter.isSupported = function() {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
ZlibAdapter.prototype.open = function(callback) {
|
||||||
|
this.provider.open(callback);
|
||||||
|
};
|
||||||
|
ZlibAdapter.prototype.getReadOnlyContext = function() {
|
||||||
|
return new ZlibContext(this.provider.getReadOnlyContext());
|
||||||
|
};
|
||||||
|
ZlibAdapter.prototype.getReadWriteContext = function() {
|
||||||
|
return new ZlibContext(this.provider.getReadWriteContext());
|
||||||
|
};
|
||||||
|
|
||||||
|
return ZlibAdapter;
|
||||||
|
});
|
|
@ -1,20 +1,31 @@
|
||||||
define(["IDBFS"], function(IDBFS) {
|
define(["IDBFS"], function(IDBFS) {
|
||||||
|
|
||||||
// We reuse the same set of tests for all crypto adapters.
|
// We reuse the same set of tests for all adapters.
|
||||||
// buildTestsFor() creates a set of tests bound to a crypto
|
// buildTestsFor() creates a set of tests bound to an
|
||||||
// adapter, and uses a Memory() provider internally.
|
// adapter, and uses a Memory() provider internally.
|
||||||
|
|
||||||
function buildTestsFor(adapterName) {
|
function buildTestsFor(adapterName, buildAdapter) {
|
||||||
var passphrase = '' + Date.now();
|
function encode(str) {
|
||||||
|
// TextEncoder is either native, or shimmed by IDBFS
|
||||||
|
return (new TextEncoder("utf-8")).encode(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make some string + binary buffer versions of things we'll need
|
||||||
|
var valueStr = "value", valueBuffer = encode(valueStr);
|
||||||
|
var value1Str = "value1", value1Buffer = encode(value1Str);
|
||||||
|
var value2Str = "value2", value2Buffer = encode(value2Str);
|
||||||
|
|
||||||
function createProvider() {
|
function createProvider() {
|
||||||
var memoryProvider = new IDBFS.FileSystem.providers.Memory();
|
var memoryProvider = new IDBFS.FileSystem.providers.Memory();
|
||||||
return new IDBFS.FileSystem.adapters[adapterName](passphrase, memoryProvider);
|
return buildAdapter(memoryProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("IDBFS.FileSystem.adapters." + adapterName, function() {
|
describe("IDBFS.FileSystem.adapters." + adapterName, function() {
|
||||||
it("is supported -- if it isn't, none of these tests can run.", function() {
|
it("is supported -- if it isn't, none of these tests can run.", function() {
|
||||||
expect(IDBFS.FileSystem.adapters[adapterName].isSupported()).toEqual(true);
|
// Allow for combined adapters (e.g., 'AES+Zlib') joined by '+'
|
||||||
|
adapterName.split('+').forEach(function(name) {
|
||||||
|
expect(IDBFS.FileSystem.adapters[name].isSupported()).toEqual(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("has open, getReadOnlyContext, and getReadWriteContext instance methods", function() {
|
it("has open, getReadOnlyContext, and getReadWriteContext instance methods", function() {
|
||||||
|
@ -57,7 +68,7 @@ define(["IDBFS"], function(IDBFS) {
|
||||||
_error = err;
|
_error = err;
|
||||||
|
|
||||||
var context = provider.getReadWriteContext();
|
var context = provider.getReadWriteContext();
|
||||||
context.put("key", "value", function(err, result) {
|
context.put("key", valueBuffer, function(err, result) {
|
||||||
_error = _error || err;
|
_error = _error || err;
|
||||||
context.get("key", function(err, result) {
|
context.get("key", function(err, result) {
|
||||||
_error = _error || err;
|
_error = _error || err;
|
||||||
|
@ -74,7 +85,7 @@ define(["IDBFS"], function(IDBFS) {
|
||||||
|
|
||||||
runs(function() {
|
runs(function() {
|
||||||
expect(_error).toEqual(null);
|
expect(_error).toEqual(null);
|
||||||
expect(_result).toEqual("value");
|
expect(_result).toEqual(valueBuffer);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -87,7 +98,7 @@ define(["IDBFS"], function(IDBFS) {
|
||||||
_error = err;
|
_error = err;
|
||||||
|
|
||||||
var context = provider.getReadWriteContext();
|
var context = provider.getReadWriteContext();
|
||||||
context.put("key", "value", function(err, result) {
|
context.put("key", valueBuffer, function(err, result) {
|
||||||
_error = _error || err;
|
_error = _error || err;
|
||||||
context.delete("key", function(err, result) {
|
context.delete("key", function(err, result) {
|
||||||
_error = _error || err;
|
_error = _error || err;
|
||||||
|
@ -120,9 +131,9 @@ define(["IDBFS"], function(IDBFS) {
|
||||||
_error = err;
|
_error = err;
|
||||||
|
|
||||||
var context = provider.getReadWriteContext();
|
var context = provider.getReadWriteContext();
|
||||||
context.put("key1", "value1", function(err, result) {
|
context.put("key1", value1Buffer, function(err, result) {
|
||||||
_error = _error || err;
|
_error = _error || err;
|
||||||
context.put("key2", "value2", function(err, result) {
|
context.put("key2", value2Buffer, function(err, result) {
|
||||||
_error = _error || err;
|
_error = _error || err;
|
||||||
|
|
||||||
context.clear(function(err) {
|
context.clear(function(err) {
|
||||||
|
@ -164,7 +175,7 @@ define(["IDBFS"], function(IDBFS) {
|
||||||
_error = err;
|
_error = err;
|
||||||
|
|
||||||
var context = provider.getReadOnlyContext();
|
var context = provider.getReadOnlyContext();
|
||||||
context.put("key1", "value1", function(err, result) {
|
context.put("key1", value1Buffer, function(err, result) {
|
||||||
_error = _error || err;
|
_error = _error || err;
|
||||||
_result = result;
|
_result = result;
|
||||||
|
|
||||||
|
@ -185,8 +196,32 @@ define(["IDBFS"], function(IDBFS) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTestsFor('AES');
|
|
||||||
buildTestsFor('TripleDES');
|
// Encryption
|
||||||
buildTestsFor('Rabbit');
|
buildTestsFor('AES', function buildAdapter(provider) {
|
||||||
|
var passphrase = '' + Date.now();
|
||||||
|
return new IDBFS.FileSystem.adapters.AES(passphrase, provider);
|
||||||
|
});
|
||||||
|
buildTestsFor('TripleDES', function buildAdapter(provider) {
|
||||||
|
var passphrase = '' + Date.now();
|
||||||
|
return new IDBFS.FileSystem.adapters.TripleDES(passphrase, provider);
|
||||||
|
});
|
||||||
|
buildTestsFor('Rabbit', function buildAdapter(provider) {
|
||||||
|
var passphrase = '' + Date.now();
|
||||||
|
return new IDBFS.FileSystem.adapters.Rabbit(passphrase, provider);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compression
|
||||||
|
buildTestsFor('Zlib', function buildAdapter(provider) {
|
||||||
|
return new IDBFS.FileSystem.adapters.Zlib(provider);
|
||||||
|
});
|
||||||
|
|
||||||
|
// AES + Zlib together
|
||||||
|
buildTestsFor('AES+Zlib', function buildAdapter(provider) {
|
||||||
|
var passphrase = '' + Date.now();
|
||||||
|
var zlib = new IDBFS.FileSystem.adapters.Zlib(provider);
|
||||||
|
var AESwithZlib = new IDBFS.FileSystem.adapters.AES(passphrase, zlib);
|
||||||
|
return AESwithZlib;
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
|
@ -19,5 +19,13 @@ define(["IDBFS"], function(IDBFS) {
|
||||||
it("has a default Encryption constructor", function() {
|
it("has a default Encryption constructor", function() {
|
||||||
expect(typeof IDBFS.FileSystem.adapters.Encryption).toEqual('function');
|
expect(typeof IDBFS.FileSystem.adapters.Encryption).toEqual('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("has a Zlib constructor", function() {
|
||||||
|
expect(typeof IDBFS.FileSystem.adapters.Zlib).toEqual('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("has a default Compression constructor", function() {
|
||||||
|
expect(typeof IDBFS.FileSystem.adapters.Compression).toEqual('function');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,7 +36,7 @@ define([
|
||||||
|
|
||||||
// IDBFS.FileSystem.adapters.*
|
// IDBFS.FileSystem.adapters.*
|
||||||
"spec/adapters/adapters.spec",
|
"spec/adapters/adapters.spec",
|
||||||
"spec/adapters/adapters.crypto.spec",
|
"spec/adapters/adapters.general.spec",
|
||||||
|
|
||||||
// Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test)
|
// Ported node.js tests (filenames match names in https://github.com/joyent/node/tree/master/test)
|
||||||
"spec/node-js/simple/test-fs-mkdir",
|
"spec/node-js/simple/test-fs-mkdir",
|
||||||
|
|
Loading…
Reference in New Issue