forked from sheetjs/sheetjs
		
	Compare commits
	
		
			11 Commits
		
	
	
		
			git-ignore
			...
			master
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1517aa1bca | |||
| b4bb01c731 | |||
| 4495a9253e | |||
| 0e4eb976e1 | |||
| 9c3853ba25 | |||
| 318e2319ee | |||
| 6c0f950f83 | |||
| 235ed7ccfb | |||
| 2d6c821261 | |||
| 36debb0eaa | |||
| df48a059c3 | 
| @ -7,6 +7,7 @@ changes may not be included if they are not expected to break existing code. | ||||
| * Sheet Visibility for ODS / FODS (h/t @edemaine) | ||||
| * HTML DOM ingress support formulae (`data-f`) | ||||
| * Proper handling of XLSX encoded entities (h/t @inreoh) | ||||
| * Proper handling of invalid DIF sheets that match heuristics (h/t @lowkeyfish) | ||||
| 
 | ||||
| ## v0.20.3 | ||||
| 
 | ||||
|  | ||||
| @ -1,69 +1,74 @@ | ||||
| # Contributing | ||||
| 
 | ||||
| The SheetJS Libraries should be free and clear to use in your projects.  In | ||||
| order to maintain that, every contributor must be vigilant. | ||||
| SheetJS CE should be free and clear to use in your projects. To ensure that | ||||
| remains true, each contributor must be vigilant and each contribution must be | ||||
| carefully scrutinized from a technical and legal perspective. | ||||
| 
 | ||||
| There have been many projects in the past that have been very lax regarding | ||||
| licensing. We are of the opinion that those are ticking timebombs and that no | ||||
| commercial product should depend on them. | ||||
| Many commercial products and open source projects have been very lax regarding | ||||
| licensing. They are ticking timebombs that no commercial product should use. | ||||
| 
 | ||||
| 
 | ||||
| # Required Reading | ||||
| ## Required Reading | ||||
| 
 | ||||
| These are pretty short reads and emphasize the importance of proper licensing: | ||||
| 
 | ||||
| - https://github.com/jazzband/tablib/issues/114 (discussion of other tools) | ||||
| - https://web.archive.org/web/20200916173942/https://github.com/jazzband/tablib/issues/114 | ||||
| 
 | ||||
| - https://web.archive.org/web/20120615223756/http://www.codinghorror.com/blog/2007/04/pick-a-license-any-license.html | ||||
| - https://web.archive.org/web/20240909210554/https://github.com/stephen-hardy/xlsx.js/issues/8 | ||||
| 
 | ||||
| 
 | ||||
| # Raising Issues | ||||
| ## Raising Issues | ||||
| 
 | ||||
| Issues should generally be accompanied by test files.  Since github does not | ||||
| support attachments, the best method is to send files to <sheetjs@gmail.com> | ||||
| (subject line should contain issue number or message) or to share using some | ||||
| storage service.  Unless expressly permitted, any attachments will not be | ||||
| shared or included in a test suite (although I will ask :) | ||||
| Issues should generally be accompanied by test files. It is strongly recommended | ||||
| to use the [issue tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues). | ||||
| 
 | ||||
| If sending email to a gmail account is problematic, the <dev@sheetjs.com> email | ||||
| inbox is self-hosted. | ||||
| If they cannot be shared publicly, please send files to <oss@sheetjs.com> | ||||
| (subject line should contain issue number or message) or share links to files | ||||
| hosted on a storage service. Unless expressly permitted, attachments will not be | ||||
| shared outside of SheetJS LLC or included in a test suite. | ||||
| 
 | ||||
| # Opening Pull Requests | ||||
| If a NDA is required, please send an email to <oss@sheetjs.com> with subject | ||||
| line "Non-Disclosure Agreemeant Request". | ||||
| 
 | ||||
| [Squash commits](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History) | ||||
| before opening a pull request, If the pull request addresses documentation or | ||||
| demos, add `[ci skip]` in the body or title of the commit message to skip tests. | ||||
| 
 | ||||
| # Pre-Contribution Checklist | ||||
| ## Opening Pull Requests | ||||
| 
 | ||||
| Please raise an issue before opening pull requests. It is easy to solve a | ||||
| specific problem without considering the full context or implications. | ||||
| 
 | ||||
| 
 | ||||
| ## Pre-Contribution Checklist | ||||
| 
 | ||||
| Before thinking about contributing, make sure that: | ||||
| 
 | ||||
| - You are not, nor have ever been, an employee of Microsoft Corporation. | ||||
| 
 | ||||
| - You have not signed any NDAs or Shared Source Agreements with Microsoft | ||||
|   Corporation or a subsidiary | ||||
|   Corporation or a subsidiary. | ||||
| 
 | ||||
| - You have not consulted any existing relevant codebase (if you have, please | ||||
|   take note of which codebases were consulted). | ||||
| 
 | ||||
| If you cannot attest to each of these items, the best approach is to raise an | ||||
| issue.  If it is a particularly high-priority issue, please drop an email to | ||||
| <sheetjs@gmail.com> and it will be prioritized. | ||||
| issue. If it is a particularly high-priority issue, please drop an email to | ||||
| <support@sheetjs.com> and it will be prioritized. | ||||
| 
 | ||||
| 
 | ||||
| # Intra-Contribution | ||||
| ## Intra-Contribution | ||||
| 
 | ||||
| Keep these in mind as you work: | ||||
| 
 | ||||
| - Your contributions are your original work.  Take note of any resources you | ||||
| - Your contributions are your original work. Take note of any resources you | ||||
|   consult in the process. Be extra careful not to use unlicensed code on the | ||||
|   Internet or code generated by a large language model or other AI tool. | ||||
| 
 | ||||
| - You are working on your own time.  Unless they explicitly grant permission, | ||||
| - You are working on your own time. Unless they explicitly grant permission, | ||||
|   your employer may be the ultimate owner of your IP | ||||
| 
 | ||||
| # Post-Contribution | ||||
| 
 | ||||
| Before contributions are merged, you will receive an email (at the address | ||||
| associated with the git commit) and will be asked to confirm the aforementioned | ||||
| items.  Ensure that the email addresses associated with the commits are valid. | ||||
| ## Post-Contribution | ||||
| 
 | ||||
| Before certain contributions are merged, you will receive an email (at the | ||||
| address associated with the git commit) and will be asked to confirm the | ||||
| aforementioned items. Ensure that the email addresses associated with the | ||||
| commits are valid. | ||||
|  | ||||
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							| @ -151,6 +151,10 @@ test-esm: test.mjs ## Run Node ESM test suite | ||||
| test.ts: test.mts | ||||
| 	node -pe 'var data = fs.readFileSync("'$<'", "utf8"); data.split("\n").map(function(l) { return l.replace(/^describe\((.*?)function\(\)/, "Deno.test($$1async function(t)").replace(/\b(?:it|describe)\((.*?)function\(\)/g, "await t.step($$1async function(t)").replace("assert.ok", "assert.assert"); }).join("\n")' > $@ | ||||
| 
 | ||||
| # NOTE: `bun test test.mjs` does not actually run the tests, hence test.test.mjs
 | ||||
| test.test.mjs: test.mjs | ||||
| 	cp $< $@ | ||||
| 
 | ||||
| .PHONY: test-bun | ||||
| test-bun: test.test.mjs ## Run Bun test suite
 | ||||
| 	bun test $< | ||||
|  | ||||
							
								
								
									
										64
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										64
									
								
								bin/xlsx.njs
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ | ||||
| /* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */ | ||||
| /* eslint-env node */ | ||||
| /* vim: set ts=2 ft=javascript: */ | ||||
| 
 | ||||
