From 3c78bb2a1b416ac0302d867e16a25d008cd9f848 Mon Sep 17 00:00:00 2001 From: michal-kapala Date: Wed, 28 Jun 2023 02:16:09 +0200 Subject: [PATCH] url type added + support for `Url` columns --- input/example.csv | 6 +++--- input/example.json | 6 ++++-- types/pocketbase.ts | 1 + utils/csv.ts | 8 +++++++- utils/json.ts | 5 ++++- utils/pocketbase.ts | 15 +++++++++++++++ utils/regex.ts | 25 +++++++++++++++++++++++++ 7 files changed, 59 insertions(+), 7 deletions(-) diff --git a/input/example.csv b/input/example.csv index a0d3e15..e28ba13 100644 --- a/input/example.csv +++ b/input/example.csv @@ -1,3 +1,3 @@ -id,name,is_good,score,email,json,date -1,john,1,0.8412384213497,john.doe@example.com,[],2023-03-05T00:35:21.104Z -2,fire,0,-80347329472,firebase@google.com,{"xd": "nice meme"}, \ No newline at end of file +id,name,is_good,score,email,json,date,url +1,john,1,0.8412384213497,john.doe@example.com,[],2023-03-05T00:35:21.104Z,https://example.com +2,fire,0,-80347329472,firebase@google.com,{"xd": "nice meme"},,sftp://fire@8.8.8.8/base.txt \ No newline at end of file diff --git a/input/example.json b/input/example.json index eb0abf8..8238ecd 100644 --- a/input/example.json +++ b/input/example.json @@ -6,7 +6,8 @@ "score": 0.8412384213497, "email": "john.doe@example.com", "json": [], - "date": "2023-03-05T00:35:21.104Z" + "date": "2023-03-05T00:35:21.104Z", + "url": "https://example.com" }, { "id": 2, @@ -17,6 +18,7 @@ "json": { "xd": "nice meme" }, - "date": null + "date": null, + "url": "sftp://fire@8.8.8.8/base.txt" } ] diff --git a/types/pocketbase.ts b/types/pocketbase.ts index 4513f83..73acc73 100644 --- a/types/pocketbase.ts +++ b/types/pocketbase.ts @@ -8,6 +8,7 @@ export const POCKETBASE_TYPE = { EMAIL: "email", JSON: "json", DATETIME: "date", + URL: "url", } as const; type ObjectValues = T[keyof T]; diff --git a/utils/csv.ts b/utils/csv.ts index d0067aa..5002a2f 100644 --- a/utils/csv.ts +++ b/utils/csv.ts @@ -17,7 +17,7 @@ import { PocketbaseType, } from "../types/pocketbase.ts"; import { createSchemaField, generateRowSchema } from "./pocketbase.ts"; -import { isBool, isDate, isEmail, isJson, isNumber } from "./regex.ts"; +import { isBool, isDate, isEmail, isJson, isNumber, isUrl } from "./regex.ts"; /** * Reads raw data from a CSV file. @@ -122,6 +122,10 @@ export function addSchemaField(data: RawCsvRow[], prop: string): SchemaField { return createSchemaField(targetProp, "date"); } + if (isUrl(data, prop)) { + return createSchemaField(targetProp, "url"); + } + // Plain text is the default type return createSchemaField(targetProp, "text"); } @@ -206,6 +210,8 @@ function parseValue(value: string, type: PocketbaseType): any { return value !== "" ? value : null; case POCKETBASE_TYPE.DATETIME: return value !== "" ? value : null; + case POCKETBASE_TYPE.URL: + return value !== "" ? value : null; default: console.error( `%cPbTypeError: value parser for type '${type}' is not yet implemented.`, diff --git a/utils/json.ts b/utils/json.ts index d46c1d5..94023d4 100644 --- a/utils/json.ts +++ b/utils/json.ts @@ -3,7 +3,7 @@ import { SchemaField } from "https://unpkg.com/pocketbase@0.12.0/dist/pocketbase import { RawJsonRow } from "../types/json.ts"; import { POCKETBASE_SYSFIELD } from "../types/pocketbase.ts"; import { createSchemaField } from "./pocketbase.ts"; -import { isDate, isEmail } from "./regex.ts"; +import { isDate, isEmail, isUrl } from "./regex.ts"; /** * Reads an array of rows from a JSON file. @@ -89,6 +89,9 @@ export function addSchemaField(data: RawJsonRow[], prop: string): SchemaField { case "bigint": return createSchemaField(targetProp, "number"); case "string": + if(isUrl(data, targetProp)) { + return createSchemaField(targetProp, "url"); + } if (isEmail(data, targetProp)) { return createSchemaField(targetProp, "email"); } diff --git a/utils/pocketbase.ts b/utils/pocketbase.ts index 661a48e..d271006 100644 --- a/utils/pocketbase.ts +++ b/utils/pocketbase.ts @@ -50,6 +50,9 @@ export function getSchemaType( case POCKETBASE_TYPE.DATETIME: return POCKETBASE_TYPE.DATETIME; + case POCKETBASE_TYPE.URL: + return POCKETBASE_TYPE.URL; + default: console.error( `%cPbTypeError: Unsupported type '${schemaField.type}'`, @@ -137,6 +140,18 @@ export function createSchemaField( max: null, }, }); + case POCKETBASE_TYPE.URL: + return new SchemaField({ + name, + type, + system: false, + required: false, + unique: false, + options: { + exceptDomains: null, + onlyDomains: null, + }, + }); } } diff --git a/utils/regex.ts b/utils/regex.ts index 5b71124..a72b88e 100644 --- a/utils/regex.ts +++ b/utils/regex.ts @@ -64,6 +64,31 @@ export function isNumber(data: RawCsvRow[], prop: string): boolean { return matched === values && matched > 0; } +/** + * Checks if the column type could be `Url`. + * @param data Sample data. + * @param prop Validated property. + * @returns + */ +export function isUrl(data: RawCsvRow[], prop: string): boolean { + let values = 0; + let parsed = 0; + + data.forEach((obj) => { + if (obj[prop] !== "" && obj[prop] !== null) { + values++; + try { + new URL(obj[prop]); + parsed++; + } // deno-lint-ignore no-empty + catch {} + } + }); + + // an empty column will return false + return parsed === values && parsed > 0; +} + /** * Checks if the column type could be `Email`. * @param data Sample data.