[REFACTOR] types 수정. api 수정 아직 안됨.

This commit is contained in:
ChangHangeol 2025-01-20 22:16:08 +09:00
parent 20fb1bf696
commit c3dc6fc065
2 changed files with 80 additions and 44 deletions

View file

@ -1,103 +1,115 @@
export type CSVCell = string | number | null;
export type stringDate = string; // 날짜를 string 형식 (YYYY-MM-DD)로 저장하기 위한 클래스
function isStringDate(date: string): date is stringDate {
const regex = /^\d{4}-\d{2}-\d{2}$/; // YYYY-MM-DD 형식 확인
return regex.test(date);
}
export type select = string;
export type CSVCell = string | number | stringDate | select | Date /*사용 여부 미정*/ | null;
export type CSVRow = CSVCell[];
export type Header = [string, string]; // [columnName, columnType]
export type Header = {
[key: string]: {
type: string;
default: CSVCell;
options?: string[]; // select type일 때만 필요
}
}
export class CSVTable {
private headers: Header[];
private headers: Header; // Header는 이제 객체로 변경
private rows: CSVRow[];
// string으로 넣거나, 분리된 headers/rows로 생성자 호출 가능.
constructor(headers: Header[], rows: CSVRow[] = []) {
constructor(headers: Header, rows: CSVRow[] = []) {
this.headers = headers;
this.rows = rows;
}
// constructor(contentOrHeaders: string | string[], rows: CSVRow[] = []) {
// if (typeof contentOrHeaders === 'string') {
// // content가 문자열일 때
// const lines = contentOrHeaders.split("\n").map(line => line.trim());
// this.headers = lines.shift()?.split(",") ?? [];
// this.rows = lines.map(line => line.split(",").map(cell => cell.trim()));
// } else {
// // headers가 배열일 때
// this.headers = contentOrHeaders;
// this.rows = rows;
// }
// }
getHeaders(): Header[] {
getHeaders(): Header {
return this.headers;
}
getRows(): CSVRow[] {
return this.rows;
}
// 가급적이면 CSVRow로 넣어주는 것을 권장.
append(row: CSVRow | {[key: string]: string}): void {
if (row.length !== this.headers.length) {
throw new Error(`Row length (${row.length}) must match headers length (${this.headers.length}).`);
append(row: CSVRow | { [key: string]: string }): void {
if (Array.isArray(row)) {
if (row.length !== Object.keys(this.headers).length) {
throw new Error(`Row length (${row.length}) must match headers length.`);
}
this.rows.push(row);
} else {
// console.log(`append row: ${row}`);
if(Array.isArray(row)) {
this.rows.push(row);
}
else {
// key-value로 들어올 때
const newRow: CSVRow = [];
for(const header of this.headers) { newRow.push(row[header[0]]); }
this.rows.push(newRow);
// key-value로 들어올 때
const newRow: CSVRow = [];
for (const key in this.headers) {
if (row[key] === undefined) {
throw new Error(`Missing value for column '${key}'.`);
}
newRow.push(row[key]);
}
this.rows.push(newRow);
}
}
delete(rowIndex: number): void {
if (rowIndex < 0 || rowIndex >= this.rows.length) {
throw new Error(`Invalid row index: ${rowIndex}`);
}
this.rows.splice(rowIndex, 1);
}
updateCell(rowIndex: number, columnName: string, value: CSVCell): void {
const columnIndex = this.headers.findIndex(([colname]) => colname === columnName);
if (columnIndex === -1) {
// Column name은 headers에서 찾고, 그에 맞는 인덱스를 찾아서 업데이트
const header = this.headers[columnName];
if (!header) {
throw new Error(`Column '${columnName}' does not exist.`);
}
if (rowIndex < 0 || rowIndex >= this.rows.length) {
throw new Error(`Invalid row index: ${rowIndex}`);
}
const columnIndex = Object.keys(this.headers).indexOf(columnName);
this.rows[rowIndex][columnIndex] = value;
}
toCSV(): string {
const csvContent = [this.headers.join(",")];
const csvContent = [Object.keys(this.headers).join(",")];
for (const row of this.rows) {
csvContent.push(row.map(cell => (cell === null ? "" : cell.toString())).join(","));
}
return csvContent.join("\n");
}
// 실제로 사용하게될 api일지는 모르겠습니다.
addColoumn(columnName: string, columnType: string, value: CSVCell = 0): void {
this.headers.push([columnName, columnType]);
addColumn(columnName: string, columnType: string, value: CSVCell = 0): void {
this.headers[columnName] = { type: columnType, default: value };
for (let i = 0; i < this.rows.length; i++) {
this.rows[i].push(value);
}
}
deleteColumn(columnName: string): void {
const columnIndex = this.headers.findIndex(([colname]) => colname === columnName);
if (columnIndex === -1) {
const header = this.headers[columnName];
if (!header) {
throw new Error(`Column '${columnName}' does not exist.`);
}
this.headers.splice(columnIndex, 1);
delete this.headers[columnName];
for (let i = 0; i < this.rows.length; i++) {
const columnIndex = Object.keys(this.headers).indexOf(columnName);
this.rows[i].splice(columnIndex, 1);
}
}
}
export interface CSVFile {
name: string;
path: string;
content: CSVTable;
}
export const columnTypes: string[] = [
'string',
'number',
'boolean',
];
// export const columnTypes: string[] = [
// 'string',
// 'number',
// 'boolean',
// ];

24
test/.meta Normal file
View file

@ -0,0 +1,24 @@
{
"cost" : {
"type" : "number",
"default" : 0
},
"description" : {
"type" : "string",
"default" : "-"
},
"date" : {
"type" : "string",
"default" : "1970-01-01"
},
"category" : {
"type" : "select",
"default" : "other",
"options" : [
"food",
"transport",
"entertainment",
"other"
]
}
}