16 Commits

Author SHA1 Message Date
ab1c84f41f 1.0.22 2019-12-15 18:30:47 +00:00
6f575e8516 fix(core): update 2019-12-15 18:30:46 +00:00
d11f237221 1.0.21 2019-12-15 18:18:40 +00:00
16826ed337 fix(core): update 2019-12-15 18:18:39 +00:00
c49b518b8a 1.0.20 2019-12-15 18:15:04 +00:00
5f49532fc2 fix(core): update 2019-12-15 18:15:03 +00:00
e7f06a7f44 1.0.19 2019-10-11 15:48:23 +02:00
491477da82 fix(core): update 2019-10-11 15:48:23 +02:00
935109abb6 1.0.18 2019-10-10 18:30:29 +02:00
ea26a1d8ef fix(core): update 2019-10-10 18:30:29 +02:00
c7324f0240 1.0.17 2019-07-08 16:57:46 +02:00
be44a1354b fix(core): update 2019-07-08 16:57:45 +02:00
13f3f7b2f6 1.0.16 2019-05-23 17:28:21 +02:00
94f2620161 fix(core): update 2019-05-23 17:28:21 +02:00
bdebb3308c 1.0.15 2018-10-14 23:30:19 +02:00
cb5ac7618b fix(snyk): add snyk policy 2018-10-14 23:30:19 +02:00
12 changed files with 1447 additions and 455 deletions

18
.gitignore vendored
View File

@@ -1,6 +1,22 @@
.nogit/ .nogit/
node_modules/
# artifacts
coverage/ coverage/
public/ public/
pages/ pages/
# installs
node_modules/
# caches
.yarn/ .yarn/
.cache/
.rpt2_cache
# builds
dist/
dist_web/
dist_serve/
dist_ts_web/
# custom

View File

@@ -1,10 +1,10 @@
# gitzone standard # gitzone ci_default
image: hosttoday/ht-docker-node:npmci image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache: cache:
paths: paths:
- .npmci_cache/ - .npmci_cache/
key: "$CI_BUILD_STAGE" key: '$CI_BUILD_STAGE'
stages: stages:
- security - security
@@ -20,49 +20,27 @@ mirror:
script: script:
- npmci git mirror - npmci git mirror
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
snyk: snyk:
image: registry.gitlab.com/hosttoday/ht-docker-node:snyk
stage: security stage: security
script: script:
- npmci npm prepare - npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts - npmci command npm install --ignore-scripts
- npmci command snyk test - npmci command snyk test
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
# ==================== # ====================
# test stage # test stage
# ==================== # ====================
testLEGACY:
stage: test
script:
- npmci npm prepare
- npmci node install legacy
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
allow_failure: true
testLTS: testStable:
stage: test
script:
- npmci npm prepare
- npmci node install lts
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- notpriv
testSTABLE:
stage: test stage: test
script: script:
- npmci npm prepare - npmci npm prepare
@@ -71,6 +49,20 @@ testSTABLE:
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- lossless
- docker
- priv
testBuild:
stage: test
script:
- npmci npm prepare
- npmci node install stable
- npmci npm install
- npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- lossless
- docker - docker
- notpriv - notpriv
@@ -82,6 +74,7 @@ release:
only: only:
- tags - tags
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
@@ -90,20 +83,14 @@ release:
# ==================== # ====================
codequality: codequality:
stage: metadata stage: metadata
image: docker:stable
allow_failure: true allow_failure: true
services:
- docker:stable-dind
script: script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') - npmci command npm install -g tslint typescript
- docker run - npmci npm prepare
--env SOURCE_CODE="$PWD" - npmci npm install
--volume "$PWD":/code - npmci command "tslint -c tslint.json ./ts/**/*.ts"
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [codeclimate.json]
tags: tags:
- lossless
- docker - docker
- priv - priv
@@ -114,18 +101,20 @@ trigger:
only: only:
- tags - tags
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
pages: pages:
image: hosttoday/ht-docker-node:npmci
stage: metadata stage: metadata
script: script:
- npmci command npm install -g typedoc typescript - npmci node install lts
- npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare - npmci npm prepare
- npmci npm install - npmci npm install
- npmci command typedoc --module "commonjs" --target "ES2016" --out public/ ts/ - npmci command tsdoc
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
only: only:
@@ -135,13 +124,3 @@ pages:
paths: paths:
- public - public
allow_failure: true allow_failure: true
windowsCompatibility:
image: stefanscherer/node-windows:10-build-tools
stage: metadata
script:
- npm install & npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- windows
allow_failure: true