| var n = "xlsx"; | ||||
| var X = require('../'); | ||||
| try { X = require('../xlsx.flow'); } catch(e) {} | ||||
| @ -17,7 +18,7 @@ try { program = require('commander'); } catch(e) { | ||||
| 		"For older versions of node, explicitly install `xlsx-cli` globally:", | ||||
| 		"    $ npm i -g xlsx-cli", | ||||
| 		"    $ xlsx-cli --help" | ||||
| 	].forEach(function(m) { console.error(m); }); | ||||
| 	].forEach(function (m) { console.error(m); }); | ||||
| 	process.exit(1); | ||||
| } | ||||
| program | ||||
| @ -65,9 +66,10 @@ program | ||||
| 	.option('-F, --field-sep <sep>', 'CSV field separator', ",") | ||||
| 	.option('-R, --row-sep <sep>', 'CSV row separator', "\n") | ||||
| 	.option('-n, --sheet-rows <num>', 'Number of rows to process (0=all rows)') | ||||
| 	.option('--date-format <string>', 'output date format, for example yyyy-mm-dd') | ||||
| 	.option('--codepage <cp>', 'default to specified codepage when ambiguous') | ||||
| 	.option('--req <module>', 'require module before processing') | ||||
| 	.option('--sst', 'generate shared string table for XLS* formats') | ||||
| 	.option('-d, --no-dim', 'recalculate worksheet range') | ||||
| 	.option('--compress', 'use compression when writing XLSX/M/B and ODS') | ||||
| 	.option('--read', 'read but do not generate output') | ||||
| 	.option('--book', 'for single-sheet formats, emit a file per worksheet') | ||||
| @ -102,18 +104,18 @@ var wb_formats_2 = [ | ||||
| program.parse(process.argv); | ||||
| 
 | ||||
| var filename = '', sheetname = ''; | ||||
| if(program.args[0]) { | ||||
| if (program.args[0]) { | ||||
| 	filename = program.args[0]; | ||||
| 	if(program.args[1]) sheetname = program.args[1]; | ||||
| 	if (program.args[1]) sheetname = program.args[1]; | ||||
| } | ||||
| if(program.sheet) sheetname = program.sheet; | ||||
| if(program.file) filename = program.file; | ||||
| if (program.sheet) sheetname = program.sheet; | ||||
| if (program.file) filename = program.file; | ||||
| 
 | ||||
| if(!filename) { | ||||
| if (!filename) { | ||||
| 	console.error(n + ": must specify a filename"); | ||||
| 	process.exit(1); | ||||
| } | ||||
| if(!fs.existsSync(filename)) { | ||||
| if (!fs.existsSync(filename)) { | ||||
| 	console.error(n + ": " + filename + ": No such file or directory"); | ||||
| 	process.exit(2); | ||||
| } | ||||
| @ -209,15 +211,15 @@ wb_formats_2.forEach(function(m) { if(program[m[0]] || isfmt(m[0])) { | ||||
| } }); | ||||
| 
 | ||||
| var target_sheet = sheetname || ''; | ||||
| if(target_sheet === '') { | ||||
| 	if(+program.sheetIndex < (wb.SheetNames||[]).length) target_sheet = wb.SheetNames[+program.sheetIndex]; | ||||
| 	else target_sheet = (wb.SheetNames||[""])[0]; | ||||
| if (target_sheet === '') { | ||||
| 	if (+program.sheetIndex < (wb.SheetNames || []).length) target_sheet = wb.SheetNames[+program.sheetIndex]; | ||||
| 	else target_sheet = (wb.SheetNames || [""])[0]; | ||||
| } | ||||
| 
 | ||||
| var ws; | ||||
| try { | ||||
| 	ws = wb.Sheets[target_sheet]; | ||||
| 	if(!ws) { | ||||
| 	if (!ws) { | ||||
| 		console.error("Sheet " + target_sheet + " cannot be found"); | ||||
| 		process.exit(3); | ||||
| 	} | ||||
| @ -226,7 +228,7 @@ try { | ||||
| 	process.exit(4); | ||||
| } | ||||
| 
 | ||||
| if(!program.quiet && !program.book) console.error(target_sheet); | ||||
| if (!program.quiet && !program.book) console.error(target_sheet); | ||||
| 
 | ||||
| /* single worksheet file formats */ | ||||
| [ | ||||
| @ -254,21 +256,21 @@ if(!program.quiet && !program.book) console.error(target_sheet); | ||||
| 	process.exit(0); | ||||
| } }); | ||||
| 
 | ||||
| function outit(o, fn) { if(fn) fs.writeFileSync(fn, o); else console.log(o); } | ||||
| function outit(o, fn) { if (fn) fs.writeFileSync(fn, o); else console.log(o); } | ||||
| 
 | ||||
| function doit(cb) { | ||||
| 	/*:: if(!wb) throw new Error("unreachable"); */ | ||||
| 	if(program.book) wb.SheetNames.forEach(function(n, i) { | ||||
| 		/*:: if(!wb) throw new Error("unreachable"); */ | ||||
| 	/*:: if (!wb) throw new Error("unreachable"); */ | ||||
| 	if (program.book) wb.SheetNames.forEach(function (n, i) { | ||||
| 		/*:: if (!wb) throw new Error("unreachable"); */ | ||||
| 		outit(cb(wb.Sheets[n]), (program.output || sheetname || filename) + "." + i); | ||||
| 	}); | ||||
| 	else outit(cb(ws), program.output); | ||||
| } | ||||
| 
 | ||||
| var jso = {}; | ||||
| switch(true) { | ||||
| switch (true) { | ||||
| 	case program.formulae: | ||||
| 		doit(function(ws) { return X.utils.sheet_to_formulae(ws).join("\n"); }); | ||||
| 		doit(function (ws) { return X.utils.sheet_to_formulae(ws).join("\n"); }); | ||||
| 		break; | ||||
| 
 | ||||
| 	case program.arrays: jso.header = 1; | ||||
| @ -276,33 +278,33 @@ switch(true) { | ||||
| 	case program.rawJs: jso.raw = true; | ||||
| 	/* falls through */ | ||||
| 	case program.json: | ||||
| 		doit(function(ws) { return JSON.stringify(X.utils.sheet_to_json(ws,jso)); }); | ||||
| 		doit(function (ws) { return JSON.stringify(X.utils.sheet_to_json(ws, jso)); }); | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		if(!program.book) { | ||||
| 			var stream = X.stream.to_csv(ws, {FS:program.fieldSep||",", RS:program.rowSep||"\n"}); | ||||
| 			if(program.output) stream.pipe(fs.createWriteStream(program.output)); | ||||
| 		if (!program.book) { | ||||
| 			var stream = X.stream.to_csv(ws, { FS: program.fieldSep || ",", RS: program.rowSep || "\n" }); | ||||
| 			if (program.output) stream.pipe(fs.createWriteStream(program.output)); | ||||
| 			else stream.pipe(process.stdout); | ||||
| 		} else doit(function(ws) { return X.utils.sheet_to_csv(ws,{FS:program.fieldSep, RS:program.rowSep}); }); | ||||
| 		} else doit(function (ws) { return X.utils.sheet_to_csv(ws, { FS: program.fieldSep, RS: program.rowSep }); }); | ||||
| 		break; | ||||
| } | ||||
| 
 | ||||
| function dump_props(wb/*:Workbook*/) { | ||||
| 	var propaoa = []; | ||||
| 	if(Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops)); | ||||
| 	if (Object.assign && Object.entries) propaoa = Object.entries(Object.assign({}, wb.Props, wb.Custprops)); | ||||
| 	else { | ||||
| 		var Keys/*:: :Array<string> = []*/, pi; | ||||
| 		if(wb.Props) { | ||||
| 		if (wb.Props) { | ||||
| 			Keys = Object.keys(wb.Props); | ||||
| 			for(pi = 0; pi < Keys.length; ++pi) { | ||||
| 				if(Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]); | ||||
| 			for (pi = 0; pi < Keys.length; ++pi) { | ||||
| 				if (Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]); | ||||
| 			} | ||||
| 		} | ||||
| 		if(wb.Custprops) { | ||||
| 		if (wb.Custprops) { | ||||
| 			Keys = Object.keys(wb.Custprops); | ||||
| 			for(pi = 0; pi < Keys.length; ++pi) { | ||||
| 				if(Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]); | ||||
| 			for (pi = 0; pi < Keys.length; ++pi) { | ||||
| 				if (Object.prototype.hasOwnProperty.call(Keys, Keys[pi])) propaoa.push([Keys[pi], Keys[/*::+*/Keys[pi]]]); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -421,7 +421,11 @@ function hashq(str/*:string*/)/*:string*/ { | ||||
| 	} | ||||
| 	return o; | ||||
| } | ||||
| function rnd(val/*:number*/, d/*:number*/)/*:string*/ { var dd = Math.pow(10,d); return ""+(Math.round(val * dd)/dd); } | ||||
| function rnd(val/*:number*/, d/*:number*/)/*:string*/ { | ||||
| 	var sgn = val < 0 ? -1 : 1; | ||||
| 	var dd = Math.pow(10,d); | ||||
| 	return ""+sgn*(Math.round(sgn * val * dd)/dd); | ||||
| } | ||||
| function dec(val/*:number*/, d/*:number*/)/*:number*/ { | ||||
| 	var _frac = val - Math.floor(val), dd = Math.pow(10,d); | ||||
| 	if (d < ('' + Math.round(_frac * dd)).length) return 0; | ||||
|  | ||||
| @ -153,7 +153,13 @@ function utf8readb(data) { | ||||
| function utf8readc(data) { return Buffer_from(data, 'binary').toString('utf8'); } | ||||
| 
 | ||||
| var utf8corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3"; | ||||
| var utf8read = has_buf && (/*#__PURE__*/utf8readc(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readc || /*#__PURE__*/utf8readb(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readb) || utf8reada; | ||||
| var utf8read = /*#__PURE__*/(function() { | ||||
|   if(has_buf) { | ||||
|     if(utf8readc(utf8corpus) == utf8reada(utf8corpus)) return utf8readc; | ||||
|     if(utf8readb(utf8corpus) == utf8reada(utf8corpus)) return utf8readb; | ||||
|   } | ||||
|   return utf8reada; | ||||
| })(); | ||||
| 
 | ||||
| var utf8write/*:StringConv*/ = has_buf ? function(data) { return Buffer_from(data, 'utf8').toString("binary"); } : function(orig/*:string*/)/*:string*/ { | ||||
| 	var out/*:Array<string>*/ = [], i = 0, c = 0, d = 0; | ||||
|  | ||||
| @ -21,7 +21,8 @@ function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) { | ||||
| /* control buffer usage for fixed-length buffers */ | ||||
| function buf_array()/*:BufArray*/ { | ||||
| 	var bufs/*:Array<Block>*/ = [], blksz = has_buf ? 16384 : 2048; | ||||
| 	var has_buf_copy = has_buf && (typeof new_buf(blksz).copy == "function"); | ||||
| 	var has_buf_subarray = has_buf && (typeof new_buf(blksz).subarray == "function"); | ||||
| 
 | ||||
| 	var newblk = function ba_newblk(sz/*:number*/)/*:Block*/ { | ||||
| 		var o/*:Block*/ = (new_buf(sz)/*:any*/); | ||||
| 		prep_blob(o, 0); | ||||
| @ -55,7 +56,10 @@ function buf_array()/*:BufArray*/ { | ||||
| 	}; | ||||
| 
 | ||||
| 	var push = function ba_push(buf) { | ||||
| 		endbuf(); curbuf = buf; if(curbuf.l == null) curbuf.l = curbuf.length; next(blksz); | ||||
| 		if(curbuf.l > 0) bufs.push(curbuf.slice(0, curbuf.l)); | ||||
| 		bufs.push(buf); | ||||
| 		curbuf = has_buf_subarray ? curbuf.subarray(curbuf.l || 0) : curbuf.slice(curbuf.l || 0); | ||||
| 		prep_blob(curbuf, 0); | ||||
| 	}; | ||||
| 
 | ||||
| 	return ({ next:next, push:push, end:end, _bufs:bufs, end2:end2 }/*:any*/); | ||||
|  | ||||
| @ -1138,3 +1138,17 @@ function read_wb_ID(d, opts) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function read_wb_TABL(d, opts) { | ||||
| 	var o = opts || {}, OLD_WTF = !!o.WTF; o.WTF = true; | ||||
| 	try { | ||||
| 		var out = DIF.to_workbook(d, o); | ||||
| 		if(!out || !out.Sheets) throw "DIF bad workbook"; | ||||
| 		var ws = out.Sheets[out.SheetNames[0]]; | ||||
| 		if(!ws || !ws["!ref"]) throw "DIF empty worksheet"; | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		return out; | ||||
| 	} catch(e) { | ||||
| 		o.WTF = OLD_WTF; | ||||
| 		return PRN.to_workbook(d, opts); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -52,6 +52,10 @@ function parse_xlmeta_bin(data, name, _opts) { | ||||
|   var metatype = 2; | ||||
|   recordhopper(data, function(val, R, RT) { | ||||
|     switch (RT) { | ||||
|       case 58: | ||||
|         break; | ||||
|       case 59: | ||||
|         break; | ||||
|       case 335: | ||||
|         out.Types.push({ name: val.name }); | ||||
|         break; | ||||
|  | ||||
| @ -35,6 +35,7 @@ function parse_xlink_bin(data, rel, name/*:string*/, _opts) { | ||||
| 			case 0x0249: /* 'BrtSupNameFmla' */ | ||||
| 			case 0x024A: /* 'BrtSupNameBits' */ | ||||
| 			case 0x024B: /* 'BrtSupNameEnd' */ | ||||
| 			case 0x13F4: /* 'BrtExternalLinksAlternateUrls' */ | ||||
| 				break; | ||||
| 
 | ||||
| 			case 0x0023: /* 'BrtFRTBegin' */ | ||||
|  | ||||
| @ -23,9 +23,10 @@ var rc_to_a1 = /*#__PURE__*/(function(){ | ||||
| 	}; | ||||
| })(); | ||||
| 
 | ||||
| var crefregex = /(^|[^._A-Z0-9])(\$?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])(\$?)(\d{1,7})(?![_.\(A-Za-z0-9])/g; | ||||
| /* TODO: check if engines support \b */ | ||||
| var crefregex = /(^|[^._A-Za-z0-9])(\$?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])(\$?)(\d{1,7})(?![_.\(A-Za-z0-9])/g; | ||||
| try { | ||||
| 	crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)(10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6]|[1-9]\d{0,5})(?![_.\(A-Za-z0-9])/g; | ||||
| 	crefregex = /(^|[^._A-Za-z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)(10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6]|[1-9]\d{0,5})(?![_.\(A-Za-z0-9])/g; | ||||
| }catch(e){} | ||||
| var a1_to_rc = /*#__PURE__*/(function(){ | ||||
| 	return function a1_to_rc(fstr/*:string*/, base/*:CellAddress*/) { | ||||
|  | ||||
| @ -6,7 +6,7 @@ var mergecregex = /<(?:\w+:)?mergeCell ref=["'][A-Z0-9:]+['"]\s*[\/]?>/g; | ||||
| var hlinkregex = /<(?:\w+:)?hyperlink [^<>]*>/mg; | ||||
| var dimregex = /"(\w*:\w*)"/; | ||||
| var colregex = /<(?:\w+:)?col\b[^<>]*[\/]?>/g; | ||||
| var afregex = /<(?:\w+:)?autoFilter[^>]*/g; | ||||
| var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g; | ||||
| var marginregex= /<(?:\w+:)?pageMargins[^<>]*\/>/g; | ||||
| var sheetprregex = /<(?:\w+:)?sheetPr\b[^<>]*?\/>/; | ||||
| 
 | ||||
| @ -217,7 +217,7 @@ function write_ws_xml_cols(ws, cols)/*:string*/ { | ||||
| } | ||||
| 
 | ||||
| function parse_ws_xml_autofilter(data/*:string*/) { | ||||
| 	var o = { ref: (data.match(/ref="([^"]*)"/)||[])[1]}; | ||||
| 	var o = { ref: (data.match(/ref=["']([^"']*)["']/)||[])[1]}; | ||||
| 	return o; | ||||
| } | ||||
| function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ { | ||||
| @ -529,7 +529,7 @@ function write_ws_xml_data(ws/*:Worksheet*/, opts, idx/*:number*/, wb/*:Workbook | ||||
| 		r = []; | ||||
| 		rr = encode_row(R); | ||||
| 		var data_R = dense ? data[R] : []; | ||||
| 		for(C = range.s.c; C <= range.e.c; ++C) { | ||||
| 		if(data_R) for(C = range.s.c; C <= range.e.c; ++C) { | ||||
| 			ref = cols[C] + rr; | ||||
| 			var _cell = dense ? data_R[C] : ws[ref]; | ||||
| 			if(_cell === undefined) continue; | ||||
|  | ||||
| @ -505,7 +505,7 @@ function parse_BrtDVal(/*data, length, opts*/) { | ||||
| } | ||||
| function parse_BrtDVal14(/*data, length, opts*/) { | ||||
| } | ||||
| /* [MS-XLSB] 2.1.7.61 Worksheet */ | ||||
| /* [MS-XLSB] 2.1.7.62 Worksheet */ | ||||
| function parse_ws_bin(data, _opts, idx, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ { | ||||
| 	if(!data) return data; | ||||
| 	var opts = _opts || {}; | ||||
|  | ||||
| @ -856,6 +856,25 @@ var XLSBRecordEnum = { | ||||
| 	0x13E8: { /* n:"BrtEndCalcFeatures", */ T:-1 }, | ||||
| 	0x13E9: { /* n:"BrtCalcFeature" */ }, | ||||
| 	0x13EB: { /* n:"BrtExternalLinksPr" */ }, | ||||
| 	0x13EC: { /* n:"BrtPivotCacheImplicitMeasureSupport" */ }, | ||||
| 	0x13ED: { /* n:"BrtPivotFieldIgnorableAfter" */ }, | ||||
| 	0x13EE: { /* n:"BrtPivotHierarchyIgnorableAfter" */ }, | ||||
| 	0x13EF: { /* n:"BrtPivotDataFieldFutureData" */ }, | ||||
| 	0x13F1: { /* n:"BrtPivotCacheRichData" */ }, | ||||
| 	0x13F4: { /* n:"BrtExternalLinksAlternateUrls" */ }, | ||||
| 	0x13F5: { /* n:"BrtBeginPivotVersionInfo" */ }, | ||||
| 	0x13F6: { /* n:"BrtEndPivotVersionInfo" */ }, | ||||
| 	0x13F7: { /* n:"BrtBeginCacheVersionInfo" */ }, | ||||
| 	0x13F8: { /* n:"BrtEndCacheVersionInfo" */ }, | ||||
| 	0x13F9: { /* n:"BrtPivotRequiredFeature" */ }, | ||||
| 	0x13FA: { /* n:"BrtPivotLastUsedFeature" */ }, | ||||
| 	0x13FD: { /* n:"BrtExternalCodeService" */ }, | ||||
| 	0x1407: { /* n:"BrtShowDataTypeIcons" */ }, | ||||
| 	0x140A: { /* n:"BrtSXDIAggregation" */ }, | ||||
| 	0x140B: { /* n:"BrtPivotFieldFeatureSupportInfo" */ }, | ||||
| 	0x140C: { /* n:"BrtPivotCacheAutoRefresh" */ }, | ||||
| 	0x140E: { /* n:"BrtShowDataTypeIconsUserShView" */ }, | ||||
| 	0x140F: { /* n:"BrtWorkbookCompatibilityVersion" */ }, | ||||
| 	0xFFFF: { n:"" } | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -431,8 +431,54 @@ function write_FMTS_biff8(ba, NF/*:?SSFTable*/, opts) { | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| function write_ws_protect_biff8(sp) { | ||||
| 	/* SheetProtection */ | ||||
| 	var flags = 0x0000; | ||||
| 	[ | ||||
| 		["objects",             false, 0x0001], // fObjects - Bit 0 (Edit objects)
 | ||||
| 		["scenarios",           false, 0x0002], // fScenarios - Bit 1 (Edit scenarios)
 | ||||
| 		["formatCells",          true, 0x0004], // fFormatCells - Bit 2 (Change cell formatting)
 | ||||
| 		["formatColumns",        true, 0x0008], // fFormatColumns - Bit 3 (Change column formatting)
 | ||||
| 		["formatRows",           true, 0x0010], // fFormatRows - Bit 4 (Change row formatting)
 | ||||
| 		["insertColumns",        true, 0x0020], // fInsertColumns - Bit 5 (Insert columns)
 | ||||
| 		["insertRows",           true, 0x0040], // fInsertRows - Bit 6 (Insert rows)
 | ||||
| 		["insertHyperlinks",     true, 0x0080], // fInsertHyperlinks - Bit Bit 7 (Insert hyperlinks)
 | ||||
| 		["deleteColumns",        true, 0x0100], // fDeleteColumns - Bit 8 (Delete columns)
 | ||||
| 		["deleteRows",           true, 0x0200], // fDeleteRows - Bit 9 (Delete rows)
 | ||||
| 		["selectLockedCells",   false, 0x0400], // fSelLockedCells - Bit 10 (Select locked cells)
 | ||||
| 		["sort",                 true, 0x0800], // fSort - Bit 11 (Sort a cell range)
 | ||||
| 		["autoFilter",           true, 0x1000], // fAutoFilter - Bit 12 (Edit auto filters)
 | ||||
| 		["pivotTables",          true, 0x2000], // fPivotTables - Bit 13 (Edit PivotTables)
 | ||||
| 		["selectUnlockedCells", false, 0x4000]  // fSelUnlockedCells - Bit 14 (Select unlocked cells)
 | ||||
| 	].forEach(function(n) { | ||||
| 		if(n[1]) flags |= sp[n[0]] != null && !sp[n[0]] ? n[2] : 0x0000; | ||||
| 		else     flags |= sp[n[0]] != null && sp[n[0]] ? 0x0000 : n[2]; | ||||
| 	}); | ||||
| 
 | ||||
| 	/* [MS-XLS] 2.4.112 */ | ||||
| 	var featHdr = new_buf(23); | ||||
| 	/* [MS-XLS] 2.5.135 */ | ||||
| 	featHdr.write_shift(2, 0x0867); | ||||
| 	featHdr.write_shift(2, 0x0000); | ||||
| 	featHdr.write_shift(4, 0x00000000); | ||||
| 	featHdr.write_shift(4, 0x00000000); | ||||
| 	/* [MS-XLS] 2.5.237 */ | ||||
| 	featHdr.write_shift(2, 0x0002); // SharedFeatureType ISFPROTECTION
 | ||||
| 	/* Reserved byte */ | ||||
| 	featHdr.write_shift(1, 0x01); | ||||
| 	/* cbHdrData */ | ||||
| 	featHdr.write_shift(4, 0xffffffff); | ||||
| 	/* [MS-XLS] 2.5.104 */ | ||||
| 	featHdr.write_shift(4, flags); | ||||
| 
 | ||||
| 	return featHdr; | ||||
| } | ||||
| 
 | ||||
| function write_FEAT(ba, ws) { | ||||
| 	/* [MS-XLS] 2.4.112 */ | ||||
| 	/* ISFPROTECTION */ | ||||
| 	if(ws['!protect']) write_biff_rec(ba, 0x0867 /* FeatHdr */, write_ws_protect_biff8(ws['!protect'])); | ||||
| 	/* ISFFEC2 */ | ||||
| 	var o = new_buf(19); | ||||
| 	o.write_shift(4, 0x867); o.write_shift(4, 0); o.write_shift(4, 0); | ||||
| 	o.write_shift(2, 3); o.write_shift(1, 1); o.write_shift(4, 0); | ||||
| @ -537,6 +583,14 @@ function write_ws_biff8(idx/*:number*/, opts, wb/*:Workbook*/) { | ||||
| 	/* Footer (string) */ | ||||
| 	write_biff_rec(ba, 0x0083 /* HCenter */, writebool(false)); | ||||
| 	write_biff_rec(ba, 0x0084 /* VCenter */, writebool(false)); | ||||
| 	/* PROTECTION */ | ||||
| 	if(ws['!protect']){ | ||||
| 		var sp = ws['!protect']; | ||||
| 		/* [MS-XLS] 2.4.207 */ | ||||
| 		write_biff_rec(ba, 0x0012 /* Protect */, writeuint16(1)); | ||||
| 		/* [MS-XLS] 2.4.191 */ | ||||
| 		if(sp.password) write_biff_rec(ba, 0x0013 /* Password */, writeuint16(crypto_CreatePasswordVerifier_Method1(sp.password))); | ||||
| 	} | ||||
| 	/* ... */ | ||||
| 	if(b8) write_ws_cols_biff8(ba, ws["!cols"]); | ||||
| 	/* ... */ | ||||
|  | ||||
| @ -137,12 +137,6 @@ function sheet_to_html(ws/*:Worksheet*/, opts/*:?Sheet2HTMLOpts*//*, wb:?Workboo | ||||
| } | ||||
| 
 | ||||
| function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/*:Worksheet*/ { | ||||
| 	var rows/*:HTMLCollection<HTMLTableRowElement>*/ = table.rows; | ||||
| 	if(!rows) { | ||||
| 		/* not an HTML TABLE */ | ||||
| 		throw "Unsupported origin when " + table.tagName + " is not a TABLE"; | ||||
| 	} | ||||
| 
 | ||||
| 	var opts = _opts || {}; | ||||
| 	var dense = ws["!data"] != null; | ||||
| 	var or_R = 0, or_C = 0; | ||||
| @ -154,7 +148,6 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/ | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	var sheetRows = Math.min(opts.sheetRows||10000000, rows.length); | ||||
| 	var range/*:Range*/ = {s:{r:0,c:0},e:{r:or_R,c:or_C}}; | ||||
| 	if(ws["!ref"]) { | ||||
| 		var _range/*:Range*/ = decode_range(ws["!ref"]); | ||||
| @ -164,6 +157,15 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/ | ||||
| 		range.e.c = Math.max(range.e.c, _range.e.c); | ||||
| 		if(or_R == -1) range.e.r = or_R = _range.e.r + 1; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	var rows/*:HTMLCollection<HTMLTableRowElement>*/ = table.rows; | ||||
| 	if(!rows) { | ||||
| 		/* not an HTML TABLE */ | ||||
| 		throw "Unsupported origin when " + table.tagName + " is not a TABLE"; | ||||
| 	} | ||||
| 	var sheetRows = Math.min(opts.sheetRows||10000000, rows.length); | ||||
| 
 | ||||
| 	var merges/*:Array<Range>*/ = [], midx = 0; | ||||
| 	var rowinfo/*:Array<RowInfo>*/ = ws["!rows"] || (ws["!rows"] = []); | ||||
| 	var _R = 0, R = 0, _C = 0, C = 0, RS = 0, CS = 0; | ||||
| @ -187,7 +189,9 @@ function sheet_add_dom(ws/*:Worksheet*/, table/*:HTMLElement*/, _opts/*:?any*/)/ | ||||
| 			} | ||||
| 			/* TODO: figure out how to extract nonstandard mso- style */ | ||||
| 			CS = +elt.getAttribute("colspan") || 1; | ||||
| 			if( ((RS = (+elt.getAttribute("rowspan") || 1)))>1 || CS>1) merges.push({s:{r:R + or_R,c:C + or_C},e:{r:R + or_R + (RS||1) - 1, c:C + or_C + (CS||1) - 1}}); | ||||
| 			if( ((RS = (+elt.getAttribute("rowspan") || 1)))>1 || CS>1) { | ||||
| 				merges.push({s:{r:R + or_R,c:C + or_C},e:{r:R + or_R + (RS||1) - 1, c:C + or_C + (CS||1) - 1}}); | ||||
| 			} | ||||
| 			var o/*:Cell*/ = {t:'s', v:v}; | ||||
| 			var _t/*:string*/ = elt.getAttribute("data-t") || elt.getAttribute("t") || ""; | ||||
| 			if(v != null) { | ||||
|  | ||||
| @ -205,7 +205,7 @@ function parse_ods_styles(d/*:string*/, _opts, _nfm) { | ||||
| 			// TODO: handle more complex maps
 | ||||
| 			y = parsexmltag(Rn[0], false); | ||||
| 			if(unescapexml(y["condition"]) == "value()>=0") NF = number_format_map[y["apply-style-name"]] + ";" + NF; | ||||
| 			else console.error("ODS number format may be incorrect: " + y["condition"]); | ||||
| 			else if(_opts && _opts.WTF) console.error("ODS number format may be incorrect: " + y["condition"]); | ||||
| 			break; | ||||
| 
 | ||||
| 		case 'number': // <number:number> 16.29.3
 | ||||
| @ -764,6 +764,10 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ { | ||||
| 						_Ref = ods_to_csf_3D(atag.Target.slice(1)); | ||||
| 						atag.Target = "#" + _Ref[0] + "!" + _Ref[1]; | ||||
| 					} else if(atag.Target.match(/^\.\.[\\\/]/)) atag.Target = atag.Target.slice(3); | ||||
| 					/* Appendix D.2 Hyperlink Titles */ | ||||
| 					if(atag.title) { | ||||
| 						atag.Tooltip = unescapexml(atag.title); delete atag.title; | ||||
| 					} | ||||
| 				} | ||||
| 				break; | ||||
| 
 | ||||
|  | ||||
| @ -99,7 +99,7 @@ function readSync(data/*:RawData*/, opts/*:?ParseOpts*/)/*:Workbook*/ { | ||||
| 			if(n[1] === 0x49 && n[2] === 0x2a && n[3] === 0x00) throw new Error("TIFF Image File is not a spreadsheet"); | ||||
| 			if(n[1] === 0x44) return read_wb_ID(d, o); | ||||
| 			break; | ||||
| 		case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o); break; | ||||
| 		case 0x54: if(n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return read_wb_TABL(d, o); break; | ||||
| 		case 0x50: return (n[1] === 0x4B && n[2] < 0x09 && n[3] < 0x09) ? read_zip(d, o) : read_prn(data, d, o, str); | ||||
| 		case 0xEF: return n[3] === 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str); | ||||
| 		case 0xFF: | ||||
|  | ||||
| @ -111,7 +111,7 @@ function write_binary_type(out, opts/*:WriteOpts*/)/*:any*/ { | ||||
| 
 | ||||
| function writeSyncXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/) { | ||||
| 	reset_cp(); | ||||
| 	check_wb(wb); | ||||
| 	if(!opts || !opts.unsafe) check_wb(wb); | ||||
| 	var o = dup(opts||{}); | ||||
| 	if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; } | ||||
| 	if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSyncXLSX(wb, o)/*:any*/); o.type = "array"; return s2ab(out); } | ||||
| @ -120,7 +120,7 @@ function writeSyncXLSX(wb/*:Workbook*/, opts/*:?WriteOpts*/) { | ||||
| 
 | ||||
| function writeSync(wb/*:Workbook*/, opts/*:?WriteOpts*/) { | ||||
| 	reset_cp(); | ||||
| 	check_wb(wb); | ||||
| 	if(!opts || !opts.unsafe) check_wb(wb); | ||||
| 	var o = dup(opts||{}); | ||||
| 	if(o.cellStyles) { o.cellNF = true; o.sheetStubs = true; } | ||||
| 	if(o.type == "array") { o.type = "binary"; var out/*:string*/ = (writeSync(wb, o)/*:any*/); o.type = "array"; return s2ab(out); } | ||||
|  | ||||
| @ -24,7 +24,7 @@ function make_json_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Ar | ||||
| 		switch(val.t){ | ||||
| 			case 'z': if(v == null) break; continue; | ||||
| 			case 'e': v = (v == 0 ? null : void 0); break; | ||||
| 			case 's': case 'b': | ||||
| 			case 's': case 'b': break; | ||||
| 			case 'n': if(!val.z || !fmt_is_date(val.z)) break; | ||||
| 			v = numdate(v); // TODO: date1904 setting should also be stored in worksheet object
 | ||||
| 			if(typeof v == "number") break; | ||||
| @ -116,7 +116,7 @@ function make_csv_row(sheet/*:Worksheet*/, r/*:Range*/, R/*:number*/, cols/*:Arr | ||||
| 		else if(val.v != null) { | ||||
| 			isempty = false; | ||||
| 			txt = ''+(o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o)); | ||||
| 			for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			for(var i = 0, cc = 0; i !== txt.length; ++i) if((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 10 ||cc === 13 ||  cc === 34 || o.forceQuotes) {txt = "\"" + txt.replace(qreg, '""') + "\""; break; } | ||||
| 			if(txt == "ID" && w == 0 && row.length == 0) txt = '"ID"'; | ||||
| 		} else if(val.f != null && !val.F) { | ||||
| 			isempty = false; | ||||
|  | ||||
| @ -52,6 +52,10 @@ function parse_xlmeta_bin(data, name, _opts) { | ||||
|   var metatype = 2; | ||||
|   recordhopper(data, function(val, R, RT) { | ||||
|     switch (RT) { | ||||
|       case 58: | ||||
|         break; | ||||
|       case 59: | ||||
|         break; | ||||
|       case 335: | ||||
|         out.Types.push({ name: val.name }); | ||||
|         break; | ||||
|  | ||||
| @ -73,15 +73,37 @@ function parse_xlmeta_bin(data: RawData, name: string, _opts?: ParseXLMetaOption | ||||
| 			// case 0x014D: /* BrtEndMetadata */
 | ||||
| 			// case 0x014E: /* BrtBeginEsmdtinfo */
 | ||||
| 			// case 0x0150: /* BrtEndEsmdtinfo */
 | ||||
| 			// case 0x0151: /* BrtBeginEsmdb */
 | ||||
| 			// case 0x0152: /* BrtEndEsmdb */
 | ||||
| 			// case 0x0153: /* BrtBeginEsfmd */
 | ||||
| 			// case 0x0154: /* BrtEndEsfmd */
 | ||||
| 			// case 0x0174: /* BrtBeginEsmdx */
 | ||||
| 			// case 0x0175: /* BrtEndEsmdx */
 | ||||
| 			// case 0x0176: /* BrtBeginMdxSet */
 | ||||
| 			// case 0x0177: /* BrtEndMdxSet */
 | ||||
| 			// case 0x0178: /* BrtBeginMdxMbrProp */
 | ||||
| 			// case 0x0179: /* BrtEndMdxMbrProp */
 | ||||
| 			// case 0x017A: /* BrtBeginMdxKPI */
 | ||||
| 			// case 0x017B: /* BrtEndMdxKPI */
 | ||||
| 			// case 0x017C: /* BrtBeginEsstr */
 | ||||
| 			// case 0x017D: /* BrtEndEsstr */
 | ||||
| 			// case 0x0034: /* BrtBeginFmd */
 | ||||
| 			// case 0x0035: /* BrtEndFmd */
 | ||||
| 			// case 0x0036: /* BrtBeginMdx */
 | ||||
| 			// case 0x0037: /* BrtEndMdx */
 | ||||
| 			// case 0x0038: /* BrtBeginMdxTuple */
 | ||||
| 			// case 0x0039: /* BrtEndMdxTuple */
 | ||||
| 			// case 0x1000: /* BrtBeginDynamicArrayPr */
 | ||||
| 			// case 0x1001: /* BrtEndDynamicArrayPr */
 | ||||
| 			// case 0x138A: /* BrtBeginRichValueBlock */
 | ||||
| 			// case 0x138B: /* BrtEndRichValueBlock */
 | ||||
| 
 | ||||
| 			case 0x003A: /* BrtMdxMbrIstr */ | ||||
| 				break; | ||||
| 
 | ||||
| 			case 0x003B: /* BrtStr */ | ||||
| 				break; | ||||
| 
 | ||||
| 			case 0x014F: /* BrtMdtinfo */ | ||||
| 				out.Types.push({name: (val as BrtMdtinfo).name}); break; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										5
									
								
								test.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								test.js
									
									
									
									
									
								
							| @ -3104,6 +3104,11 @@ describe('corner cases', function() { | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 	(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() { | ||||
| 		var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE}); | ||||
| 		var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]); | ||||
| 		assert.equal(formulae[4], 'A5=nvRTX6090'); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('encryption', function() { | ||||
|  | ||||
							
								
								
									
										5
									
								
								test.mjs
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								test.mjs
									
									
									
										generated
									
									
									
								
							| @ -3103,6 +3103,11 @@ describe('corner cases', function() { | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 	(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() { | ||||
| 		var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE}); | ||||
| 		var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]); | ||||
| 		assert.equal(formulae[4], 'A5=nvRTX6090'); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('encryption', function() { | ||||
|  | ||||
							
								
								
									
										33
									
								
								test.mts
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										33
									
								
								test.mts
									
									
									
									
									
								
							| @ -9,10 +9,10 @@ declare type EmptyFunc = (() => void) | null; | ||||
| declare var afterEach:(test:EmptyFunc)=>void; | ||||
| declare var cptable: any; | ||||
| */ | ||||
| import * as assert_ from 'https://deno.land/std/testing/asserts.ts'; | ||||
| import * as base64_ from 'https://deno.land/std/encoding/base64.ts'; | ||||
| import * as assert_ from 'https://deno.land/std@0.169.0/testing/asserts.ts'; | ||||
| import * as base64_ from 'https://deno.land/std@0.169.0/encoding/base64.ts'; | ||||
| const assert: any = {...assert_}; | ||||
| assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e); }})}; | ||||
| assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e as string); }})}; | ||||
| assert.doesNotThrow = function(f: ()=>void) { f(); }; | ||||
| assert.equal = assert.assertEquals; | ||||
| assert.notEqual = assert.assertNotEquals; | ||||
| @ -36,7 +36,7 @@ function readFileSync2(x: string, e?: ShEncoding): Uint8Array | string { | ||||
| 	if(!e) return u8; | ||||
| 	switch(e) { | ||||
| 		case 'utf-8': return new TextDecoder().decode(u8); | ||||
| 		case 'base64': return base64_.encode(u8); | ||||
| 		case 'base64': return base64_.encode(u8 as any); | ||||
| 		case 'buffer': return u8; | ||||
| 		case 'binary': return Array.from({length: u8.length}, (_,i) => String.fromCharCode(u8[i])).join(""); | ||||
| 	} | ||||
| @ -2724,7 +2724,7 @@ describe('dense mode', function() { | ||||
| 			wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true}); | ||||
| 			ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 			assert.ok(!ws["A1"]); | ||||
| 			assert.equal(ws["!data"]?.[0][0].v, "Link to Sheet2"); | ||||
| 			assert.equal(ws["!data"]?.[0]![0]!.v, "Link to Sheet2"); | ||||
| 		}); | ||||
| 		if(!browser) artifax.forEach(function(p) { | ||||
| 			var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true}); | ||||
| @ -2736,7 +2736,7 @@ describe('dense mode', function() { | ||||
| 			ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 			assert.ok(!ws["A1"]); | ||||
| 			assert.ok(!!ws["!data"]); | ||||
| 			assert.ok(ws["!data"]?.[0][0]); | ||||
| 			assert.ok(ws["!data"]?.[0]![0]); | ||||
| 		}); | ||||
| 	}); | ||||
| 	it('aoa_to_sheet', function() { | ||||
| @ -2744,28 +2744,28 @@ describe('dense mode', function() { | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]); | ||||
| 	}); | ||||
| 	it('json_to_sheet', function() { | ||||
| 		var json = [{"SheetJS": 5433795}]; | ||||
| 		var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]); | ||||
| 	}); | ||||
| 	it('sheet_add_aoa', function() { | ||||
| 		var aoa = [["SheetJS"]]; | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]); | ||||
| 	}); | ||||
| 	it('sheet_add_json', function() { | ||||
| 		var aoa = [["SheetJS"]]; | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.ok(!sp["!data"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.ok(!ds["A2"]); | ||||
| 	}); | ||||
| 	for(var ofmti = 0; ofmti < ofmt.length; ++ofmti) { var f = ofmt[ofmti]; | ||||
| 	it('write ' + f, function() { | ||||
| @ -3022,6 +3022,11 @@ describe('corner cases', function() { | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 	if(fs.existsSync(dir + 'shared_formula.xlsx')) it('should properly handle defined names in shared formulae', function() { | ||||
| 		var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE}); | ||||
| 		var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]); | ||||
| 		assert.equal(formulae[4], 'A5=nvRTX6090'); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('encryption', function() { | ||||
| @ -3033,14 +3038,14 @@ describe('encryption', function() { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:TYPE,password:'Password',WTF:opts.WTF}); | ||||
| 					throw new Error("incorrect password was accepted"); | ||||
| 				} catch(e) { | ||||
| 					if(e.message != "Password is incorrect") throw e; | ||||
| 					if((e as any).message != "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			it('should recognize correct password', function() { | ||||
| 				try { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF}); | ||||
| 				} catch(e) { | ||||
| 					if(e.message == "Password is incorrect") throw e; | ||||
| 					if((e as any).message == "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			if(false) it('should decrypt file', function() { | ||||
|  | ||||
							
								
								
									
										19
									
								
								test.sh
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										19
									
								
								test.sh
									
									
									
									
									
								
							| @ -2,8 +2,12 @@ | ||||
| set -euxo pipefail | ||||
| TZONES=(America/New_York Europe/London Asia/Seoul America/Los_Angeles Europe/Berlin Asia/Kolkata Asia/Shanghai America/Cancun America/Anchorage America/Barbados Asia/Tokyo  America/Cayman Pacific/Honolulu America/Mexico_City Asia/Hong_Kong Europe/Paris Atlantic/Azores) | ||||
| 
 | ||||
| export NVM_DIR="$HOME/.nvm" | ||||
| [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm | ||||
| 
 | ||||
| if [ -e datetest.js ]; then | ||||
| 	sudo n 20; | ||||
| 	nvm use 20 | ||||
| 	# sudo n 20; | ||||
| 	for TZ in ${TZONES[@]}; do | ||||
| 		echo "$TZ" | ||||
| 		env TZ="$TZ" mocha -R dot datetest.js | ||||
| @ -11,19 +15,22 @@ if [ -e datetest.js ]; then | ||||
| fi | ||||
| 
 | ||||
| # min test  | ||||
| for n in 20 10 0.8 0.10 0.12 4 6 8 12 14 16 18; do | ||||
| 	sudo n $n | ||||
| for n in 20 10 0.8 0.10 0.12 4 6 8 12 14 16 18 22 24; do | ||||
| 	nvm use $n | ||||
| 	# sudo n $n | ||||
| 	env WTF=1 make testdot_misc | ||||
| 	for TZ in ${TZONES[@]}; do | ||||
| 		sudo n $n | ||||
| 		# sudo n $n | ||||
| 		nvm use $n | ||||
| 		env WTF=1 TZ="$TZ" make testdot_misc | ||||
| 	done | ||||
| done | ||||
| 
 | ||||
| # full test | ||||
| for n in 20 10 0.12; do | ||||
| for n in 24 16 0.12; do | ||||
| 	for TZ in America/New_York Asia/Seoul Asia/Kolkata Europe/Paris; do | ||||
| 		sudo n $n | ||||
| 		# sudo n $n | ||||
| 		nvm use $n | ||||
| 		env WTF=1 TZ="$TZ" make testdot | ||||
| 	done | ||||
| done | ||||
|  | ||||
							
								
								
									
										5
									
								
								test.test.mjs
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								test.test.mjs
									
									
									
										generated
									
									
									
								
							| @ -3103,6 +3103,11 @@ describe('corner cases', function() { | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 	(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() { | ||||
| 		var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE}); | ||||
| 		var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]); | ||||
| 		assert.equal(formulae[4], 'A5=nvRTX6090'); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('encryption', function() { | ||||
|  | ||||
							
								
								
									
										33
									
								
								test.ts
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										33
									
								
								test.ts
									
									
									
									
									
								
							| @ -9,10 +9,10 @@ declare type EmptyFunc = (() => void) | null; | ||||
| declare var afterEach:(test:EmptyFunc)=>void; | ||||
| declare var cptable: any; | ||||
| */ | ||||
| import * as assert_ from 'https://deno.land/std/testing/asserts.ts'; | ||||
| import * as base64_ from 'https://deno.land/std/encoding/base64.ts'; | ||||
| import * as assert_ from 'https://deno.land/std@0.169.0/testing/asserts.ts'; | ||||
| import * as base64_ from 'https://deno.land/std@0.169.0/encoding/base64.ts'; | ||||
| const assert: any = {...assert_}; | ||||
| assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e); }})}; | ||||
| assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e as string); }})}; | ||||
| assert.doesNotThrow = function(f: ()=>void) { f(); }; | ||||
| assert.equal = assert.assertEquals; | ||||
| assert.notEqual = assert.assertNotEquals; | ||||
| @ -36,7 +36,7 @@ function readFileSync2(x: string, e?: ShEncoding): Uint8Array | string { | ||||
| 	if(!e) return u8; | ||||
| 	switch(e) { | ||||
| 		case 'utf-8': return new TextDecoder().decode(u8); | ||||
| 		case 'base64': return base64_.encode(u8); | ||||
| 		case 'base64': return base64_.encode(u8 as any); | ||||
| 		case 'buffer': return u8; | ||||
| 		case 'binary': return Array.from({length: u8.length}, (_,i) => String.fromCharCode(u8[i])).join(""); | ||||
| 	} | ||||
| @ -2724,7 +2724,7 @@ Deno.test('dense mode', async function(t) { | ||||
| 			wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true}); | ||||
| 			ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 			assert.assert(!ws["A1"]); | ||||
| 			assert.equal(ws["!data"]?.[0][0].v, "Link to Sheet2"); | ||||
| 			assert.equal(ws["!data"]?.[0]![0]!.v, "Link to Sheet2"); | ||||
| 		}); | ||||
| 		if(!browser) artifax.forEach(function(p) { | ||||
| 			var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true}); | ||||
| @ -2736,7 +2736,7 @@ Deno.test('dense mode', async function(t) { | ||||
| 			ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 			assert.assert(!ws["A1"]); | ||||
| 			assert.assert(!!ws["!data"]); | ||||
| 			assert.assert(ws["!data"]?.[0][0]); | ||||
| 			assert.assert(ws["!data"]?.[0]![0]); | ||||
| 		}); | ||||
| 	}); | ||||
| 	await t.step('aoa_to_sheet', async function(t) { | ||||
| @ -2744,28 +2744,28 @@ Deno.test('dense mode', async function(t) { | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	await t.step('json_to_sheet', async function(t) { | ||||
| 		var json = [{"SheetJS": 5433795}]; | ||||
| 		var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	await t.step('sheet_add_aoa', async function(t) { | ||||
| 		var aoa = [["SheetJS"]]; | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	await t.step('sheet_add_json', async function(t) { | ||||
| 		var aoa = [["SheetJS"]]; | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	for(var ofmti = 0; ofmti < ofmt.length; ++ofmti) { var f = ofmt[ofmti]; | ||||
| 	await t.step('write ' + f, async function(t) { | ||||
| @ -3022,6 +3022,11 @@ Deno.test('corner cases', async function(t) { | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 	if(fs.existsSync(dir + 'shared_formula.xlsx')) await t.step('should properly handle defined names in shared formulae', async function(t) { | ||||
| 		var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE}); | ||||
| 		var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]); | ||||
| 		assert.equal(formulae[4], 'A5=nvRTX6090'); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| Deno.test('encryption', async function(t) { | ||||
| @ -3033,14 +3038,14 @@ Deno.test('encryption', async function(t) { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:TYPE,password:'Password',WTF:opts.WTF}); | ||||
| 					throw new Error("incorrect password was accepted"); | ||||
| 				} catch(e) { | ||||
| 					if(e.message != "Password is incorrect") throw e; | ||||
| 					if((e as any).message != "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			await t.step('should recognize correct password', async function(t) { | ||||
| 				try { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF}); | ||||
| 				} catch(e) { | ||||
| 					if(e.message == "Password is incorrect") throw e; | ||||
| 					if((e as any).message == "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			if(false) await t.step('should decrypt file', async function(t) { | ||||
|  | ||||
							
								
								
									
										33
									
								
								testnocp.ts
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										33
									
								
								testnocp.ts
									
									
									
									
									
								
							| @ -9,10 +9,10 @@ declare type EmptyFunc = (() => void) | null; | ||||
| declare var afterEach:(test:EmptyFunc)=>void; | ||||
| declare var cptable: any; | ||||
| */ | ||||
| import * as assert_ from 'https://deno.land/std/testing/asserts.ts'; | ||||
| import * as base64_ from 'https://deno.land/std/encoding/base64.ts'; | ||||
| import * as assert_ from 'https://deno.land/std@0.169.0/testing/asserts.ts'; | ||||
| import * as base64_ from 'https://deno.land/std@0.169.0/encoding/base64.ts'; | ||||
| const assert: any = {...assert_}; | ||||
| assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e); }})}; | ||||
| assert.throws = function(f: () => void) { assert.assertThrows(function() { try { f(); } catch(e) { throw e instanceof Error ? e : new Error(e as string); }})}; | ||||
| assert.doesNotThrow = function(f: ()=>void) { f(); }; | ||||
| assert.equal = assert.assertEquals; | ||||
| assert.notEqual = assert.assertNotEquals; | ||||
| @ -35,7 +35,7 @@ function readFileSync2(x: string, e?: ShEncoding): Uint8Array | string { | ||||
| 	if(!e) return u8; | ||||
| 	switch(e) { | ||||
| 		case 'utf-8': return new TextDecoder().decode(u8); | ||||
| 		case 'base64': return base64_.encode(u8); | ||||
| 		case 'base64': return base64_.encode(u8 as any); | ||||
| 		case 'buffer': return u8; | ||||
| 		case 'binary': return Array.from({length: u8.length}, (_,i) => String.fromCharCode(u8[i])).join(""); | ||||
| 	} | ||||
| @ -2723,7 +2723,7 @@ Deno.test('dense mode', async function(t) { | ||||
| 			wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true, dense: true}); | ||||
| 			ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 			assert.assert(!ws["A1"]); | ||||
| 			assert.equal(ws["!data"]?.[0][0].v, "Link to Sheet2"); | ||||
| 			assert.equal(ws["!data"]?.[0]![0]!.v, "Link to Sheet2"); | ||||
| 		}); | ||||
| 		if(!browser) artifax.forEach(function(p) { | ||||
| 			var wb = X.read(fs.readFileSync(p), {type: TYPE, WTF: true}); | ||||
| @ -2735,7 +2735,7 @@ Deno.test('dense mode', async function(t) { | ||||
| 			ws = wb.Sheets[wb.SheetNames[0]]; | ||||
| 			assert.assert(!ws["A1"]); | ||||
| 			assert.assert(!!ws["!data"]); | ||||
| 			assert.assert(ws["!data"]?.[0][0]); | ||||
| 			assert.assert(ws["!data"]?.[0]![0]); | ||||
| 		}); | ||||
| 	}); | ||||
| 	await t.step('aoa_to_sheet', async function(t) { | ||||
| @ -2743,28 +2743,28 @@ Deno.test('dense mode', async function(t) { | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds = X.utils.aoa_to_sheet(aoa, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	await t.step('json_to_sheet', async function(t) { | ||||
| 		var json = [{"SheetJS": 5433795}]; | ||||
| 		var sp = X.utils.json_to_sheet(json); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.json_to_sheet(json, {}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.json_to_sheet(json, {dense: false}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds = X.utils.json_to_sheet(json, {dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	await t.step('sheet_add_aoa', async function(t) { | ||||
| 		var aoa = [["SheetJS"]]; | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_aoa(sp, [[5433795]], {origin:-1, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_aoa(ds, [[5433795]], {origin:-1, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	await t.step('sheet_add_json', async function(t) { | ||||
| 		var aoa = [["SheetJS"]]; | ||||
| 		var sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader:true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		sp = X.utils.aoa_to_sheet(aoa); X.utils.sheet_add_json(sp, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(sp["A2"].v, 5433795); assert.assert(!sp["!data"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1][0].v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		var ds:X.WorkSheet = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 		ds = X.utils.aoa_to_sheet(aoa, {dense: true}); X.utils.sheet_add_json(ds, [{X:5433795}], {origin:-1, skipHeader: true, dense: true}); assert.equal(ds["!data"]?.[1]![0]!.v, 5433795); assert.assert(!ds["A2"]); | ||||
| 	}); | ||||
| 	for(var ofmti = 0; ofmti < ofmt.length; ++ofmti) { var f = ofmt[ofmti]; | ||||
| 	await t.step('write ' + f, async function(t) { | ||||
| @ -3021,6 +3021,11 @@ Deno.test('corner cases', async function(t) { | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 	if(fs.existsSync(dir + 'shared_formula.xlsx')) await t.step('should properly handle defined names in shared formulae', async function(t) { | ||||
| 		var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE}); | ||||
| 		var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]); | ||||
| 		assert.equal(formulae[4], 'A5=nvRTX6090'); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| Deno.test('encryption', async function(t) { | ||||
| @ -3032,14 +3037,14 @@ Deno.test('encryption', async function(t) { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:TYPE,password:'Password',WTF:opts.WTF}); | ||||
| 					throw new Error("incorrect password was accepted"); | ||||
| 				} catch(e) { | ||||
| 					if(e.message != "Password is incorrect") throw e; | ||||
| 					if((e as any).message != "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			await t.step('should recognize correct password', async function(t) { | ||||
| 				try { | ||||
| 					X.read(fs.readFileSync(dir + x), {type:TYPE,password:'password',WTF:opts.WTF}); | ||||
| 				} catch(e) { | ||||
| 					if(e.message == "Password is incorrect") throw e; | ||||
| 					if((e as any).message == "Password is incorrect") throw e; | ||||
| 				} | ||||
| 			}); | ||||
| 			if(false) await t.step('should decrypt file', async function(t) { | ||||
|  | ||||
							
								
								
									
										5
									
								
								tests/core.js
									
									
									
										generated
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								tests/core.js
									
									
									
										generated
									
									
									
								
							| @ -3102,6 +3102,11 @@ describe('corner cases', function() { | ||||
| 			} | ||||
| 		}); | ||||
| 	}); | ||||
| 	(fs.existsSync(dir + 'shared_formula.xlsx') ? it : it.skip)('should properly handle defined names in shared formulae', function() { | ||||
| 		var wb = X.read(fs.readFileSync(dir + 'shared_formula.xlsx'), {type:TYPE}); | ||||
| 		var formulae = X.utils.sheet_to_formulae(wb.Sheets[wb.SheetNames[0]]); | ||||
| 		assert.equal(formulae[4], 'A5=nvRTX6090'); | ||||
| 	}); | ||||
| }); | ||||
| 
 | ||||
| describe('encryption', function() { | ||||
|  | ||||
							
								
								
									
										3
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								types/index.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -317,6 +317,9 @@ export interface WritingOptions extends CommonOptions { | ||||
| 
 | ||||
|     /** Record Separator ("row separator") for CSV / Text output */ | ||||
|     RS?: string; | ||||
| 
 | ||||
|     /** Skip certain validity checks (NOTE: generated files may not open in Excel) */ | ||||
|     unsafe?: boolean; | ||||
| } | ||||
| 
 | ||||
| /** Workbook Object */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user