pocketbase-import/utils/pocketbase.ts
michal-kapala 3c78bb2a1b url type added
+ support for `Url` columns
2023-06-28 02:16:09 +02:00

209 lines
4.9 KiB
TypeScript

// @deno-types="https://unpkg.com/pocketbase@0.12.0/dist/pocketbase.es.d.mts"
import { SchemaField } from "https://unpkg.com/pocketbase@0.12.0/dist/pocketbase.es.mjs";
import { RawCsvRow } from "../types/csv.ts";
import { RawJsonRow } from "../types/json.ts";
import {
POCKETBASE_TYPE,
PocketbaseRowSchema,
PocketbaseType,
} from "../types/pocketbase.ts";
import { addSchemaField as addCsvSchemaField } from "./csv.ts";
import { addSchemaField as addJsonSchemaField } from "./json.ts";
/**
* Finds column's type in the schema.
* @param column Column name.
* @param schema PocketBase collection schema.
* @returns
*/
export function getSchemaType(
column: string,
schema: SchemaField[],
): PocketbaseType {
const schemaField = schema.find((field) => field.name === column);
// if somehow the data got structured wrong
if (schemaField === undefined) {
console.error(
`%cSchemaError: Supplied column '${column}' not found in collection schema`,
"color: red",
);
Deno.exit(-1);
}
switch (schemaField.type) {
case POCKETBASE_TYPE.BOOL:
return POCKETBASE_TYPE.BOOL;
case POCKETBASE_TYPE.NUMBER:
return POCKETBASE_TYPE.NUMBER;
case POCKETBASE_TYPE.PLAIN_TEXT:
return POCKETBASE_TYPE.PLAIN_TEXT;
case POCKETBASE_TYPE.EMAIL:
return POCKETBASE_TYPE.EMAIL;
case POCKETBASE_TYPE.JSON:
return POCKETBASE_TYPE.JSON;
case POCKETBASE_TYPE.DATETIME:
return POCKETBASE_TYPE.DATETIME;
case POCKETBASE_TYPE.URL:
return POCKETBASE_TYPE.URL;
default:
console.error(
`%cPbTypeError: Unsupported type '${schemaField.type}'`,
"color: red",
);
Deno.exit(-2);
}
}
/**
* Builds a `SchemaField` object based on data type.
* @param name Column name.
* @param type PocketBase type.
* @returns
*/
export function createSchemaField(
name: string,
type: PocketbaseType,
): SchemaField {
switch (type) {
case POCKETBASE_TYPE.BOOL:
return new SchemaField({
name,
type,
system: false,
required: false,
unique: false,
options: {},
});
case POCKETBASE_TYPE.NUMBER:
return new SchemaField({
name,
type,
system: false,
required: false,
unique: false,
options: {
min: null,
max: null,
},
});
case POCKETBASE_TYPE.PLAIN_TEXT:
return new SchemaField({
name,
type,
system: false,
required: false,
unique: false,
options: {
min: null,
max: null,
pattern: "",
},
});
case POCKETBASE_TYPE.EMAIL:
return new SchemaField({
name,
type,
system: false,
required: false,
unique: false,
options: {
min: null,
max: null,
},
});
case POCKETBASE_TYPE.JSON:
return new SchemaField({
name,
type,
system: false,
required: false,
unique: false,
options: {},
});
case POCKETBASE_TYPE.DATETIME:
return new SchemaField({
name,
type,
system: false,
required: false,
unique: false,
options: {
min: null,
max: null,
},
});
case POCKETBASE_TYPE.URL:
return new SchemaField({
name,
type,
system: false,
required: false,
unique: false,
options: {
exceptDomains: null,
onlyDomains: null,
},
});
}
}
/**
* Creates a row object schema from PocketBase collection schema.
* @param schema PocketBase collection schema.
* @returns
*/
export function generateRowSchema(schema: SchemaField[]): PocketbaseRowSchema {
let instance: PocketbaseRowSchema = {};
let fieldType: PocketbaseType;
schema.forEach((field) => {
fieldType = getSchemaType(field.name, schema);
instance = { ...instance, [field.name]: fieldType };
});
return instance;
}
/**
* Parses raw objects into PocketBase collection schema fields.
* @param data Raw input data.
* @returns
*/
// deno-lint-ignore no-explicit-any
export function createSchema(
data: { [key: string]: any },
stringifyId: boolean,
inputFormat: "csv" | "json",
): SchemaField[] {
const schema: SchemaField[] = [];
// Seeks patterns in up to 1k records to avoid poor performance on large datasets
if (data.length > 1000) {
data = data.slice(0, 1000);
}
// Analyzes each column, deducts a type and creates a schema field
for (const prop in data[0]) {
// respect --id option
if (stringifyId && prop.toLowerCase() === "id") {
schema.push(createSchemaField(`_${prop}`, "text"));
} else {
schema.push(
inputFormat === "csv"
? addCsvSchemaField(data as RawCsvRow[], prop)
: addJsonSchemaField(data as RawJsonRow[], prop),
);
}
}
return schema;
}