4
.snyk Normal file
View File

@@ -0,0 +1,4 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.12.0
ignore: {}
patch: {}

View File

@@ -2,5 +2,15 @@
"npmci": { "npmci": {
"npmGlobalTools": [], "npmGlobalTools": [],
"npmAccessLevel": "public" "npmAccessLevel": "public"
},
"gitzone": {
"module": {
"githost": "gitlab.com",
"gitscope": "pushrocks",
"gitrepo": "smartcsv",
"shortDescription": "handle csv data | gitzone standard compliant",
"npmPackagename": "@pushrocks/smartcsv",
"license": "MIT"
}
} }
} }

1522
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "@pushrocks/smartcsv", "name": "@pushrocks/smartcsv",
"version": "1.0.14", "version": "1.0.22",
"private": false, "private": false,
"description": "handle csv data | gitzone standard compliant", "description": "handle csv data | gitzone standard compliant",
"main": "dist/index.js", "main": "dist/index.js",
@@ -13,14 +13,28 @@
"format": "(gitzone format)" "format": "(gitzone format)"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.0.22", "@gitzone/tsbuild": "^2.1.17",
"@gitzone/tsrun": "^1.1.13", "@gitzone/tsrun": "^1.2.8",
"@gitzone/tstest": "^1.0.15", "@gitzone/tstest": "^1.0.28",
"@pushrocks/smartfile": "^6.0.8", "@pushrocks/smartfile": "^7.0.6",
"@pushrocks/tapbundle": "^3.0.7", "@pushrocks/tapbundle": "^3.2.0",
"@types/node": "^10.11.7" "@types/node": "^12.12.17",
"tslint": "^6.0.0-beta0",
"tslint-config-prettier": "^1.18.0"
}, },
"dependencies": { "dependencies": {
"@pushrocks/smartpromise": "^2.0.5" "@pushrocks/smartpromise": "^3.0.6",
} "@pushrocks/smartstring": "^3.0.17"
},
"files": [
"ts/**/*",
"ts_web/**/*",
"dist/**/*",
"dist_web/**/*",
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
"npmextra.json",
"readme.md"
]
} }

31
readme.md Normal file
View File

