JSON import support
+ JSON import added + code structure refactored
This commit is contained in:
113
json.ts
Normal file
113
json.ts
Normal file
@ -0,0 +1,113 @@
|
||||
// @deno-types="https://unpkg.com/pocketbase@0.12.0/dist/pocketbase.es.d.mts"
|
||||
import PocketBase, {
|
||||
Collection,
|
||||
SchemaField,
|
||||
} from "https://unpkg.com/pocketbase@0.12.0/dist/pocketbase.es.mjs";
|
||||
import "https://deno.land/std@0.178.0/dotenv/load.ts";
|
||||
import { parse } from "https://deno.land/std@0.175.0/flags/mod.ts";
|
||||
import { readJson, resolveConflicts } from "./utils/json.ts";
|
||||
import { createSchema } from "./utils/pocketbase.ts";
|
||||
|
||||
/**
|
||||
* Structures and populates a new collection from a JSON file.
|
||||
*/
|
||||
async function importJson() {
|
||||
// config data
|
||||
const pbUrl = Deno.env.get("POCKETBASE_URL") ?? "http://localhost:8090";
|
||||
const adminName = Deno.env.get("ADMIN_EMAIL") ?? "";
|
||||
const adminPass = Deno.env.get("ADMIN_PASSWORD") ?? "";
|
||||
|
||||
// parse CLI args
|
||||
const options = parse(Deno.args, {
|
||||
string: ["input"],
|
||||
boolean: ["id"],
|
||||
default: {
|
||||
/**
|
||||
* Name of the JSON file to import (with extension).
|
||||
*/
|
||||
input: null,
|
||||
/**
|
||||
* Flag to always set `_id` column type to Plain text (detected by default).
|
||||
*/
|
||||
id: false,
|
||||
},
|
||||
});
|
||||
|
||||
if (options.input === null) {
|
||||
console.error("%cOptionError: JSON file name not supplied", "color: red");
|
||||
Deno.exit(-1);
|
||||
}
|
||||
|
||||
// read the file
|
||||
const data = await readJson(options.input);
|
||||
|
||||
// sanitize the file name for collection name
|
||||
const collectName = options.input.replace(".json", "");
|
||||
|
||||
// connect to pocketbase
|
||||
const pb = new PocketBase(pbUrl);
|
||||
|
||||
// authenticate as super admin
|
||||
const _authResponse = await pb.admins.authWithPassword(adminName, adminPass);
|
||||
|
||||
// collection schema object
|
||||
const schema: SchemaField[] = createSchema(data, options.id, "json");
|
||||
|
||||
const creationDate = new Date().toISOString();
|
||||
|
||||
// the new collection
|
||||
const collection = new Collection({
|
||||
name: collectName,
|
||||
type: "base",
|
||||
system: false,
|
||||
schema,
|
||||
listRule: null,
|
||||
viewRule: null,
|
||||
createRule: null,
|
||||
updateRule: null,
|
||||
deleteRule: null,
|
||||
options: {},
|
||||
created: creationDate,
|
||||
updated: creationDate,
|
||||
});
|
||||
|
||||
// show the submitted collection
|
||||
console.log(collection);
|
||||
|
||||
// create the new collection
|
||||
// import will fail if a collection with the same name exists
|
||||
await pb.collections.import([collection]);
|
||||
|
||||
console.log(
|
||||
`%c[Import] Collection '${collectName}' created!`,
|
||||
"color: green",
|
||||
);
|
||||
|
||||
// prefix conflicting column names
|
||||
const rows = resolveConflicts(data);
|
||||
|
||||
console.log(`[Import] Importing ${rows.length} rows...`);
|
||||
|
||||
// number of successfully inserted rows
|
||||
let insertCount = 0;
|
||||
|
||||
for (insertCount; insertCount < rows.length; insertCount++) {
|
||||
try {
|
||||
await pb.collection(collectName).create(rows[insertCount], {
|
||||
"$autoCancel": false,
|
||||
});
|
||||
} catch (e) {
|
||||
// breaks on first error
|
||||
console.error(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const color = insertCount === data.length ? "green" : "orange";
|
||||
console.log(
|
||||
`%c[Import] Imported rows: ${insertCount}/${data.length}`,
|
||||
`color: ${color}`,
|
||||
);
|
||||
}
|
||||
|
||||
importJson();
|
Reference in New Issue
Block a user