Skip to content

Commit

Permalink
v1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
jerrywithaz committed Jan 20, 2022
1 parent dde6256 commit 4d27c3a
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 120 deletions.
8 changes: 8 additions & 0 deletions declarations/node.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare namespace NodeJS {
export interface ProcessEnv {
PROJECT_ID: string;
DATASTORE_EMULATOR_HOST: string;
DATASTORE_BACKUP_BUCKET: string;
DATASTORE_BACKUP_DIR: string;
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "google-datastore-emulator-ui",
"version": "1.2.2",
"version": "1.3.0",
"description": "",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
6 changes: 3 additions & 3 deletions src/server/lib/src/env.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
declare type Env = {
export declare type Env = {
DATASTORE_EMULATOR_HOST: string;
DATASTORE_BACKUP_BUCKET: string;
DATASTORE_BACKUP_DIR: string;
PROJECT_ID: string;
DATASTORE_EMULATOR_PORT: number;
DATASTORE_PROJECT_URL: string;
};
declare const env: Env;
export default env;
declare function getEnv(): Env;
export default getEnv;
44 changes: 24 additions & 20 deletions src/server/lib/src/env.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("dotenv").config();
const { DATASTORE_EMULATOR_HOST, DATASTORE_BACKUP_BUCKET, PROJECT_ID, DATASTORE_BACKUP_DIR, } = process.env;
const DATASTORE_EMULATOR_PORT = Number(DATASTORE_EMULATOR_HOST.match(/\d+/)[0]);
const DATASTORE_PROJECT_URL = `${DATASTORE_EMULATOR_HOST}/v1/projects/${PROJECT_ID}`;
const env = {
DATASTORE_EMULATOR_HOST: DATASTORE_EMULATOR_HOST,
DATASTORE_BACKUP_BUCKET: DATASTORE_BACKUP_BUCKET,
DATASTORE_BACKUP_DIR: DATASTORE_BACKUP_DIR,
PROJECT_ID: PROJECT_ID,
DATASTORE_EMULATOR_PORT: DATASTORE_EMULATOR_PORT,
DATASTORE_PROJECT_URL: DATASTORE_PROJECT_URL,
};
for (const key in env) {
const typedKey = key;
const element = env[typedKey];
if (element) {
console.log("✅", key, element);
}
else {
console.log("❌", key, element);
function getEnv() {
const { DATASTORE_EMULATOR_HOST = '', DATASTORE_BACKUP_BUCKET = '', PROJECT_ID = '', DATASTORE_BACKUP_DIR = '', } = process.env;
const DATASTORE_EMULATOR_HOST_MATCHES = DATASTORE_EMULATOR_HOST.match(/\d+/);
const DATASTORE_EMULATOR_PORT = Number(DATASTORE_EMULATOR_HOST_MATCHES ? DATASTORE_EMULATOR_HOST_MATCHES[0] : 0);
const DATASTORE_PROJECT_URL = `${DATASTORE_EMULATOR_HOST}/v1/projects/${PROJECT_ID}`;
const env = {
DATASTORE_EMULATOR_HOST: DATASTORE_EMULATOR_HOST,
DATASTORE_BACKUP_BUCKET: DATASTORE_BACKUP_BUCKET,
DATASTORE_BACKUP_DIR: DATASTORE_BACKUP_DIR,
PROJECT_ID: PROJECT_ID,
DATASTORE_EMULATOR_PORT: DATASTORE_EMULATOR_PORT,
DATASTORE_PROJECT_URL: DATASTORE_PROJECT_URL,
};
for (const key in env) {
const typedKey = key;
const element = env[typedKey];
if (element) {
console.log("✅", key, element);
}
else {
console.log("❌", key, element);
}
}
return env;
}
exports.default = env;
exports.default = getEnv;
11 changes: 6 additions & 5 deletions src/server/lib/src/schema/gsutil/resolver.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { DatastoreBackup } from "./types";
import { Context } from "../../types";
declare class GsUtilResolver {
getProjectId(): Promise<string>;
getBackups(): Promise<DatastoreBackup[]>;
startBackup(): Promise<string>;
downloadBackup(name: string): Promise<string>;
importBackup(name: string): Promise<string>;
getProjectId({ env }: Context): Promise<string>;
getBackups({ env }: Context): Promise<DatastoreBackup[]>;
startBackup({ env }: Context): Promise<string>;
downloadBackup(name: string, { env }: Context): Promise<string>;
importBackup(name: string, { env }: Context): Promise<string>;
}
export default GsUtilResolver;
60 changes: 32 additions & 28 deletions src/server/lib/src/schema/gsutil/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,49 +41,48 @@ const types_1 = require("./types");
const removeTrailingSlash_1 = __importDefault(require("../../utils/removeTrailingSlash"));
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const env_1 = __importDefault(require("../../env"));
const ValidateEmulatorRunning_1 = __importDefault(require("../../decorators/ValidateEmulatorRunning"));
const ValidateEnv_1 = __importDefault(require("../../decorators/ValidateEnv"));
const execAsync = (0, util_1.promisify)(child_process_1.exec);
function getBackupName(backup) {
function getBackupName(backup, bucket) {
return backup
.replace(`gs://${env_1.default.DATASTORE_BACKUP_BUCKET}`, "")
.replace(`gs://${bucket}`, "")
.replace(/\//g, "");
}
function getDate(backup) {
const date = getBackupName(backup).replace(/_\d+/, "");
function getDate(backup, bucket) {
const date = getBackupName(backup, bucket).replace(/_\d+/, "");
return new Date(date);
}
function getBackupInfo(backup) {
const name = getBackupName(backup);
const potential_path = path.join(env_1.default.DATASTORE_BACKUP_DIR, name);
function getBackupInfo(backup, backupDir, bucket) {
const name = getBackupName(backup, bucket);
const potential_path = path.join(backupDir, name);
const exists = fs.existsSync(path.resolve(potential_path));
return { exists, path: potential_path };
}
let GsUtilResolver = class GsUtilResolver {
async getProjectId() {
return env_1.default.PROJECT_ID;
async getProjectId({ env }) {
return env.PROJECT_ID;
}
async getBackups() {
const { stdout, stderr } = await execAsync(`gsutil ls gs://${env_1.default.DATASTORE_BACKUP_BUCKET}`);
async getBackups({ env }) {
const { stdout, stderr } = await execAsync(`gsutil ls gs://${env.DATASTORE_BACKUP_BUCKET}`);
const backups = stdout
.trim()
.split(/\n/)
.map((backup) => {
return {
id: (0, removeTrailingSlash_1.default)(backup),
name: getBackupName(backup),
date: getDate(backup),
...getBackupInfo(backup),
name: getBackupName(backup, env.DATASTORE_BACKUP_BUCKET),
date: getDate(backup, env.DATASTORE_BACKUP_BUCKET),
...getBackupInfo(backup, env.DATASTORE_BACKUP_DIR, env.DATASTORE_BACKUP_BUCKET),
};
});
if (stderr) {
throw new Error(stderr);
}
return backups;
}
async startBackup() {
const command = `gcloud datastore export gs://${env_1.default.DATASTORE_BACKUP_BUCKET} --project='${env_1.default.PROJECT_ID}' --format=json`;
async startBackup({ env }) {
const command = `gcloud datastore export gs://${env.DATASTORE_BACKUP_BUCKET} --project='${env.PROJECT_ID}' --format=json`;
const { stdout, stderr } = await execAsync(command);
if (stderr) {
throw new Error(stderr);
Expand All @@ -92,9 +91,9 @@ let GsUtilResolver = class GsUtilResolver {
const timestamp = outputUrlPrefix.split("/").pop();
return timestamp;
}
async downloadBackup(name) {
const backup_bucket = env_1.default.DATASTORE_BACKUP_BUCKET;
const outputDir = path.join(env_1.default.DATASTORE_BACKUP_DIR, name);
async downloadBackup(name, { env }) {
const backup_bucket = env.DATASTORE_BACKUP_BUCKET;
const outputDir = path.join(env.DATASTORE_BACKUP_DIR, name);
const command = `gsutil -o GSUtil:parallel_process_count=1 -m cp -r "gs://${backup_bucket}/${name}/${name}.overall_export_metadata" "gs://${backup_bucket}/${name}/all_namespaces/" ${outputDir}`;
fs.mkdirSync(outputDir);
const { stderr } = await execAsync(command);
Expand All @@ -103,9 +102,9 @@ let GsUtilResolver = class GsUtilResolver {
}
return name;
}
async importBackup(name) {
const input_url = path.join(env_1.default.DATASTORE_BACKUP_DIR, `${name}/${name}.overall_export_metadata`);
const url = `${env_1.default.DATASTORE_PROJECT_URL}:import`;
async importBackup(name, { env }) {
const input_url = path.join(env.DATASTORE_BACKUP_DIR, `${name}/${name}.overall_export_metadata`);
const url = `${env.DATASTORE_PROJECT_URL}:import`;
const command = `curl -d '{"input_url": "${input_url}"}' -H 'Content-Type: application/json' -X POST ${url}`;
const { stderr } = await execAsync(command);
if (stderr) {
Expand All @@ -116,38 +115,43 @@ let GsUtilResolver = class GsUtilResolver {
};
__decorate([
(0, type_graphql_1.Query)(() => String),
__param(0, (0, type_graphql_1.Ctx)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], GsUtilResolver.prototype, "getProjectId", null);
__decorate([
(0, type_graphql_1.Query)(() => [types_1.DatastoreBackup]),
(0, ValidateEnv_1.default)(['DATASTORE_BACKUP_BUCKET']),
__param(0, (0, type_graphql_1.Ctx)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], GsUtilResolver.prototype, "getBackups", null);
__decorate([
(0, type_graphql_1.Mutation)(() => String),
(0, ValidateEnv_1.default)(['DATASTORE_BACKUP_BUCKET', 'PROJECT_ID']),
__param(0, (0, type_graphql_1.Ctx)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], GsUtilResolver.prototype, "startBackup", null);
__decorate([
(0, type_graphql_1.Mutation)(() => String),
(0, ValidateEnv_1.default)(['DATASTORE_BACKUP_BUCKET', 'DATASTORE_BACKUP_DIR']),
__param(0, (0, type_graphql_1.Arg)("name")),
__param(1, (0, type_graphql_1.Ctx)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:paramtypes", [String, Object]),
__metadata("design:returntype", Promise)
], GsUtilResolver.prototype, "downloadBackup", null);
__decorate([
(0, type_graphql_1.Mutation)(() => String),
(0, ValidateEmulatorRunning_1.default)(),
__param(0, (0, type_graphql_1.Arg)("name")),
__param(1, (0, type_graphql_1.Ctx)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:paramtypes", [String, Object]),
__metadata("design:returntype", Promise)
], GsUtilResolver.prototype, "importBackup", null);
GsUtilResolver = __decorate([
Expand Down
14 changes: 13 additions & 1 deletion src/server/lib/src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,27 @@ const resolver_2 = __importDefault(require("./schema/namespaces/resolver"));
const resolver_3 = __importDefault(require("./schema/entities/resolver"));
const scalars_1 = require("./schema/entities/scalars");
const resolver_4 = __importDefault(require("./schema/gsutil/resolver"));
const env_1 = __importDefault(require("./env"));
function setEnv({ projectId, emulatorHost, port, backupBucket, backupDir }) {
process.env.PROJECT_ID = projectId;
process.env.DATASTORE_EMULATOR_HOST = emulatorHost;
process.env.SERVER_PORT = port.toString();
process.env.DATASTORE_BACKUP_BUCKET = backupBucket;
process.env.DATASTORE_BACKUP_DIR = backupDir;
const env = ["PROJECT_ID", "DATASTORE_EMULATOR_HOST", "SERVER_PORT", "DATASTORE_BACKUP_BUCKET", "DATASTORE_BACKUP_DIR"];
for (const key of env) {
const element = process.env[key];
if (element) {
console.log("✅", key, element);
}
else {
console.log("❌", key, element);
}
}
}
async function boostrap({ projectId, emulatorHost, port, backupBucket, backupDir }) {
setEnv({ projectId, emulatorHost, port, backupBucket, backupDir });
const env = (0, env_1.default)();
const app = (0, express_1.default)();
const httpServer = http_1.default.createServer(app);
const datastore = (0, datastore_1.default)();
Expand All @@ -45,7 +57,7 @@ async function boostrap({ projectId, emulatorHost, port, backupBucket, backupDir
app.use((0, cors_1.default)());
const server = new apollo_server_express_1.ApolloServer({
schema,
context: { datastore },
context: { datastore, env },
introspection: true,
plugins: [
process.env.NODE_ENV === "production"
Expand Down
4 changes: 3 additions & 1 deletion src/server/lib/src/types/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Datastore } from "@google-cloud/datastore";
import type { Datastore } from "@google-cloud/datastore";
import type { Env } from "../env";
export declare type Context = {
datastore: Datastore;
env: Env;
};
8 changes: 4 additions & 4 deletions src/server/lib/src/utils/checkIfEmulatorRunning.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ const util_1 = require("util");
const execAsync = (0, util_1.promisify)(child_process_1.exec);
async function checkIfEmulatorRunning() {
try {
const { stderr, stdout } = await execAsync(`curl -X GET -L ${process.env.DATASTORE_EMULATOR_HOST}`);
const { stderr, stdout } = await execAsync(`curl --write-out '%{http_code}' --silent --output /dev/null -X GET -L ${process.env.DATASTORE_EMULATOR_HOST}`);
if (stdout.trim() === '200') {
return true;
}
if (stderr) {
return false;
}
if (stdout === "ok") {
return true;
}
return false;
}
catch (error) {
Expand Down
70 changes: 38 additions & 32 deletions src/server/src/env.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require("dotenv").config();

type Env = {
export type Env = {
DATASTORE_EMULATOR_HOST: string;
DATASTORE_BACKUP_BUCKET: string;
DATASTORE_BACKUP_DIR: string;
Expand All @@ -9,37 +9,43 @@ type Env = {
DATASTORE_PROJECT_URL: string;
};

const {
DATASTORE_EMULATOR_HOST,
DATASTORE_BACKUP_BUCKET,
PROJECT_ID,
DATASTORE_BACKUP_DIR,
} = process.env;

const DATASTORE_EMULATOR_PORT = Number(
DATASTORE_EMULATOR_HOST.match(/\d+/)![0]
);

const DATASTORE_PROJECT_URL = `${DATASTORE_EMULATOR_HOST}/v1/projects/${PROJECT_ID}`;

const env: Env = {
DATASTORE_EMULATOR_HOST: DATASTORE_EMULATOR_HOST,
DATASTORE_BACKUP_BUCKET: DATASTORE_BACKUP_BUCKET,
DATASTORE_BACKUP_DIR: DATASTORE_BACKUP_DIR,
PROJECT_ID: PROJECT_ID,
DATASTORE_EMULATOR_PORT: DATASTORE_EMULATOR_PORT,
DATASTORE_PROJECT_URL: DATASTORE_PROJECT_URL,
};

for (const key in env) {
const typedKey = key as keyof Env;
const element = env[typedKey];

if (element) {
console.log("✅", key, element);
} else {
console.log("❌", key, element);
function getEnv() {
const {
DATASTORE_EMULATOR_HOST = '',
DATASTORE_BACKUP_BUCKET = '',
PROJECT_ID = '',
DATASTORE_BACKUP_DIR = '',
} = process.env;

const DATASTORE_EMULATOR_HOST_MATCHES = DATASTORE_EMULATOR_HOST.match(/\d+/);

const DATASTORE_EMULATOR_PORT = Number(
DATASTORE_EMULATOR_HOST_MATCHES ? DATASTORE_EMULATOR_HOST_MATCHES[0] : 0
);

const DATASTORE_PROJECT_URL = `${DATASTORE_EMULATOR_HOST}/v1/projects/${PROJECT_ID}`;

const env: Env = {
DATASTORE_EMULATOR_HOST: DATASTORE_EMULATOR_HOST,
DATASTORE_BACKUP_BUCKET: DATASTORE_BACKUP_BUCKET,
DATASTORE_BACKUP_DIR: DATASTORE_BACKUP_DIR,
PROJECT_ID: PROJECT_ID,
DATASTORE_EMULATOR_PORT: DATASTORE_EMULATOR_PORT,
DATASTORE_PROJECT_URL: DATASTORE_PROJECT_URL,
};

for (const key in env) {
const typedKey = key as keyof Env;
const element = env[typedKey];

if (element) {
console.log("✅", key, element);
} else {
console.log("❌", key, element);
}
}

return env;
}

export default env;
export default getEnv;
Loading

0 comments on commit 4d27c3a

Please sign in to comment.