@@ -0,0 +1,31 @@
# @pushrocks/smartcsv
handle csv data | gitzone standard compliant
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartcsv)
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartcsv)
* [github.com (source mirror)](https://github.com/pushrocks/smartcsv)
* [docs (typedoc)](https://pushrocks.gitlab.io/smartcsv/)
## Status for master
[![build status](https://gitlab.com/pushrocks/smartcsv/badges/master/build.svg)](https://gitlab.com/pushrocks/smartcsv/commits/master)
[![coverage report](https://gitlab.com/pushrocks/smartcsv/badges/master/coverage.svg)](https://gitlab.com/pushrocks/smartcsv/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/@pushrocks/smartcsv.svg)](https://www.npmjs.com/package/@pushrocks/smartcsv)
[![Known Vulnerabilities](https://snyk.io/test/npm/@pushrocks/smartcsv/badge.svg)](https://snyk.io/test/npm/@pushrocks/smartcsv)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
## Usage
## Contribution
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
For further information read the linked docs at the top of this readme.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)

View File

@@ -1,3 +1,3 @@
Header 1;Header 2; Header3 Header 1;Header 2;"Header 3"
row1data1; row1data2; row1data3 "row1data1";"row1data2";"row1data3"
row2data1; row2data2; row2data3 "row2data1";row2data2;"row2data3"
1 Header 1 Header 2 Header3 Header 3
2 row1data1 row1data2 row1data3 row1data3
3 row2data1 row2data2 row2data3 row2data3

View File

@@ -13,9 +13,17 @@ tap.test('should read a file', async tools => {
}); });
tap.test('should create a valid csv', async () => { tap.test('should create a valid csv', async () => {
testCsv = await smartcsv.Csv.createCsvFromString(fileString, { headers: true }); testCsv = await smartcsv.Csv.createCsvFromString(fileString, { headers: true, unquote: true });
const result = await testCsv.exportAsObject(); const result = await testCsv.exportAsObject();
console.log(result); console.log(result);
}); });
tap.test('should create a valid csv string', async () => {
const createdCsvString = await smartcsv.Csv.createCsvStringFromArray([
{ wow: 'hi', wow2: 'there' },
{ wow: 'really', wow3: 'yes' }
]);
console.log(createdCsvString);
});
tap.start(); tap.start();

View File

@@ -2,34 +2,91 @@ import * as plugins from './smartcsv.plugins';
export interface ICsvConstructorOptions { export interface ICsvConstructorOptions {
headers: boolean; headers: boolean;
unquote?: boolean;
} }
export class Csv { export class Csv {
// STATIC
/**
* creates a Csv Object from string
* @param csvStringArg
* @param optionsArg
*/
public static async createCsvFromString( public static async createCsvFromString(
csvStringArg: string, csvStringArg: string,
optionsArg: ICsvConstructorOptions optionsArg: ICsvConstructorOptions
): Promise<Csv> { ): Promise<Csv> {
const csvInstance = new Csv(csvStringArg, optionsArg); const csvInstance = new Csv(csvStringArg, optionsArg);
await csvInstance.exportAsObject();
return csvInstance; return csvInstance;
} }
public static async createCsvStringFromArray(arrayArg: any[]): Promise<string> {
const foundKeys: string[] = [];
// lets deal with the keys
for (const objectArg of arrayArg) {
for (const key of Object.keys(objectArg)) {
foundKeys.includes(key) ? null : foundKeys.push(key);
}
}
// lets deal with the data
const dataRows: string[] = [];
for (const objectArg of arrayArg) {
const dataRowArray: string[] = [];
for (const key of foundKeys) {
dataRowArray.push(objectArg[key]);
}
dataRows.push(dataRowArray.join(','));
}
// lets put togehter the csv string and return it
const headerString = foundKeys.join(',');
const dataString = dataRows.join('\n');
const csvString = `${headerString}\n${dataString}\n`;
return csvString;
}
// INSTANCE
public csvString: string; public csvString: string;
public headers: string[]; public headers: string[];
public keyFrame: string = null; public keyFrame: string = null;
public data: any[];
private base64RecognitionPrefix = '####12345####';
public options: ICsvConstructorOptions = { public options: ICsvConstructorOptions = {
headers: true headers: true,
unquote: true
}; };
constructor(csvStringArg: string, optionsArg: ICsvConstructorOptions) { constructor(csvStringArg: string, optionsArg: ICsvConstructorOptions) {
this.csvString = csvStringArg; this.options = {
this.options = optionsArg; ...this.options,
...optionsArg
};
let csvStringToParse = csvStringArg;
if (this.options.unquote) {
csvStringToParse = csvStringToParse.replace(
/"(.*?)"/gi,
(match, p1, offset, originalString) => {
return this.base64RecognitionPrefix + plugins.smartstring.base64.encode(match);
}
);
}
this.csvString = csvStringToParse;
this.determineKeyframe(); this.determineKeyframe();
} }
/** /**
* determines the keyframe of the csv string * determines the keyframe of the csv string
*/ */
public determineKeyframe() { private determineKeyframe() {
let commaLength = 0; let commaLength = 0;
let semicolonLength = 0; let semicolonLength = 0;
const commaRegexResult = this.csvString.match(/,/g); const commaRegexResult = this.csvString.match(/,/g);
@@ -51,7 +108,7 @@ export class Csv {
/** /**
* serializes the csv string * serializes the csv string
*/ */
public serializeCsvString() { private serializeCsvString() {
const rowArray = this.getRows(); const rowArray = this.getRows();
const resultArray = []; const resultArray = [];
if (this.options.headers) { if (this.options.headers) {
@@ -64,7 +121,10 @@ export class Csv {
return resultArray; return resultArray;
} }
public getRows(): string[] { /**
* gets the rows of the csv
*/
private getRows(): string[] {
const rowsArray = this.csvString.split('\n'); const rowsArray = this.csvString.split('\n');
if (rowsArray[rowsArray.length - 1] === '') { if (rowsArray[rowsArray.length - 1] === '') {
rowsArray.pop(); rowsArray.pop();
@@ -72,20 +132,40 @@ export class Csv {
return rowsArray; return rowsArray;
} }
public getHeaders() { private getHeaders() {
const rowArray = this.getRows(); const rowArray = this.getRows();
if (this.options.headers) { if (this.options.headers) {
let headerRow = rowArray[0]; let headerRow = rowArray[0];
this.headers = headerRow.split(this.keyFrame); this.headers = headerRow.split(this.keyFrame);
if (this.options.unquote) {
const unquotedHeaders: string[] = [];
for (let header of this.headers) {
if (header.startsWith(this.base64RecognitionPrefix)) {
header = header.replace(this.base64RecognitionPrefix, '');
unquotedHeaders.push(plugins.smartstring.base64.decode(header).replace(/['"]+/g, ''));
} else {
unquotedHeaders.push(header);
}
}
this.headers = unquotedHeaders;
}
} }
return this.headers; return this.headers;
} }
public createDataObject(dataArray: string[]) { private createDataObject(dataArray: string[]) {
const neededIterations = dataArray.length; const neededIterations = dataArray.length;
let resultJson: any = {}; let resultJson: any = {};
for (let i = 0; i < neededIterations; i++) { for (let i = 0; i < neededIterations; i++) {
resultJson[this.headers[i]] = dataArray[i]; let value = dataArray[i];
if (this.options.unquote && value.startsWith(this.base64RecognitionPrefix)) {
value = value.replace(this.base64RecognitionPrefix, '');
value = plugins.smartstring.base64
.decode(value)
.replace(/['"]+/g, '')
.replace(/['"]+/g, '');
}
resultJson[this.headers[i]] = value;
} }
return resultJson; return resultJson;
} }
@@ -96,6 +176,7 @@ export class Csv {
for (const dataArray of serializedData) { for (const dataArray of serializedData) {
dataObjects.push(this.createDataObject(dataArray)); dataObjects.push(this.createDataObject(dataArray));
} }
this.data = dataObjects;
return dataObjects; return dataObjects;
} }
} }

View File

@@ -1,3 +1,4 @@
import * as smartq from '@pushrocks/smartpromise'; import * as smartpromise from '@pushrocks/smartpromise';
import * as smartstring from '@pushrocks/smartstring';
export { smartq }; export { smartpromise, smartstring };

View File

@@ -1,13 +1,17 @@
{ {
"extends": [ "extends": ["tslint:latest", "tslint-config-prettier"],
"tslint:latest",
"tslint-config-prettier"
],
"rules": { "rules": {
"semicolon": [ "semicolon": [true, "always"],
true, "no-console": false,
"always" "ordered-imports": false,
"object-literal-sort-keys": false,
"member-ordering": {
"options":{
"order": [
"static-method"
] ]
} }
} }
},
"defaultSeverity": "warning"
}