26 Commits

Author SHA1 Message Date
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
00aed79e18 1.0.14 2018-10-14 23:28:38 +02:00
438053a2f9 fix(structure): run gitzone format 2018-10-14 23:28:38 +02:00
7479328e13 1.0.13 2018-10-14 23:26:54 +02:00
56d7ae8952 fix(refactor): update static function/constructor responsibilities 2018-10-14 23:26:54 +02:00
feb41df3e2 1.0.12 2018-08-18 22:09:30 +02:00
1474cb1665 fix(CI): remove obsolete build dependency 2018-08-18 22:09:29 +02:00
6e289a01b1 1.0.11 2018-08-18 22:08:13 +02:00
c08aa1959f fix(dependencies): update 2018-08-18 22:08:13 +02:00
0dd0d31f41 1.0.10 2018-08-18 22:05:26 +02:00
ee1f5036aa fix(CI): update testing 2018-08-18 22:05:26 +02:00
987cb9593e 1.0.9 2018-06-10 14:38:31 +02:00
d6ff7c54e2 fix(package): set private marker to false 2018-06-10 14:38:30 +02:00
12 changed files with 1502 additions and 569 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,16 +1,16 @@
# 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
- test - test
- release - release
- metadata - metadata
# ==================== # ====================
# security stage # security stage
@@ -20,53 +20,49 @@ 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 command npm install -g snyk - npmci npm prepare
- 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 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 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 node install stable - npmci node install stable
- npmci npm install - npmci npm install
- 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
@@ -78,6 +74,7 @@ release:
only: only:
- tags - tags
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
@@ -86,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
@@ -110,16 +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 npmpage - npmci node install lts
- npmci command npmpage - npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare
- npmci npm install
- npmci command tsdoc
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
only: only:
@@ -128,3 +123,4 @@ pages:
expire_in: 1 week expire_in: 1 week
paths: paths:
- public - public
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

@@ -1,8 +1,16 @@
{ {
"npmci": { "npmci": {
"npmGlobalTools": [ "npmGlobalTools": [],
"@gitzone/npmts"
],
"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"
}
} }
} }

1673
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,38 @@
{ {
"name": "@pushrocks/smartcsv", "name": "@pushrocks/smartcsv",
"version": "1.0.8", "version": "1.0.21",
"private": true, "private": false,
"description": "handle csv data | gitzone standard compliant", "description": "handle csv data | gitzone standard compliant",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"test": "(tsrun test/test.ts)", "test": "(tstest test/)",
"build": "(npmts)", "build": "(tsbuild)",
"format": "(gitzone format)" "format": "(gitzone format)"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsrun": "^1.0.5", "@gitzone/tsbuild": "^2.1.17",
"smartfile": "^4.2.28", "@gitzone/tsrun": "^1.2.8",
"tapbundle": "^2.0.0" "@gitzone/tstest": "^1.0.28",
"@pushrocks/smartfile": "^7.0.6",
"@pushrocks/tapbundle": "^3.2.0",
"@types/node": "^12.12.17"
}, },
"dependencies": { "dependencies": {
"smartq": "^1.1.8" "@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

@@ -1,9 +1,9 @@
// tslint:disable-next-line:no-implicit-dependencies // tslint:disable-next-line:no-implicit-dependencies
import { expect, tap } from 'tapbundle'; import { expect, tap } from '@pushrocks/tapbundle';
import * as smartcsv from '../ts/index'; import * as smartcsv from '../ts/index';
// tslint:disable-next-line:no-implicit-dependencies // tslint:disable-next-line:no-implicit-dependencies
import * as smartfile from 'smartfile'; import * as smartfile from '@pushrocks/smartfile';
let fileString: string; let fileString: string;
let testCsv: smartcsv.Csv; let testCsv: smartcsv.Csv;
@@ -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,27 +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,
options: ICsvConstructorOptions optionsArg: ICsvConstructorOptions
): Promise<Csv> { ): Promise<Csv> {
const csvInstance = new Csv(); const csvInstance = new Csv(csvStringArg, optionsArg);
csvInstance.csvString = csvStringArg; await csvInstance.exportAsObject();
csvInstance.determineKeyframe();
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
}; };
public determineKeyframe() { constructor(csvStringArg: string, optionsArg: ICsvConstructorOptions) {
this.options = {
...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();
}
/**
* determines the keyframe of the csv string
*/
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);
@@ -41,7 +105,10 @@ export class Csv {
} }
} }
public serializeCsvString() { /**
* serializes the csv string
*/
private serializeCsvString() {
const rowArray = this.getRows(); const rowArray = this.getRows();
const resultArray = []; const resultArray = [];
if (this.options.headers) { if (this.options.headers) {
@@ -54,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();
@@ -62,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;
} }
@@ -86,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 'smartq'; 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"
}