Compare commits
No commits in common. "main" and "template" have entirely different histories.
14
.env.example
14
.env.example
@ -2,17 +2,3 @@ DATABASE_URL=postgres://user:password@127.0.0.1:5432/postgres
|
||||
REDIS_URL=redis://127.0.0.1:6379/
|
||||
PORT=8080
|
||||
HOST=127.0.0.1
|
||||
PUBLIC_API_URL=http://localhost:3000
|
||||
FRONTEND_URL=http://localhost:3002
|
||||
SITES_HOST=http://localhost:3001
|
||||
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_SECRET=
|
||||
|
||||
OPENAI_TOKEN=
|
||||
|
||||
CERTS_URL=
|
||||
|
||||
STRIPE_KEY=
|
||||
STRIPE_WEBHOOK_SECRET=
|
||||
STRIPE_SUBSCRIPTION_PRICE_ID=
|
21
Dockerfile
21
Dockerfile
@ -1,21 +0,0 @@
|
||||
FROM node:20-alpine
|
||||
|
||||
# Create app directory
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Install app dependencies
|
||||
# A wildcard is used to ensure both package.json AND package-lock.json are copied
|
||||
# where available (npm@5+) and yarn.lock because we are using yarn
|
||||
COPY package*.json yarn.lock ./
|
||||
|
||||
# Run yarn without generating a yarn.lock file
|
||||
RUN yarn --pure-lockfile
|
||||
|
||||
# Bundle app source
|
||||
COPY . ./
|
||||
|
||||
# Use the port used by our server.js configuration
|
||||
EXPOSE 3000
|
||||
|
||||
# This will run `yarn start` when the docker image is ran
|
||||
CMD [ "yarn", "start" ]
|
@ -1,12 +0,0 @@
|
||||
import * as dotenv from 'dotenv'
|
||||
dotenv.config()
|
||||
|
||||
|
||||
export default {
|
||||
"out": "./src/db/migrations",
|
||||
"schema": "./src/db/schemas.js",
|
||||
"dbCredentials": {
|
||||
"url": process.env.DATABASE_URL
|
||||
},
|
||||
"dialect": "postgresql"
|
||||
}
|
4
drizzle.config.json
Normal file
4
drizzle.config.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"out": "./src/db/migrations",
|
||||
"schema": "./src/db/schemas.ts"
|
||||
}
|
10518
package-lock.json
generated
10518
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
@ -9,20 +9,19 @@
|
||||
"license": "none",
|
||||
"scripts": {
|
||||
"lint": "xo",
|
||||
"dev": "tsx watch --clear-screen=false src/index.js",
|
||||
"dev": "tsx watch --clear-screen=false src/index.ts",
|
||||
"prettier": "prettier --write .",
|
||||
"migrate": "drizzle-kit generate:pg",
|
||||
"build": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cli-color": "^2.0.6",
|
||||
"@types/node": "^20.10.4",
|
||||
"@types/pg": "^8.10.9",
|
||||
"@types/stripe-v3": "^3.1.33",
|
||||
"cli-color": "^2.0.3",
|
||||
"dotenv": "^16.3.1",
|
||||
"drizzle-kit": "^0.22.4",
|
||||
"pg": "^8.12.0",
|
||||
"drizzle-kit": "^0.20.6",
|
||||
"prettier": "^3.1.1",
|
||||
"tsc-alias": "^1.8.8",
|
||||
"tsx": "^3.12.7",
|
||||
@ -30,25 +29,13 @@
|
||||
"xo": "^0.56.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@distube/ytdl-core": "^4.14.4",
|
||||
"@fastify/cookie": "^9.3.1",
|
||||
"@fastify/cors": "^8.4.2",
|
||||
"@fastify/multipart": "^8.2.0",
|
||||
"@fastify/oauth2": "^7.8.0",
|
||||
"@neondatabase/serverless": "^0.9.3",
|
||||
"@sentry/node": "^8.9.2",
|
||||
"drizzle-orm": "^0.31.1",
|
||||
"drizzle-orm": "^0.29.1",
|
||||
"fastify": "^4.25.0",
|
||||
"fastify-plugin": "^4.5.1",
|
||||
"fastify-raw-body": "^4.3.0",
|
||||
"googleapis": "^134.0.0",
|
||||
"nodemailer": "^6.9.14",
|
||||
"openai": "^4.38.5",
|
||||
"pg": "^8.11.3",
|
||||
"redis": "^4.6.11",
|
||||
"simple-get": "^4.0.1",
|
||||
"stripe": "^15.7.0",
|
||||
"tsc": "^2.0.4",
|
||||
"xml2js": "^0.6.2",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"xo": {
|
||||
|
@ -2,38 +2,39 @@ import * as schema from "./schemas.js";
|
||||
import { env, Logger } from "../utils/index.js";
|
||||
import { drizzle } from "drizzle-orm/node-postgres";
|
||||
import { migrate } from "drizzle-orm/node-postgres/migrator";
|
||||
import pg from 'pg'
|
||||
const { Pool } = pg
|
||||
import pgpkg from 'pg';
|
||||
const { Pool } = pgpkg;
|
||||
|
||||
/** @type {ReturnType<typeof drizzle<typeof schema>>} */
|
||||
export let db;
|
||||
|
||||
export const initDb = async () => {
|
||||
const client = new Pool({
|
||||
const pool = await new Pool({
|
||||
connectionString: env.DATABASE_URL,
|
||||
keepAlive: true
|
||||
})
|
||||
.connect()
|
||||
.then((client) => {
|
||||
Logger.info("INIT", "Connected to database");
|
||||
|
||||
return client;
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("INIT", `Failed to connect to database ${String(error)}}`);
|
||||
throw new Error(`Failed to connect to database ${String(error)}`);
|
||||
});
|
||||
|
||||
client.on('error', e => {
|
||||
console.error('Database error', e);
|
||||
client = null;
|
||||
});
|
||||
|
||||
await client.connect();
|
||||
|
||||
db = drizzle(client, {
|
||||
db = drizzle(pool, {
|
||||
schema,
|
||||
});
|
||||
|
||||
|
||||
// await migrate(db, {
|
||||
// migrationsFolder: "./src/db/migrations",
|
||||
// })
|
||||
// .then(() => {
|
||||
// Logger.info("INIT", "Migrated database");
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// Logger.error("INIT", `Failed to migrate database ${String(error)}`);
|
||||
// throw new Error(`Failed to migrate database ${String(error)}`);
|
||||
// });
|
||||
await migrate(db, {
|
||||
migrationsFolder: "./src/db/migrations",
|
||||
})
|
||||
.then(() => {
|
||||
Logger.info("INIT", "Migrated database");
|
||||
})
|
||||
.catch((error) => {
|
||||
Logger.error("INIT", `Failed to migrate database ${String(error)}`);
|
||||
throw new Error(`Failed to migrate database ${String(error)}`);
|
||||
});
|
||||
};
|
||||
|
@ -1,99 +0,0 @@
|
||||
-- Current sql file was generated after introspecting the database
|
||||
-- If you want to run this migration please uncomment this code before executing migrations
|
||||
/*
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."subscription_tier" AS ENUM('free', 'basic', 'pro', 'enterprise');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "signups" (
|
||||
"email" text NOT NULL,
|
||||
"site_id" uuid NOT NULL,
|
||||
"created_at" timestamp DEFAULT now() NOT NULL,
|
||||
"source" text
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "users" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"name" text,
|
||||
"email" text,
|
||||
"channel_id" text,
|
||||
"google_id" text,
|
||||
"uploads_playlist_id" text,
|
||||
"subscription_tier" "subscription_tier" DEFAULT 'free' NOT NULL,
|
||||
"tokens" integer DEFAULT 0 NOT NULL,
|
||||
"stripe_id" text
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "sites" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"user_id" uuid,
|
||||
"name" text,
|
||||
"primary_color_hex" varchar(6) DEFAULT 'c4ced4'::character varying NOT NULL,
|
||||
"secondary_color_hex" varchar(6) DEFAULT '27251f'::character varying NOT NULL,
|
||||
"text_color_hex" varchar(6) DEFAULT 'ffffff'::character varying NOT NULL,
|
||||
"title" text DEFAULT 'The best blog in the world!',
|
||||
"subtitle" text DEFAULT 'Some extra info about the best blog in the world!',
|
||||
"domain" text,
|
||||
"send_freebie" boolean DEFAULT false,
|
||||
"freebie_name" text DEFAULT '',
|
||||
"freebie_url" text DEFAULT '',
|
||||
"freebie_text" text DEFAULT '',
|
||||
"freebie_image_url" text DEFAULT '',
|
||||
"subdomain_slug" text,
|
||||
"social_medias" jsonb
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "sessions" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"user_id" uuid,
|
||||
"google_access_token" text,
|
||||
"google_refresh_token" text,
|
||||
"expires_at" timestamp
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "articles" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
||||
"site_id" uuid,
|
||||
"content" text,
|
||||
"source_video_id" text,
|
||||
"title" text,
|
||||
"seo_slug" text,
|
||||
"created_at" timestamp DEFAULT now(),
|
||||
"is_public" boolean DEFAULT false,
|
||||
"views" integer DEFAULT 0,
|
||||
"seo_title" text,
|
||||
"seo_description" text,
|
||||
"excerp" text
|
||||
);
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE IF NOT EXISTS "waitlist" (
|
||||
"email" text
|
||||
);
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "signups" ADD CONSTRAINT "signups_site_id_sites_id_fk" FOREIGN KEY ("site_id") REFERENCES "public"."sites"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "sites" ADD CONSTRAINT "sites_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."users"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "articles" ADD CONSTRAINT "articles_site_id_sites_id_fk" FOREIGN KEY ("site_id") REFERENCES "public"."sites"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
|
||||
*/
|
5
src/db/migrations/0000_plain_killmonger.sql
Normal file
5
src/db/migrations/0000_plain_killmonger.sql
Normal file
@ -0,0 +1,5 @@
|
||||
CREATE TABLE IF NOT EXISTS "users" (
|
||||
"id" serial PRIMARY KEY NOT NULL,
|
||||
"full_name" text,
|
||||
"phone" varchar(256)
|
||||
);
|
@ -1,5 +0,0 @@
|
||||
ALTER TABLE "sites" ALTER COLUMN "primary_color_hex" SET DEFAULT 'c4ced4';--> statement-breakpoint
|
||||
ALTER TABLE "sites" ALTER COLUMN "secondary_color_hex" SET DEFAULT '27251f';--> statement-breakpoint
|
||||
ALTER TABLE "sites" ALTER COLUMN "text_color_hex" SET DEFAULT 'ffffff';--> statement-breakpoint
|
||||
ALTER TABLE "sites" ALTER COLUMN "domain" SET DEFAULT null;--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS "domainUniqueIndex" ON "sites" USING btree ((lower("domain"))) WHERE "sites"."domain" IS NOT NULL;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "sites" ALTER COLUMN "domain" SET DEFAULT NULL;
|
@ -1,2 +0,0 @@
|
||||
DROP INDEX IF EXISTS "domainUniqueIndex";--> statement-breakpoint
|
||||
ALTER TABLE "sites" ADD CONSTRAINT "domainUniqueIndex" UNIQUE NULLS NOT DISTINCT("domain");
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "sites" DROP CONSTRAINT "domainUniqueIndex";--> statement-breakpoint
|
||||
ALTER TABLE "sites" ADD CONSTRAINT "domainUniqueIndex" UNIQUE("domain");
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "sites" DROP CONSTRAINT "domainUniqueIndex";--> statement-breakpoint
|
||||
ALTER TABLE "sites" ADD CONSTRAINT "sites_domain_unique" UNIQUE("domain");
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "users" ALTER COLUMN "tokens" SET DEFAULT 200;--> statement-breakpoint
|
||||
ALTER TABLE "sites" ADD COLUMN "auto_publish" boolean DEFAULT false;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "sites" ADD COLUMN "pubsub_expiry" date;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "sites" ALTER COLUMN "pubsub_expiry" SET DATA TYPE timestamp;
|
@ -1,7 +0,0 @@
|
||||
DO $$ BEGIN
|
||||
CREATE TYPE "public"."article_status" AS ENUM('queued', 'transcribing', 'generating', 'done');
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "articles" ADD COLUMN "status" "article_status" DEFAULT 'done';
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "articles" ALTER COLUMN "status" SET DEFAULT 'queued';
|
@ -1 +0,0 @@
|
||||
ALTER TYPE "article_status" ADD VALUE 'error';
|
@ -1,3 +0,0 @@
|
||||
ALTER TABLE "sites" ALTER COLUMN "freebie_name" SET DEFAULT 'Our newsletter';--> statement-breakpoint
|
||||
ALTER TABLE "sites" ADD COLUMN "use_contact_page" boolean DEFAULT false;--> statement-breakpoint
|
||||
ALTER TABLE "sites" ADD COLUMN "contact_email" text;
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "sites" ADD COLUMN "use_about_page" boolean DEFAULT true;--> statement-breakpoint
|
||||
ALTER TABLE "sites" ADD COLUMN "about_text" text;
|
@ -1,2 +0,0 @@
|
||||
ALTER TABLE "users" ADD COLUMN "subscribed_until" date DEFAULT '1970-01-01';--> statement-breakpoint
|
||||
ALTER TABLE "users" ADD COLUMN "tokens_claimed" date;
|
@ -1 +0,0 @@
|
||||
ALTER TABLE "users" ADD COLUMN "trial_used" boolean DEFAULT false;
|
@ -1,452 +1,42 @@
|
||||
{
|
||||
"id": "00000000-0000-0000-0000-000000000000",
|
||||
"prevId": "",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"version": "5",
|
||||
"dialect": "pg",
|
||||
"id": "478200dd-a614-41dd-9cd1-f6368405417e",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"tables": {
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"type": "serial",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
"notNull": true
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"full_name": {
|
||||
"name": "full_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"phone": {
|
||||
"name": "phone",
|
||||
"type": "varchar(256)",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'::character varying"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'::character varying"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'::character varying"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"schemaTo": "public",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
],
|
||||
"schema": "public"
|
||||
"compositePrimaryKeys": {}
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"schemas": {},
|
||||
"tables": {},
|
||||
"columns": {}
|
||||
},
|
||||
"internal": {
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,463 +0,0 @@
|
||||
{
|
||||
"id": "4bc82cd1-68f2-4b03-bdc9-058a4f3ff395",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": null
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"domainUniqueIndex": {
|
||||
"name": "domainUniqueIndex",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "(lower(\"domain\"))",
|
||||
"asc": true,
|
||||
"isExpression": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": true,
|
||||
"where": "\"sites\".\"domain\" IS NOT NULL",
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,463 +0,0 @@
|
||||
{
|
||||
"id": "ca4576ea-6a09-4a8d-afe2-ad00dd56505f",
|
||||
"prevId": "4bc82cd1-68f2-4b03-bdc9-058a4f3ff395",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"domainUniqueIndex": {
|
||||
"name": "domainUniqueIndex",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "(lower(\"domain\"))",
|
||||
"asc": true,
|
||||
"isExpression": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": true,
|
||||
"where": "\"sites\".\"domain\" IS NOT NULL",
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,454 +0,0 @@
|
||||
{
|
||||
"id": "a8542e87-bade-4eae-b740-8ca9d8429118",
|
||||
"prevId": "ca4576ea-6a09-4a8d-afe2-ad00dd56505f",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"domainUniqueIndex": {
|
||||
"name": "domainUniqueIndex",
|
||||
"nullsNotDistinct": true,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,454 +0,0 @@
|
||||
{
|
||||
"id": "3332ba7a-6f32-4ee9-8c5a-61dfbe163bda",
|
||||
"prevId": "a8542e87-bade-4eae-b740-8ca9d8429118",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"domainUniqueIndex": {
|
||||
"name": "domainUniqueIndex",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,454 +0,0 @@
|
||||
{
|
||||
"id": "e3391040-c733-41df-ab35-ddb8c0bbec80",
|
||||
"prevId": "3332ba7a-6f32-4ee9-8c5a-61dfbe163bda",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,461 +0,0 @@
|
||||
{
|
||||
"id": "00d3bd2f-2c64-4026-982e-e67ce4a45a11",
|
||||
"prevId": "e3391040-c733-41df-ab35-ddb8c0bbec80",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,467 +0,0 @@
|
||||
{
|
||||
"id": "77f7612a-c9c8-4843-b0b6-09842cd9cff7",
|
||||
"prevId": "00d3bd2f-2c64-4026-982e-e67ce4a45a11",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "date",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,467 +0,0 @@
|
||||
{
|
||||
"id": "d4c8325d-683a-4d6d-bcf7-bf16892332cc",
|
||||
"prevId": "77f7612a-c9c8-4843-b0b6-09842cd9cff7",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,485 +0,0 @@
|
||||
{
|
||||
"id": "805686b7-a39a-4dd8-b119-37d73e86d686",
|
||||
"prevId": "d4c8325d-683a-4d6d-bcf7-bf16892332cc",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "article_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'done'"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.article_status": {
|
||||
"name": "article_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"queued",
|
||||
"transcribing",
|
||||
"generating",
|
||||
"done"
|
||||
]
|
||||
},
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,485 +0,0 @@
|
||||
{
|
||||
"id": "9e95f80e-79e7-4af0-9a8e-327fb358ec26",
|
||||
"prevId": "805686b7-a39a-4dd8-b119-37d73e86d686",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "article_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'queued'"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.article_status": {
|
||||
"name": "article_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"queued",
|
||||
"transcribing",
|
||||
"generating",
|
||||
"done"
|
||||
]
|
||||
},
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,486 +0,0 @@
|
||||
{
|
||||
"id": "1b69d63a-4517-42bc-aa1f-0ae6ed4ac685",
|
||||
"prevId": "9e95f80e-79e7-4af0-9a8e-327fb358ec26",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "article_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'queued'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.article_status": {
|
||||
"name": "article_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"queued",
|
||||
"transcribing",
|
||||
"generating",
|
||||
"done",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,499 +0,0 @@
|
||||
{
|
||||
"id": "dcc6e5bd-8fea-4462-8f49-5cfc09408ab7",
|
||||
"prevId": "1b69d63a-4517-42bc-aa1f-0ae6ed4ac685",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "article_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'queued'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Our newsletter'"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"use_contact_page": {
|
||||
"name": "use_contact_page",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"contact_email": {
|
||||
"name": "contact_email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.article_status": {
|
||||
"name": "article_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"queued",
|
||||
"transcribing",
|
||||
"generating",
|
||||
"done",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,512 +0,0 @@
|
||||
{
|
||||
"id": "de65dcf5-f6de-434b-80b6-ba199df3a96a",
|
||||
"prevId": "dcc6e5bd-8fea-4462-8f49-5cfc09408ab7",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "article_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'queued'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Our newsletter'"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"use_contact_page": {
|
||||
"name": "use_contact_page",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"contact_email": {
|
||||
"name": "contact_email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"use_about_page": {
|
||||
"name": "use_about_page",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"about_text": {
|
||||
"name": "about_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.article_status": {
|
||||
"name": "article_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"queued",
|
||||
"transcribing",
|
||||
"generating",
|
||||
"done",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,525 +0,0 @@
|
||||
{
|
||||
"id": "674d04c7-a853-4f20-98ac-b92e33d6d017",
|
||||
"prevId": "de65dcf5-f6de-434b-80b6-ba199df3a96a",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "article_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'queued'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Our newsletter'"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"use_contact_page": {
|
||||
"name": "use_contact_page",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"contact_email": {
|
||||
"name": "contact_email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"use_about_page": {
|
||||
"name": "use_about_page",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"about_text": {
|
||||
"name": "about_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"subscribed_until": {
|
||||
"name": "subscribed_until",
|
||||
"type": "date",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'1970-01-01'"
|
||||
},
|
||||
"tokens_claimed": {
|
||||
"name": "tokens_claimed",
|
||||
"type": "date",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.article_status": {
|
||||
"name": "article_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"queued",
|
||||
"transcribing",
|
||||
"generating",
|
||||
"done",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -1,532 +0,0 @@
|
||||
{
|
||||
"id": "5df89ef6-dcab-4661-87f4-ad81b88bf4f4",
|
||||
"prevId": "674d04c7-a853-4f20-98ac-b92e33d6d017",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.articles": {
|
||||
"name": "articles",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"content": {
|
||||
"name": "content",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"source_video_id": {
|
||||
"name": "source_video_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_slug": {
|
||||
"name": "seo_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"is_public": {
|
||||
"name": "is_public",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"views": {
|
||||
"name": "views",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": 0
|
||||
},
|
||||
"seo_title": {
|
||||
"name": "seo_title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"seo_description": {
|
||||
"name": "seo_description",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"excerp": {
|
||||
"name": "excerp",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"status": {
|
||||
"name": "status",
|
||||
"type": "article_status",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'queued'"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"articles_site_id_sites_id_fk": {
|
||||
"name": "articles_site_id_sites_id_fk",
|
||||
"tableFrom": "articles",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sessions": {
|
||||
"name": "sessions",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_access_token": {
|
||||
"name": "google_access_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"google_refresh_token": {
|
||||
"name": "google_refresh_token",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"expires_at": {
|
||||
"name": "expires_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sessions_user_id_users_id_fk": {
|
||||
"name": "sessions_user_id_users_id_fk",
|
||||
"tableFrom": "sessions",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.signups": {
|
||||
"name": "signups",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"site_id": {
|
||||
"name": "site_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"source": {
|
||||
"name": "source",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"signups_site_id_sites_id_fk": {
|
||||
"name": "signups_site_id_sites_id_fk",
|
||||
"tableFrom": "signups",
|
||||
"tableTo": "sites",
|
||||
"columnsFrom": [
|
||||
"site_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.sites": {
|
||||
"name": "sites",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"user_id": {
|
||||
"name": "user_id",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"primary_color_hex": {
|
||||
"name": "primary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'c4ced4'"
|
||||
},
|
||||
"secondary_color_hex": {
|
||||
"name": "secondary_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'27251f'"
|
||||
},
|
||||
"text_color_hex": {
|
||||
"name": "text_color_hex",
|
||||
"type": "varchar(6)",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'ffffff'"
|
||||
},
|
||||
"title": {
|
||||
"name": "title",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'The best blog in the world!'"
|
||||
},
|
||||
"subtitle": {
|
||||
"name": "subtitle",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Some extra info about the best blog in the world!'"
|
||||
},
|
||||
"domain": {
|
||||
"name": "domain",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "NULL"
|
||||
},
|
||||
"send_freebie": {
|
||||
"name": "send_freebie",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"freebie_name": {
|
||||
"name": "freebie_name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'Our newsletter'"
|
||||
},
|
||||
"freebie_url": {
|
||||
"name": "freebie_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_text": {
|
||||
"name": "freebie_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"freebie_image_url": {
|
||||
"name": "freebie_image_url",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "''"
|
||||
},
|
||||
"subdomain_slug": {
|
||||
"name": "subdomain_slug",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"social_medias": {
|
||||
"name": "social_medias",
|
||||
"type": "jsonb",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"auto_publish": {
|
||||
"name": "auto_publish",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"pubsub_expiry": {
|
||||
"name": "pubsub_expiry",
|
||||
"type": "timestamp",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"use_contact_page": {
|
||||
"name": "use_contact_page",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"contact_email": {
|
||||
"name": "contact_email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"use_about_page": {
|
||||
"name": "use_about_page",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": true
|
||||
},
|
||||
"about_text": {
|
||||
"name": "about_text",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"sites_user_id_users_id_fk": {
|
||||
"name": "sites_user_id_users_id_fk",
|
||||
"tableFrom": "sites",
|
||||
"tableTo": "users",
|
||||
"columnsFrom": [
|
||||
"user_id"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"sites_domain_unique": {
|
||||
"name": "sites_domain_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"domain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"public.users": {
|
||||
"name": "users",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"google_id": {
|
||||
"name": "google_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"stripe_id": {
|
||||
"name": "stripe_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"name": {
|
||||
"name": "name",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"channel_id": {
|
||||
"name": "channel_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"uploads_playlist_id": {
|
||||
"name": "uploads_playlist_id",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"type": "subscription_tier",
|
||||
"typeSchema": "public",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "'free'"
|
||||
},
|
||||
"subscribed_until": {
|
||||
"name": "subscribed_until",
|
||||
"type": "date",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": "'1970-01-01'"
|
||||
},
|
||||
"tokens_claimed": {
|
||||
"name": "tokens_claimed",
|
||||
"type": "date",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"trial_used": {
|
||||
"name": "trial_used",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": false,
|
||||
"default": false
|
||||
},
|
||||
"tokens": {
|
||||
"name": "tokens",
|
||||
"type": "integer",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": 200
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
},
|
||||
"public.waitlist": {
|
||||
"name": "waitlist",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"email": {
|
||||
"name": "email",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {}
|
||||
}
|
||||
},
|
||||
"enums": {
|
||||
"public.article_status": {
|
||||
"name": "article_status",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"queued",
|
||||
"transcribing",
|
||||
"generating",
|
||||
"done",
|
||||
"error"
|
||||
]
|
||||
},
|
||||
"public.subscription_tier": {
|
||||
"name": "subscription_tier",
|
||||
"schema": "public",
|
||||
"values": [
|
||||
"free",
|
||||
"basic",
|
||||
"pro",
|
||||
"enterprise"
|
||||
]
|
||||
}
|
||||
},
|
||||
"schemas": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
@ -4,115 +4,10 @@
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1717763053901,
|
||||
"tag": "0000_gorgeous_amazoness",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1717763195953,
|
||||
"tag": "0001_big_sugar_man",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1717793012414,
|
||||
"tag": "0002_perpetual_norman_osborn",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1717849103779,
|
||||
"tag": "0003_organic_dark_beast",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1717852643512,
|
||||
"tag": "0004_lively_frank_castle",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1717852812991,
|
||||
"tag": "0005_smiling_pandemic",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1718267048369,
|
||||
"tag": "0006_happy_red_wolf",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1718353625117,
|
||||
"tag": "0007_early_living_mummy",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1718354167998,
|
||||
"tag": "0008_smart_captain_cross",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1718818623333,
|
||||
"tag": "0009_wooden_weapon_omega",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1718818704691,
|
||||
"tag": "0010_complex_malice",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1719007763731,
|
||||
"tag": "0011_normal_thunderball",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1719133327271,
|
||||
"tag": "0012_magenta_captain_marvel",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1719134353536,
|
||||
"tag": "0013_lucky_vulture",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1719389425401,
|
||||
"tag": "0014_tan_bill_hollister",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 15,
|
||||
"version": "7",
|
||||
"when": 1719403126188,
|
||||
"tag": "0015_nervous_victor_mancha",
|
||||
"breakpoints": true
|
||||
"version": "5",
|
||||
"when": 1686356934306,
|
||||
"tag": "0000_plain_killmonger",
|
||||
"breakpoints": false
|
||||
}
|
||||
]
|
||||
}
|
@ -1,94 +1,7 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { boolean, date, integer, jsonb, pgEnum, pgTable, text, timestamp, unique, uniqueIndex, uuid, varchar } from "drizzle-orm/pg-core";
|
||||
|
||||
export const subscription_enum = pgEnum("subscription_tier", ["free", "basic", "pro", "enterprise"])
|
||||
export const article_status_enum = pgEnum("article_status", ["queued", "transcribing", "generating", "done", "error"])
|
||||
import { pgTable, serial, text, varchar } from "drizzle-orm/pg-core";
|
||||
|
||||
export const users = pgTable("users", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
google_id: text("google_id"),
|
||||
stripe_id: text("stripe_id"),
|
||||
name: text("name"),
|
||||
email: text("email"),
|
||||
channel_id: text("channel_id"),
|
||||
uploads_playlist_id: text("uploads_playlist_id"),
|
||||
subscription_tier: subscription_enum("subscription_tier").default("free").notNull(),
|
||||
subscribed_until: date("subscribed_until").default(`1970-01-01`),
|
||||
tokens_claimed: date("tokens_claimed"),
|
||||
trial_used: boolean("trial_used").default(false),
|
||||
tokens: integer("tokens").notNull()
|
||||
});
|
||||
|
||||
export const sessions = pgTable("sessions", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
user_id: uuid("user_id").references(() => users.id),
|
||||
access_token: text("google_access_token"),
|
||||
refresh_token: text("google_refresh_token"),
|
||||
expires_at: timestamp("expires_at")
|
||||
});
|
||||
|
||||
export function makeid(length) {
|
||||
let result = '';
|
||||
const characters = 'abcdefghijklmnopqrstuvwxyz';
|
||||
const charactersLength = characters.length;
|
||||
let counter = 0;
|
||||
while (counter < length) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
counter += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export const sites = pgTable("sites", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
user_id: uuid("user_id").references(() => users.id),
|
||||
name: text("name"),
|
||||
primary_color_hex: varchar("primary_color_hex", { length: 6 }).default("c4ced4").notNull(),
|
||||
secondary_color_hex: varchar("secondary_color_hex", { length: 6 }).default('27251f').notNull(),
|
||||
text_color_hex: varchar("text_color_hex", { length: 6 }).default('ffffff').notNull(),
|
||||
title: text("title").default("The best blog in the world!"),
|
||||
subtitle: text("subtitle").default("Some extra info about the best blog in the world!"),
|
||||
domain: text("domain").default(sql`NULL`).unique(),
|
||||
use_freebie: boolean("send_freebie").default(false),
|
||||
freebie_title: text("freebie_name").default("Our newsletter"),
|
||||
freebie_url: text("freebie_url").default(""),
|
||||
freebie_text: text("freebie_text").default(""),
|
||||
freebie_image_url: text("freebie_image_url").default(""),
|
||||
subdomain_slug: text("subdomain_slug").$defaultFn(() => {
|
||||
return makeid(10);
|
||||
}),
|
||||
social_medias: jsonb("social_medias"),
|
||||
auto_publish: boolean("auto_publish").default(false),
|
||||
pubsub_expiry: timestamp("pubsub_expiry"),
|
||||
use_contact_page: boolean("use_contact_page").default(false),
|
||||
contact_email: text("contact_email"),
|
||||
use_about_page: boolean("use_about_page").default(true),
|
||||
about_text: text("about_text")
|
||||
});
|
||||
|
||||
export const articles = pgTable("articles", {
|
||||
id: uuid("id").defaultRandom().primaryKey(),
|
||||
site_id: uuid("site_id").references(() => sites.id),
|
||||
content: text("content"),
|
||||
source_video_id: text("source_video_id"),
|
||||
title: text("title"),
|
||||
seo_slug: text("seo_slug"),
|
||||
is_public: boolean("is_public").default(false),
|
||||
views: integer("views").default(0),
|
||||
meta_title: text("seo_title"),
|
||||
meta_desc: text("seo_description"),
|
||||
excerp: text("excerp"),
|
||||
status: article_status_enum("status").default("queued"),
|
||||
created_at: timestamp("created_at").defaultNow()
|
||||
})
|
||||
|
||||
export const signups = pgTable("signups", {
|
||||
email: text("email").notNull(),
|
||||
site_id: uuid("site_id").references(() => sites.id).notNull(),
|
||||
source: text("source"),
|
||||
created_at: timestamp("created_at").defaultNow().notNull()
|
||||
});
|
||||
|
||||
export const waitlist = pgTable("waitlist", {
|
||||
email: text("email")
|
||||
id: serial("id").primaryKey(),
|
||||
fullName: text("full_name"),
|
||||
phone: varchar("phone", { length: 256 }),
|
||||
});
|
15
src/fastify.d.ts
vendored
15
src/fastify.d.ts
vendored
@ -1,21 +1,10 @@
|
||||
import {OAuth2Namespace} from "@fastify/oauth2";
|
||||
import type { db } from "./db";
|
||||
import type { Redis } from "./utils";
|
||||
|
||||
declare module "fastify" {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
||||
interface FastifyRequest {
|
||||
// db: typeof db;
|
||||
// redis: typeof Redis;
|
||||
session?: {
|
||||
id: string,
|
||||
user_id: string,
|
||||
access_token: string,
|
||||
refresh_token: string,
|
||||
expires_at: Date
|
||||
}
|
||||
}
|
||||
interface FastifyInstance {
|
||||
googleOAuth2: OAuth2Namespace
|
||||
db: typeof db;
|
||||
redis: typeof Redis;
|
||||
}
|
||||
}
|
||||
|
97
src/index.js
97
src/index.js
@ -1,49 +1,19 @@
|
||||
import { initDb } from "./db/index.js";
|
||||
import { channelRoutes, authRoutes, videoRoutes, meRoutes, blogRoutes, dashboardRoutes, webhookRoutes } from "./routes/index.js";
|
||||
import { env, Logger } from "./utils/index.js";
|
||||
import { testRoutes } from "./routes/index.js";
|
||||
import { env, Logger, Redis } from "./utils/index.js";
|
||||
import fastify from "fastify";
|
||||
import { middleware } from "./modules/middleware.js";
|
||||
import oauth from '@fastify/oauth2';
|
||||
import fastifyCookie from "@fastify/cookie";
|
||||
import xml2js from 'xml2js';
|
||||
import './utils/sentry.js';
|
||||
// import fastifyMultipart from "@fastify/multipart";
|
||||
import * as Sentry from "@sentry/node";
|
||||
import rawBody from 'fastify-raw-body';
|
||||
const API_VERSION = "v1";
|
||||
|
||||
const API_VERSION = "v1";
|
||||
|
||||
export const main = async () => {
|
||||
const server = fastify({
|
||||
bodyLimit: 1_000_000,
|
||||
trustProxy: true,
|
||||
// logger: true
|
||||
});
|
||||
|
||||
Sentry.setupFastifyErrorHandler(server);
|
||||
|
||||
|
||||
await initDb();
|
||||
// await Redis.initialize();
|
||||
|
||||
// server.register(fastifyMultipart, {
|
||||
// // attachFieldsToBody: true,
|
||||
// });
|
||||
|
||||
server.register(fastifyCookie, {
|
||||
secret: "my-secret", // for cookies signature
|
||||
hook: 'preParsing', // set to false to disable cookie autoparsing or set autoparsing on any of the following hooks: 'onRequest', 'preParsing', 'preHandler', 'preValidation'. default: 'onRequest'
|
||||
parseOptions: {}, // options for parsing cookies
|
||||
});
|
||||
|
||||
server.register(rawBody, {
|
||||
field: 'rawBody', // change the default request.rawBody property name
|
||||
global: false, // add the rawBody to every request. **Default true**
|
||||
encoding: 'utf8', // set it to false to set rawBody as a Buffer **Default utf8**
|
||||
runFirst: true, // get the body before any preParsing hook change/uncompress it. **Default false**
|
||||
routes: [], // array of routes, **`global`** will be ignored, wildcard routes not supported
|
||||
jsonContentTypes: [], // array of content-types to handle as JSON. **Default ['application/json']**
|
||||
})
|
||||
await Redis.initialize();
|
||||
|
||||
server.register(middleware);
|
||||
server.register(import("@fastify/cors"), {
|
||||
@ -52,66 +22,11 @@ export const main = async () => {
|
||||
credentials: true,
|
||||
});
|
||||
|
||||
server.register(oauth, {
|
||||
name: 'googleOAuth2',
|
||||
scope: ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"],
|
||||
credentials: {
|
||||
client: {
|
||||
id: env.GOOGLE_CLIENT_ID,
|
||||
secret: env.GOOGLE_SECRET
|
||||
},
|
||||
auth: oauth.GOOGLE_CONFIGURATION
|
||||
},
|
||||
callbackUriParams: {
|
||||
// custom query param that will be passed to callbackUri
|
||||
access_type: 'offline', // will tell Google to send a refreshToken too
|
||||
},
|
||||
pkce: 'S256',
|
||||
// register a fastify url to start the redirect flow
|
||||
startRedirectPath: '/auth/google',
|
||||
// google redirect here after the user login
|
||||
callbackUri: `${env.PUBLIC_API_URL}/auth/google/callback`
|
||||
});
|
||||
|
||||
server.addContentTypeParser(['text/xml', 'application/xml', 'application/atom+xml'], { parseAs: 'string' }, function (request, payload, done) {
|
||||
xml2js.parseString(payload, function (err, body) {
|
||||
done(err, body)
|
||||
})
|
||||
})
|
||||
|
||||
// Routes
|
||||
server.register(channelRoutes, {
|
||||
prefix: `/channels`,
|
||||
server.register(testRoutes, {
|
||||
prefix: `/${API_VERSION}/test`,
|
||||
});
|
||||
|
||||
server.register(videoRoutes, {
|
||||
prefix: `/videos`,
|
||||
});
|
||||
|
||||
server.register(authRoutes, {
|
||||
prefix: `/auth`,
|
||||
});
|
||||
|
||||
server.register(meRoutes, {
|
||||
prefix: `/me`
|
||||
});
|
||||
|
||||
server.register(blogRoutes, {
|
||||
prefix: `/blog`
|
||||
});
|
||||
|
||||
server.register(dashboardRoutes, {
|
||||
prefix: `/dashboard`
|
||||
});
|
||||
|
||||
server.register(webhookRoutes, {
|
||||
prefix: `/webhooks`
|
||||
});
|
||||
|
||||
server.get("/hello", (req, res) => {
|
||||
res.send({ message: "world", cookies: req.cookies });
|
||||
})
|
||||
|
||||
server.listen({ host: env.HOST, port: env.PORT }, (error, address) => {
|
||||
if (error) {
|
||||
Logger.error("INIT", error.message);
|
||||
|
@ -2,48 +2,17 @@
|
||||
import fp from "fastify-plugin";
|
||||
import { Redis } from "../utils/index.js";
|
||||
import { db } from "../db/index.js";
|
||||
import { sessions } from "../db/schemas.js";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export const middleware = fp(
|
||||
const middleware = fp(
|
||||
/**
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _options
|
||||
*/
|
||||
async (fastify, _options) => {
|
||||
fastify.addHook("onRequest", async (request) => {
|
||||
// request.redis = Redis;
|
||||
// request.db = db;
|
||||
request.redis = Redis;
|
||||
request.db = db;
|
||||
});
|
||||
});
|
||||
|
||||
export const authMiddlewareFn = async (request, response) => {
|
||||
try {
|
||||
// if (!request.headers.authorization || !request.headers.authorization.startsWith("Bearer")) {
|
||||
if (!request.cookies.token) {
|
||||
response.status(401).send({ success: false, message: "Missing authentication token" });
|
||||
return false;
|
||||
}
|
||||
// const token = request.headers.authorization.split(" ")[1];
|
||||
const token = request.cookies.token;
|
||||
|
||||
const session = await db.select().from(sessions).where(eq(sessions.id, token));
|
||||
if (session.length == 0) {
|
||||
response.status(401).send({ success: false, message: "Invalid authentication token" });
|
||||
return false;
|
||||
}
|
||||
// console.log(token);
|
||||
// console.log(session);
|
||||
request.session = session[0];
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
export const authMiddleware = fp(
|
||||
async (fastify, _options) => {
|
||||
fastify.addHook("preValidation", authMiddlewareFn);
|
||||
}
|
||||
)
|
||||
|
||||
export { middleware };
|
||||
|
@ -1,145 +0,0 @@
|
||||
import { createSession as createSession } from '../utils/token.js';
|
||||
import { getUserInfo } from '../utils/youtube.js';
|
||||
import { db } from '../db/index.js';
|
||||
import { sessions, sites, users, users as usersTable } from '../db/schemas.js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { env } from '../utils/env.js';
|
||||
import { authMiddleware, authMiddlewareFn } from '../modules/middleware.js';
|
||||
import { createCustomer } from '../utils/stripe.js';
|
||||
|
||||
/** @typedef {import("fastify").FastifyInstance} FastifyInstance */
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const authRoutes = (fastify, _, done) => {
|
||||
fastify.get("/google/callback", async (request, reply) => {
|
||||
let token = "";
|
||||
try {
|
||||
/** @type {{token: import('@fastify/oauth2').Token}} */
|
||||
const token_response = await fastify.googleOAuth2.getAccessTokenFromAuthorizationCodeFlow(request);
|
||||
token = token_response.token;
|
||||
const user_info = await getUserInfo(token.access_token);
|
||||
if (!user_info.verified_email) {
|
||||
reply.status(400).send({ success: false, message: "Provider email is not verified" });
|
||||
return;
|
||||
}
|
||||
//const channel_info = await getChannelInfo(token.access_token);
|
||||
|
||||
const [existing_user] = await db.select().from(usersTable).where(eq(usersTable.google_id, user_info.id));
|
||||
|
||||
let user;
|
||||
let session_id;
|
||||
await db.transaction(async tx => {
|
||||
try {
|
||||
if (existing_user) {
|
||||
user = existing_user;
|
||||
|
||||
if (token.refresh_token) {
|
||||
await tx.update(sessions).set({
|
||||
refresh_token: token.refresh_token
|
||||
}).where(eq(sessions.user_id, user.id));
|
||||
}
|
||||
}
|
||||
else {
|
||||
const customer = await createCustomer(user_info.email, user_info.name);
|
||||
[user] = await tx.insert(usersTable).values({
|
||||
name: user_info.name,
|
||||
google_id: user_info.id,
|
||||
email: user_info.email,
|
||||
// channel_id: channel_info.id,
|
||||
channel_id: "TEMP_DISABLED",
|
||||
// uploads_playlist_id: channel_info.contentDetails.relatedPlaylists.uploads,
|
||||
uploads_playlist_id: "TEMP_DISABLED",
|
||||
stripe_id: customer.id
|
||||
}).returning({ id: usersTable.id });
|
||||
// console.log("USER MADE")
|
||||
// console.log("user", user);
|
||||
await tx.insert(sites).values({
|
||||
name: `${user_info.name}'s Website`,
|
||||
user_id: user.id
|
||||
});
|
||||
console.log("SITE MADE")
|
||||
|
||||
|
||||
if (user.length == 0) {
|
||||
reply.status(400).send({ success: false, message: "Problem when creating user account" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
let existing_session = await tx.select().from(sessions).where(eq(sessions.user_id, user.id));
|
||||
if (!existing_session || existing_session.length === 0) {
|
||||
let session_info = await createSession(user.id, {
|
||||
access_token: token.access_token,
|
||||
refresh_token: token.refresh_token,
|
||||
expires_at: new Date(token.expires_at)
|
||||
}, tx);
|
||||
console.log("SESSION MADE")
|
||||
|
||||
session_id = session_info.session_id;
|
||||
}
|
||||
else {
|
||||
let session_info = await tx.select().from(users).leftJoin(sessions, eq(sessions.user_id, users.id)).where(eq(users.google_id, user_info.id));
|
||||
if (!session_info || session_info.length == 0) {
|
||||
reply.status(400).send({ success: false, message: "Problem when creating user account" });
|
||||
await tx.rollback();
|
||||
return;
|
||||
}
|
||||
console.log("session_info", session_info);
|
||||
session_id = session_info[0].sessions.id
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
await tx.rollback();
|
||||
return;
|
||||
}
|
||||
})
|
||||
|
||||
reply.setCookie("token", session_id, {
|
||||
httpOnly: true,
|
||||
path: "/",
|
||||
sameSite: false,
|
||||
maxAge: 1000 * 60 * 60 * 24 * 7,
|
||||
domain: "api.youpage.ai"
|
||||
});
|
||||
|
||||
reply.redirect(env.FRONTEND_URL + "/auth?token=" + session_id);
|
||||
|
||||
// response.send({
|
||||
// token: session_id
|
||||
// });
|
||||
return;
|
||||
} catch (e) {
|
||||
if(e.message === "no_channel") {
|
||||
reply.status(400).send("Your account does not have a youtube channel. Please make one.")
|
||||
}
|
||||
// fastify.googleOAuth2.revokeToken(token, "refresh_token");
|
||||
console.log(e);
|
||||
reply.send({ success: false, message: "There was a problem when making your account." });
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
fastify.post("/logout", {
|
||||
preValidation: authMiddlewareFn
|
||||
}, async (req, reply) => {
|
||||
try {
|
||||
await db.delete(sessions).where(eq(sessions.id, req.session.id));
|
||||
// await fastify.googleOAuth2.revokeToken(req.session, "refresh_token", {
|
||||
// "content-type": "application/json"
|
||||
// });
|
||||
console.log("revoked")
|
||||
// console.log(await res.json());
|
||||
|
||||
reply.send({
|
||||
success: true
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
})
|
||||
|
||||
done();
|
||||
};
|
@ -1,214 +0,0 @@
|
||||
import { and, desc, eq, not, or, sql } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { authMiddlewareFn } from "../modules/middleware.js";
|
||||
import { articles, articles as articlesTable, signups as signupsTable, sites, users } from "../db/schemas.js";
|
||||
import { sendContactEmail, sendFreebie } from "../utils/email.js";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("fastify").FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const blogRoutes = (fastify, _, done) => {
|
||||
|
||||
fastify.get("/", {
|
||||
schema: {
|
||||
querystring: {
|
||||
mine: {
|
||||
type: "boolean",
|
||||
},
|
||||
blog_id: {
|
||||
type: "string"
|
||||
},
|
||||
offset: {
|
||||
type: "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}, async (request, response) => {
|
||||
try {
|
||||
const mine = request.query.mine ? request.query.mine : false;
|
||||
const blog_id = request.query.blog_id;
|
||||
if (!mine && blog_id === "") {
|
||||
response.status(400).send({
|
||||
success: false,
|
||||
message: "Request can either have \"mine\" set to true or provide a blog_id"
|
||||
});
|
||||
return;
|
||||
}
|
||||
let clause;
|
||||
let site;
|
||||
if (mine) {
|
||||
if (!(await authMiddlewareFn(request, response))) return;
|
||||
try {
|
||||
[site] = await db.select().from(sites).where(and(eq(sites.user_id, request.session.user_id)));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let referer = new URL(request.headers.origin).host;
|
||||
try {
|
||||
[site] = await db.select().from(sites).where(or(eq(sites.domain, referer), eq(sites.subdomain_slug, referer.split(".")[0])));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
if (!site) {
|
||||
response.status(400).send({
|
||||
success: false,
|
||||
message: "Site not found"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
clause = eq(articlesTable.site_id, site.id);
|
||||
if (!mine) {
|
||||
clause = and(eq(articlesTable.site_id, site.id), eq(articlesTable.is_public, true));
|
||||
}
|
||||
// const access_token = await getAccessToken(fastify, request);
|
||||
|
||||
// const channel = await getChannelInfo(access_token);
|
||||
const results = await db.select({
|
||||
id: articlesTable.id,
|
||||
title: articlesTable.title,
|
||||
seo_slug: articlesTable.seo_slug,
|
||||
views: articlesTable.views,
|
||||
is_public: articlesTable.is_public,
|
||||
created_at: articlesTable.created_at,
|
||||
}).from(articlesTable).where(and(eq(articlesTable.status, "done"), clause)).limit(10).offset(request.query.offset || 0).orderBy(desc(articlesTable.created_at));
|
||||
|
||||
const [{ total }] = await db.select({
|
||||
total: sql`COUNT(*)`
|
||||
}).from(articlesTable).where(clause);
|
||||
|
||||
response.send({
|
||||
success: true,
|
||||
articles: results,
|
||||
total_articles: total,
|
||||
site
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
response.status(500).send({
|
||||
success: false,
|
||||
message: "Unexpected error"
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get("/article", {
|
||||
schema: {
|
||||
querystring: {
|
||||
id: {
|
||||
type: "string"
|
||||
},
|
||||
slug: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}, async (req, reply) => {
|
||||
try {
|
||||
|
||||
const [result] = await db.select().from(articlesTable)
|
||||
.where((req.query.id ? eq(articlesTable.id, req.query.id) : eq(articlesTable.seo_slug, req.query.slug)));
|
||||
|
||||
if (!req.session && result) {
|
||||
await db.update(articlesTable).set({
|
||||
views: sql`${articles.views} + 1`
|
||||
}).where(eq(articlesTable.seo_slug, req.query.slug));
|
||||
}
|
||||
|
||||
reply.send({
|
||||
success: true,
|
||||
article: result
|
||||
});
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
fastify.post("/signup", {
|
||||
schema: {
|
||||
body: {
|
||||
site_id: {
|
||||
type: "string"
|
||||
},
|
||||
email: {
|
||||
type: "string",
|
||||
format: "email"
|
||||
},
|
||||
source: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}, async (req, reply) => {
|
||||
const inserted = await db.insert(signupsTable).values({
|
||||
email: req.body.email,
|
||||
site_id: req.body.site_id,
|
||||
source: req.body.source
|
||||
});
|
||||
|
||||
if (inserted.rowCount != 1) {
|
||||
reply.status(400).send({
|
||||
success: false,
|
||||
message: "Problem when signing up email"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await sendFreebie(req.body.email, req.body.site_id)
|
||||
|
||||
reply.send({
|
||||
success: true
|
||||
});
|
||||
});
|
||||
|
||||
fastify.post("/contact", {
|
||||
body: {
|
||||
email: {
|
||||
type: "string",
|
||||
format: "email"
|
||||
},
|
||||
subject: {
|
||||
type: "string"
|
||||
},
|
||||
content: {
|
||||
type: "string"
|
||||
},
|
||||
blog_id: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}, async (req, reply) => {
|
||||
const [blog] = await db.select().from(sites).where(eq(sites.id, req.body.blog_id));
|
||||
|
||||
if(!blog || !blog.contact_email) {
|
||||
return reply.code(400).send({
|
||||
success: false,
|
||||
code: "invalid_blog"
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await sendContactEmail(blog.contact_email, req.body.email, req.body.subject, req.body.content);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return reply.code(500).send({
|
||||
success: false,
|
||||
code: "problem_sending"
|
||||
});
|
||||
}
|
||||
|
||||
return reply.send({
|
||||
success: true
|
||||
});
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
@ -1,31 +0,0 @@
|
||||
/** @typedef {import("fastify").FastifyInstance} FastifyInstance */
|
||||
|
||||
import { authMiddleware } from "../modules/middleware.js";
|
||||
import { getAccessToken, getChannelInfo } from "../utils/youtube.js";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const channelRoutes = (fastify, _, done) => {
|
||||
fastify.register(authMiddleware);
|
||||
|
||||
fastify.get("/", async (request, response) => {
|
||||
try {
|
||||
const access_token = await getAccessToken(fastify, request);
|
||||
|
||||
const channel = await getChannelInfo(access_token);
|
||||
|
||||
response.send({
|
||||
success: true,
|
||||
channel
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
@ -1,466 +0,0 @@
|
||||
/** @typedef {import("fastify").FastifyInstance} FastifyInstance */
|
||||
|
||||
import { and, desc, eq, getTableColumns, inArray, notInArray, sql, not } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { articles, articles as articlesTable, signups as signupsTable, sites, users } from "../db/schemas.js";
|
||||
import { authMiddleware, authMiddlewareFn } from "../modules/middleware.js";
|
||||
import { jsonToCsv, createBlogFromCaptions, createArticleSlug, getVideoById, env, getWhisperCaptions, getVideoDetails, getVideoWithCaptions } from "../utils/index.js";
|
||||
import { escape } from "querystring";
|
||||
|
||||
const websubVerifyToken = "FQNI4Suzih";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const dashboardRoutes = (fastify, _, done) => {
|
||||
fastify.register(authMiddleware);
|
||||
|
||||
fastify.get("/", async (req, response) => {
|
||||
try {
|
||||
const [{ site_id, user_id }] = await db.select({
|
||||
site_id: sites.id,
|
||||
user_id: sites.user_id
|
||||
}).from(sites).where(eq(sites.user_id, req.session.user_id));
|
||||
|
||||
const recentArticles = await db.select({
|
||||
title: articlesTable.title,
|
||||
views: articlesTable.views,
|
||||
created_at: articlesTable.created_at
|
||||
}).from(articlesTable)
|
||||
.where(eq(articlesTable.site_id, site_id))
|
||||
.orderBy(desc(articlesTable.created_at)).limit(5);
|
||||
|
||||
const recentSignups = await db.select({
|
||||
email: signupsTable.email,
|
||||
created_at: signupsTable.created_at
|
||||
}).from(signupsTable)
|
||||
.where(eq(signupsTable.site_id, site_id))
|
||||
.orderBy(desc(signupsTable.created_at)).limit(8);
|
||||
|
||||
const [{ totalArticles }] = await db.select({ totalArticles: sql`count(*)` }).from(articlesTable).where(and(eq(articlesTable.site_id, site_id), eq(articlesTable.status, "done")));
|
||||
const [{ totalViews }] = await db.select({ totalViews: sql`COALESCE(sum(${articlesTable.views}), 0)` }).from(articlesTable).where(eq(articlesTable.site_id, site_id));
|
||||
const [{ totalEmails }] = await db.select({ totalEmails: sql`count(*)` }).from(signupsTable).where(eq(signupsTable.site_id, site_id));
|
||||
|
||||
response.send({
|
||||
success: true,
|
||||
recentArticles,
|
||||
recentSignups,
|
||||
totalArticles,
|
||||
totalEmails,
|
||||
totalViews
|
||||
});
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
response.status(500).send({
|
||||
success: false,
|
||||
message: "Failed to get dashboard data",
|
||||
log: e.message
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get("/email-export", async (req, response) => {
|
||||
|
||||
});
|
||||
|
||||
fastify.get("/signups", async (req, reply) => {
|
||||
const site = await db.select().from(sites).where(eq(sites.user_id, req.session.user_id));
|
||||
|
||||
if (site[0]?.user_id != req.session.user_id) {
|
||||
reply.status(403).send({ success: false });
|
||||
return;
|
||||
}
|
||||
|
||||
const signups = await db.select().from(signupsTable).where(eq(signupsTable.site_id, site[0].id)).orderBy(desc(signupsTable.created_at));
|
||||
|
||||
reply.send({
|
||||
success: true,
|
||||
signups
|
||||
});
|
||||
});
|
||||
|
||||
fastify.get("/signups/export", async (req, reply) => {
|
||||
try {
|
||||
|
||||
const [{ site_id }] = await db.select({
|
||||
site_id: sites.id
|
||||
}).from(sites).where(eq(sites.user_id, req.session.user_id));
|
||||
|
||||
const signups = await db.select({
|
||||
email: signupsTable.email,
|
||||
source: sql`COALESCE(source, 'Home')`,
|
||||
created_at: signupsTable.created_at
|
||||
}).from(signupsTable).where(eq(signupsTable.site_id, site_id)).orderBy(desc(signupsTable.created_at));
|
||||
|
||||
let result = jsonToCsv(signups);
|
||||
|
||||
reply.send({
|
||||
success: true,
|
||||
data: result
|
||||
});
|
||||
return;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
fastify.put("/article", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string"
|
||||
},
|
||||
is_public: {
|
||||
type: "boolean"
|
||||
},
|
||||
content: {
|
||||
type: "string"
|
||||
},
|
||||
title: {
|
||||
type: "string"
|
||||
},
|
||||
},
|
||||
required: ["id"]
|
||||
}
|
||||
}
|
||||
}, async (req, reply) => {
|
||||
const [article] = await db.select(getTableColumns(articles)).from(articles).leftJoin(sites, eq(sites.id, articles.site_id)).where(eq(sites.user_id, req.session.user_id));
|
||||
|
||||
if (!article) {
|
||||
reply.status(404).send({
|
||||
success: false,
|
||||
message: "This article does not exist."
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (Object.keys(req.body).length > 1) {
|
||||
await db.update(articles).set(JSON.parse(JSON.stringify({ ...req.body, id: undefined }))).where(eq(articles.id, req.body.id));
|
||||
}
|
||||
reply.send({
|
||||
success: true
|
||||
});
|
||||
return;
|
||||
});
|
||||
|
||||
fastify.delete("/article", {
|
||||
schema: {
|
||||
querystring: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string"
|
||||
}
|
||||
},
|
||||
required: ["id"]
|
||||
}
|
||||
}
|
||||
}, async (req, reply) => {
|
||||
const [article] = await db.select(getTableColumns(articles)).from(articles).leftJoin(sites, eq(sites.id, articles.site_id)).where(and(eq(sites.user_id, req.session.user_id), eq(articles.id, req.query.id)));
|
||||
|
||||
if (!article) {
|
||||
reply.status(404).send({
|
||||
success: false,
|
||||
message: "This article does not exist."
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await db.delete(articles).where(eq(articles.id, article.id));
|
||||
|
||||
reply.send({
|
||||
success: true
|
||||
});
|
||||
return;
|
||||
});
|
||||
|
||||
fastify.post("/create", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["video_id"],
|
||||
properties: {
|
||||
video_id: {
|
||||
type: "string",
|
||||
},
|
||||
length: {
|
||||
type: "number",
|
||||
},
|
||||
format: {
|
||||
type: "string"
|
||||
},
|
||||
faq: {
|
||||
type: "boolean"
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}, async (req, reply) => {
|
||||
let article;
|
||||
try {
|
||||
const [{ tokens }] = await db.select({
|
||||
tokens: users.tokens
|
||||
}).from(users).where(eq(users.id, req.session.user_id));
|
||||
|
||||
if (tokens < 1) {
|
||||
reply.send({
|
||||
success: false,
|
||||
code: "insufficient_tokens",
|
||||
message: "Insufficient tokens"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// const access_token = await getAccessToken(fastify, req);
|
||||
|
||||
let urlRegex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|\?v=)([^#\&\?]*).*/;
|
||||
let match = req.body.video_id.match(urlRegex);
|
||||
if (!match) {
|
||||
reply.status(400).send({
|
||||
success: false,
|
||||
message: "Invalid Youtube URL"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const site = await db.select().from(sites).where(eq(sites.user_id, req.session.user_id));
|
||||
|
||||
// const video_data = await getVideoDetails(req.body.video_id);
|
||||
const video_data = await getVideoWithCaptions(req.body.video_id);
|
||||
|
||||
reply.send({
|
||||
success: true
|
||||
});
|
||||
|
||||
article = (await db.insert(articlesTable).values({
|
||||
title: video_data.title,
|
||||
source_video_id: match[2],
|
||||
status: "transcribing",
|
||||
site_id: site[0].id,
|
||||
is_public: false
|
||||
}).returning({ id: articlesTable.id }))[0];
|
||||
|
||||
// video_data.captions = await getWhisperCaptions(req.body.video_id);
|
||||
|
||||
// const video_data = await getVideoById(access_token, req.body.video_id);
|
||||
await db.update(articlesTable).set({
|
||||
status: "generating"
|
||||
}).where(eq(articlesTable.id, article.id));
|
||||
|
||||
const blog_content_json = await createBlogFromCaptions(video_data.captions, { title: video_data.title, description: video_data.description }, req.body);
|
||||
// TODO: once I add multiple sites per user, this should come from the client
|
||||
|
||||
await db.update(articlesTable).set({
|
||||
title: blog_content_json.title,
|
||||
content: blog_content_json.content,
|
||||
meta_title: blog_content_json.meta_title,
|
||||
meta_desc: blog_content_json.meta_desc,
|
||||
excerp: blog_content_json.excerp,
|
||||
seo_slug: createArticleSlug(blog_content_json.title),
|
||||
is_public: false,
|
||||
status: "done"
|
||||
}).where(eq(articlesTable.id, article.id));
|
||||
|
||||
await db.update(users).set({
|
||||
tokens: tokens - 1
|
||||
}).where(eq(users.id, req.session.user_id));
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
||||
if(e.message == "no_captions") {
|
||||
reply.status(400).send({
|
||||
success: false,
|
||||
message: "This video does not have captions!"
|
||||
});
|
||||
}
|
||||
|
||||
article ? await db.update(articlesTable).set({
|
||||
status: "error"
|
||||
}).where(eq(articlesTable.id, article.id)) : "";
|
||||
|
||||
let message = "problem_creating_article";
|
||||
|
||||
reply.status(500).send({
|
||||
success: false,
|
||||
message: message
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get("/queue", async (req, reply) => {
|
||||
try {
|
||||
const site_id = (await db.select({ site_id: sites.id }).from(sites).where(eq(sites.user_id, req.session.user_id)))[0].site_id;
|
||||
if (!site_id) throw new Error("Could not find site_id");
|
||||
const queue = await db.select({
|
||||
id: articlesTable.id,
|
||||
title: articlesTable.title,
|
||||
status: articlesTable.status,
|
||||
created_at: articlesTable.created_at,
|
||||
source_id: articlesTable.source_video_id
|
||||
}).from(articlesTable)
|
||||
.where(and(eq(articlesTable.site_id, site_id), notInArray(articles.status, ["done", "error"])))
|
||||
.orderBy(desc(articlesTable.created_at));
|
||||
|
||||
reply.send({
|
||||
success: true,
|
||||
queue
|
||||
});
|
||||
} catch (err) {
|
||||
reply.status(500).send({
|
||||
success: false,
|
||||
message: err.message
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
fastify.post("/recreate", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["video_id"],
|
||||
properties: {
|
||||
video_id: {
|
||||
type: "string",
|
||||
},
|
||||
length: {
|
||||
type: "number",
|
||||
},
|
||||
format: {
|
||||
type: "string"
|
||||
},
|
||||
faq: {
|
||||
type: "boolean"
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}, async (req, reply) => {
|
||||
|
||||
});
|
||||
|
||||
fastify.put("/website", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: {
|
||||
type: "string"
|
||||
},
|
||||
name: {
|
||||
type: "string"
|
||||
},
|
||||
primary_color_hex: {
|
||||
type: "string",
|
||||
maxLength: 6,
|
||||
minLength: 6
|
||||
},
|
||||
secondary_color_hex: {
|
||||
type: "string",
|
||||
maxLength: 6,
|
||||
minLength: 6
|
||||
},
|
||||
text_color_hex: {
|
||||
type: "string",
|
||||
maxLength: 6,
|
||||
minLength: 6
|
||||
},
|
||||
use_freebie: {
|
||||
type: "boolean"
|
||||
},
|
||||
freebie_title: {
|
||||
type: ["string", "null"]
|
||||
},
|
||||
freebie_url: {
|
||||
type: ["string", "null"],
|
||||
format: "uri"
|
||||
},
|
||||
freebie_image_url: {
|
||||
type: ["string", "null"],
|
||||
format: "uri"
|
||||
},
|
||||
freebie_text: {
|
||||
type: ["string", "null"]
|
||||
},
|
||||
title: {
|
||||
type: "string",
|
||||
},
|
||||
subtitle: {
|
||||
type: "string",
|
||||
},
|
||||
domain: {
|
||||
type: ["string", "null"]
|
||||
},
|
||||
auto_publish: {
|
||||
type: "boolean"
|
||||
},
|
||||
use_contact_page: {
|
||||
type: "boolean"
|
||||
},
|
||||
contact_email: {
|
||||
type: ["string", "null"],
|
||||
format: "email"
|
||||
}
|
||||
},
|
||||
required: ["id"]
|
||||
}
|
||||
},
|
||||
preValidation: authMiddlewareFn
|
||||
}, async (req, reply) => {
|
||||
try {
|
||||
const [site] = await db.select().from(sites).where(eq(sites.id, req.body.id));
|
||||
|
||||
if (site.user_id !== req.session.user_id) {
|
||||
reply.status(403).send({
|
||||
success: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (env.CERTS_URL && site.domain !== req.body.domain) {
|
||||
await fetch(`http://${env.CERTS_URL}/provision`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
domain: req.body.domain
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// if (site.auto_publish !== req.body.auto_publish) {
|
||||
// const [user] = await db.select().from(users).where(eq(users.id, req.session.user_id));
|
||||
// if (!user) throw new Error("Problem getting user");
|
||||
// let form = new FormData();
|
||||
// form.set("hub.callback", env.PUBLIC_API_URL + "/webhooks/youtube");
|
||||
// form.set("hub.topic", "https://www.youtube.com/xml/feeds/videos.xml?channel_id=" + user.channel_id);
|
||||
// form.set("hub.verify", "async");
|
||||
// form.set("hub.mode", req.body.auto_publish ? "subscribe" : "unsubscribe");
|
||||
// form.set("hub.verify_token", websubVerifyToken);
|
||||
// await fetch("https://pubsubhubbub.appspot.com/subscribe", {
|
||||
// method: "POST",
|
||||
// body: form
|
||||
// });
|
||||
// }
|
||||
|
||||
const data = structuredClone(req.body);
|
||||
|
||||
delete data.id;
|
||||
await db.update(sites).set(data).where(eq(sites.id, req.body.id));
|
||||
|
||||
return {
|
||||
success: true
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
||||
|
@ -1,7 +1 @@
|
||||
export * from "./auth.js";
|
||||
export * from "./blog.js"
|
||||
export * from "./channels.js";
|
||||
export * from "./dashboard.js"
|
||||
export * from "./me.js";
|
||||
export * from "./videos.js";
|
||||
export * from "./webhook.js";
|
||||
export * from "./test.js";
|
||||
|
@ -1,87 +0,0 @@
|
||||
/** @typedef {import("fastify").FastifyInstance} FastifyInstance */
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { users } from "../db/schemas.js";
|
||||
import { authMiddleware } from "../modules/middleware.js";
|
||||
import { createCheckout, getBillingDashboard } from "../utils/stripe.js";
|
||||
import { env } from "../utils/env.js";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const meRoutes = (fastify, _, done) => {
|
||||
fastify.register(authMiddleware);
|
||||
|
||||
fastify.get("/", async (request, response) => {
|
||||
try {
|
||||
const user = await db.select().from(users).where(eq(users.id, request.session.user_id));
|
||||
|
||||
if (typeof user == typeof Error) {
|
||||
response.status(400).send({
|
||||
success: false,
|
||||
message: "User not found"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
response.send({
|
||||
success: true,
|
||||
user: user[0],
|
||||
is_subscribed: new Date(user[0].subscribed_until) > new Date(),
|
||||
});
|
||||
} catch (e) {
|
||||
response.status(400).send({
|
||||
success: false,
|
||||
message: "User not found",
|
||||
log: e.message
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get("/billing", async (request, response) => {
|
||||
try {
|
||||
const [user] = await db.select().from(users).where(eq(users.id, request.session.user_id));
|
||||
const billing_session_url = await getBillingDashboard(user.stripe_id, env.FRONTEND_URL);
|
||||
|
||||
response.redirect(billing_session_url);
|
||||
return;
|
||||
} catch (e) {
|
||||
response.status(400).send({
|
||||
success: false,
|
||||
message: "User not found",
|
||||
log: e.message
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get("/subscribe", async (req, reply) => {
|
||||
try {
|
||||
const [user] = await db.select().from(users).where(eq(users.id, req.session.user_id));
|
||||
if (!user) throw new Error("user not found");
|
||||
if(new Date(user.subscribed_until) > new Date()) return reply.redirect(303, "/me/billing");
|
||||
console.log(new Date(user.subscribed_until).getTime())
|
||||
const checkout_url = await createCheckout(env.STRIPE_SUBSCRIPTION_PRICE_ID, user.stripe_id, {
|
||||
user_id: user.id
|
||||
}, {
|
||||
...(!user.trial_used ? {trial_end: new Date(Date.now() + 15 * 24 * 60 * 60 * 1000)} : {})
|
||||
});
|
||||
|
||||
reply.redirect(303, checkout_url);
|
||||
} catch (e) {
|
||||
reply.status(400).send({
|
||||
success: false,
|
||||
message: "User not found",
|
||||
log: e.message
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
21
src/routes/test.js
Normal file
21
src/routes/test.js
Normal file
@ -0,0 +1,21 @@
|
||||
/** @typedef {import("fastify").FastifyInstance} FastifyInstance */
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const testRoutes = (fastify, _, done) => {
|
||||
fastify.get("/", async (request, response) => {
|
||||
const visits = Number(await request.redis.get("visits"));
|
||||
|
||||
request.redis.incr("visits");
|
||||
response.send({
|
||||
hello: "world",
|
||||
visits,
|
||||
});
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
@ -1,33 +0,0 @@
|
||||
/** @typedef {import("fastify").FastifyInstance} FastifyInstance */
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { users } from "../db/schemas.js";
|
||||
import { authMiddleware } from "../modules/middleware.js";
|
||||
import { getAccessToken, getVideosFromPlaylist } from "../utils/youtube.js";
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const videoRoutes = (fastify, _, done) => {
|
||||
fastify.register(authMiddleware);
|
||||
|
||||
fastify.get("/", async (request, response) => {
|
||||
try {
|
||||
const token = await getAccessToken(fastify, request);
|
||||
const [user] = await db.select().from(users).where(eq(users.id, request.session.user_id));
|
||||
const videos = await getVideosFromPlaylist(token, user.uploads_playlist_id);
|
||||
|
||||
response.send({
|
||||
success: true,
|
||||
videos
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
@ -1,110 +0,0 @@
|
||||
/** @typedef {import("fastify").FastifyInstance} FastifyInstance */
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { articles, sites, users } from "../db/schemas.js";
|
||||
import { getVideoWithCaptions } from "../utils/youtube.js";
|
||||
import { createBlogFromCaptions } from "../utils/ai.js";
|
||||
import { createArticleSlug } from "../utils/index.js";
|
||||
import { handleWebhook } from "../utils/stripe.js";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
* @param {unknown} _
|
||||
* @param {() => void} done
|
||||
*/
|
||||
export const webhookRoutes = (fastify, _, done) => {
|
||||
|
||||
fastify.post("/stripe", {
|
||||
config: {
|
||||
rawBody: true
|
||||
},
|
||||
handler: async (req, reply) => {
|
||||
try {
|
||||
await handleWebhook(req.rawBody, req.headers["stripe-signature"]);
|
||||
|
||||
reply.status(200).send({});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
reply.status(400).send({
|
||||
success: false,
|
||||
message: "Error validating purchase",
|
||||
log: e.message
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get("/youtube", async (req, reply) => {
|
||||
// Check if the request contains the 'hub.challenge' query parameter
|
||||
if (req.query["hub.challenge"] && req.query["hub.verify_token"] === "FQNI4Suzih" && req.query["hub.topic"].startsWith("https://www.youtube.com/xml/feeds/videos.xml?channel_id=")) {
|
||||
if (req.query["hub.mode" === "unsubscribe"]) return reply.code(200).send();
|
||||
const channel = req.query["hub.topic"].replace("https://www.youtube.com/xml/feeds/videos.xml?channel_id=", "");
|
||||
const [user] = await db.select().from(users).where(eq(users.channel_id, channel));
|
||||
if (!user) return reply.code(400).send("Invalid user");
|
||||
await db.update(sites).set({
|
||||
pubsub_expiry: new Date(new Date().getTime() + (parseInt(req.query["hub.lease_seconds"] || 172800) * 1000))
|
||||
}).where(eq(sites.user_id, user.id));
|
||||
// Respond with the challenge to verify the subscription
|
||||
console.log(req.query)
|
||||
console.log("verifying...", req.query["hub.challenge"]);
|
||||
return reply.send(req.query["hub.challenge"]);
|
||||
} else {
|
||||
// Handle other cases or errors
|
||||
return reply.code(404).send("Not found");
|
||||
}
|
||||
});
|
||||
|
||||
fastify.post("/youtube", async (req, reply) => {
|
||||
const { headers, body } = req;
|
||||
const contentType = headers['content-type'];
|
||||
// Check if the content type is 'application/atom+xml'
|
||||
if (contentType === 'application/atom+xml') {
|
||||
try {
|
||||
// Parse the XML payload
|
||||
console.log(JSON.stringify(body))
|
||||
const feed = body["feed"];
|
||||
// Example processing: log the video IDs of new videos
|
||||
const entry = feed.entry[0];
|
||||
if (!entry) return reply.code(200).send();
|
||||
const [{ users: user, sites: site }] = await db.select().from(users).leftJoin(sites, eq(users.id, sites.user_id)).where(eq(users.channel_id, entry["yt:channelId"][0]));
|
||||
if (!user || !site) throw new Error("User not found");
|
||||
|
||||
if (user.tokens < 3) throw new Error("Not enough tokens");
|
||||
const videoId = entry["yt:videoId"][0];
|
||||
const videoURL = `https://youtu.be/${videoId}`;
|
||||
reply.code(200).send();
|
||||
|
||||
const video_data = await getVideoWithCaptions(videoURL);
|
||||
const blog_content_json = await createBlogFromCaptions(video_data.captions, { title: video_data.title, description: video_data.description });
|
||||
|
||||
await db.insert(articles).values({
|
||||
site_id: site.id,
|
||||
title: blog_content_json.title,
|
||||
content: blog_content_json.content,
|
||||
meta_title: blog_content_json.meta_title,
|
||||
meta_desc: blog_content_json.meta_desc,
|
||||
excerp: blog_content_json.excerp,
|
||||
source_video_id: videoId,
|
||||
seo_slug: createArticleSlug(blog_content_json.title),
|
||||
is_public: false
|
||||
}).returning({ id: articles.id });
|
||||
|
||||
await db.update(users).set({
|
||||
tokens: user.tokens - 3
|
||||
}).where(eq(users.id, user.id));
|
||||
// Respond with a success status
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
return reply.code(500).send(e);
|
||||
}
|
||||
} else {
|
||||
// Respond with an error status if the content type is not expected
|
||||
return reply.code(400).send("Bad Request");
|
||||
}
|
||||
})
|
||||
|
||||
done();
|
||||
};
|
218
src/utils/ai.js
218
src/utils/ai.js
@ -1,218 +0,0 @@
|
||||
const defaultModel = '@hf/mistralai/mistral-7b-instruct-v0.2';
|
||||
import OpenAI, { toFile } from "openai";
|
||||
import { env } from "./env.js";
|
||||
import ytdl from "@distube/ytdl-core";
|
||||
import { PassThrough } from "stream";
|
||||
|
||||
const openai = new OpenAI({
|
||||
apiKey: env.OPENAI_TOKEN
|
||||
});
|
||||
|
||||
async function cf_prompt(prompt, model = defaultModel) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: { Authorization: 'Bearer oJh-qUnkPmsaaE7mfor617dasBMnH_t9QFkSc5L2' },
|
||||
body: '{ "messages": [{ "role": "system", "content": "You are a friendly assistant" }, { "role": "user", "content": "Why is pizza so good" }]}'
|
||||
};
|
||||
|
||||
const res = await fetch('https://api.cloudflare.com/client/v4/accounts/f79c2f6c3ee16c813cbc853bc7e16166/ai/run/@hf/mistralai/mistral-7b-instruct-v0.2', options)
|
||||
.then(response => response.json())
|
||||
.catch(err => console.error(err));
|
||||
|
||||
|
||||
console.log(res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("openai/resources/index.mjs").ChatCompletionMessageParam[]} prompt
|
||||
* @param {{model: string, is_json: boolean}} opts
|
||||
* @returns
|
||||
*/
|
||||
async function promptGPT(prompt, { model, is_json } = { model: "gpt-3.5-turbo", is_json: true }) {
|
||||
// return JSON.stringify({ "title": "Tech News Update: TikTok Ban, Snapdragon X Series CPUs, Tesla Troubles, and More", "body": "I was thinking about starting this video by singing the song Tik Tok by Kesha but I don't think anyone waking up in the morning feeling like P Diddy is a good vibe right now. The United States has officially passed a law banning TikTok next year if certain conditions aren't met. This ban is part of a larger foreign aid package in support of Ukraine and Israel. TikTok has vowed to fight the law in court, calling it an unconstitutional suppression of its American users' freedom of speech. In other tech news, Qualcomm has unveiled its upcoming lineup of Snapdragon X Series CPUs, including some confusing names. Tesla is facing troubles with its Cybertruck not being waterproof. And Google has delayed its plan to phase out third-party tracking cookies yet again. Stay tuned for more tech updates on TechLink!" });
|
||||
openai.chat.completions.create({
|
||||
model: model,
|
||||
messages: prompt,
|
||||
|
||||
})
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Bearer ${env.OPENAI_TOKEN}`, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
"model": "gpt-3.5-turbo",
|
||||
// "max_tokens": 4096,
|
||||
...(is_json ? { "response_format": { "type": "json_object" } } : {}),
|
||||
"messages": prompt
|
||||
})
|
||||
};
|
||||
|
||||
console.log("prompting gpt-3.5-turbo...")
|
||||
const res = await fetch('https://api.openai.com/v1/chat/completions', options)
|
||||
.then(response => {
|
||||
return response.json();
|
||||
})
|
||||
.catch(err => console.log(err));
|
||||
|
||||
console.log(res);
|
||||
|
||||
return res.choices[0].message.content;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} captions
|
||||
* @param {{length: number, language: string, format: "summary"|"listicle"|"product review"|"tutorial", tone: "professional"|"informal"|"informational"}} param1
|
||||
*
|
||||
* @returns {Promise<{title: string, body: string, seo_friendly_slug: string}>}
|
||||
*/
|
||||
export async function createBlogFromCaptions(captions, {
|
||||
title,
|
||||
description
|
||||
}, options = {}) {
|
||||
const {
|
||||
length,
|
||||
language,
|
||||
format,
|
||||
tone,
|
||||
faq
|
||||
} = Object.assign({ length: 700, language: "English", format: "summary", tone: "informal", faq: false }, options);
|
||||
// const prompt = `Convert the following video transcript into a blog post. The approximate length should be around ${length || 500} characters, written in ${language || "English"}. The desired format of the blog post is a ${format || "summary"}. Please ensure the blog post has a ${tone || "informal"} tone throughout. Use markdown to format the article. You must always respond in the following json fromat: {"title": string, "content": string, "seo_friendly_slug": string}. \nHere is the transcript: `
|
||||
// const prompt = `Convert the following video transcript into an engaging blog post. You must always respond in the following json fromat: {"title": string, "body": string, "seo_friendly_slug": string}. Do not, under any circumstance, include the title inside the body, it should only be reserved for the body of the article. Use markdown to format the article. Use "\\n" to add line-breaks. \nHere is the transcript: `;
|
||||
|
||||
const basePrompt = [{
|
||||
role: "system",
|
||||
content: `# Role: SEO Content Specialist
|
||||
## Profile:
|
||||
- Author: Youpage.ai
|
||||
- Version: 1.0
|
||||
- Language: English
|
||||
- Description: An SEO Content Specialist is an expert in creating high-quality, factually correct, and search engine optimized content. This role involves transforming transcripts, drafts, or raw content into polished articles that rank well on search engines and engage readers.
|
||||
### Skill:
|
||||
1. Expertise in SEO best practices.
|
||||
2. Knowledge of Markdown formatting and how to use it to improve readability.
|
||||
3. Proficiency in content writing and editing.
|
||||
4. Strong understanding of keyword research and usage.
|
||||
5. Ability to maintain factual accuracy.
|
||||
6. Knowledge of news article formatting and structure.
|
||||
## Goals:
|
||||
1. Create a high-quality news article from the provided transcript.
|
||||
2. Ensure the article is SEO optimized.
|
||||
3. Maintain factual accuracy throughout the article.
|
||||
4. Enhance readability and engagement.
|
||||
5. Use relevant keywords effectively.
|
||||
## Constraints VERY IMPORTANT:
|
||||
1. Do not alter the factual content from the transcript.
|
||||
2. Follow SEO best practices.
|
||||
3. Ensure the article is engaging and readable.
|
||||
4. Adhere to news article formatting.
|
||||
5. Limit the use of adjectives. Try to use precise nouns and verbs instead.
|
||||
6. Use unique descriptions and avoid repeating the same phrases.
|
||||
7. Vary the vocabulary to avoid repetition.
|
||||
8. Keep sentences concise to maintain pace and tension.
|
||||
9. Ensure a consistent perspective and unique character voice.
|
||||
10. Do NOT use this sentence structure: [[Subject] [Predicate] [Object] [Appositive] [Prepositional Phrase] [Relative Clause]]
|
||||
11. Do NOT use these phrases: delve, Cosmic, cosmos, heady, void, stars, testament, hum, palpable, symphony, tapestry, woven, complemented, grim, I can't deny, reminder, stark, contrast, storm, tempest, a far cry, an echo, navigate, sheepish.
|
||||
## OutputFormat:
|
||||
1. Do not include a title at the top of the article.
|
||||
2. VERY IMPORTANT! Use markdown to add formatting to the article and make it easier to read.
|
||||
3. Length: The article should be roughly ${length || 1200} words.
|
||||
${faq ? "4. FAQ Section: Add a FAQ section at the end of the article to address common questions." : ""}
|
||||
## Workflow:
|
||||
1. First, analyze the provided transcript to understand the key points and factual content.
|
||||
2. Then, conduct keyword research to identify relevant and high-ranking keywords for the article.
|
||||
3. Next, draft a compelling headline and introduction that include the main keyword.
|
||||
4. After that, write the body of the article, ensuring it is factually correct, well-structured, and around {{word_count}} words in length.
|
||||
5. Conclude the article with a strong closing and ensure all SEO elements are in place, including meta description and alt text for any images.
|
||||
${faq ? "6. Finally, add an FAQ section at the end of the article to address common questions related to the topic." : ""}
|
||||
## Initialization:
|
||||
As an SEO Content Specialist, you must follow the specified rules and communicate in English. Respond only with the article content.`
|
||||
}, {
|
||||
role: "user",
|
||||
content: `# Information:
|
||||
## Title
|
||||
${title}
|
||||
## Transcript
|
||||
${captions}`
|
||||
}];
|
||||
|
||||
let response = await openai.chat.completions.create({
|
||||
model: "gpt-4o",
|
||||
messages: basePrompt
|
||||
});
|
||||
|
||||
console.log("first response", response.choices[0].message.content)
|
||||
|
||||
let final = await openai.chat.completions.create({
|
||||
model: "gpt-3.5-turbo",
|
||||
messages: [...basePrompt, { "role": "assistant", "content": response.choices[0].message.content }, { "role": "user", "content": "Respond only in JSON with the following format: { meta_title: string, meta_desc: string, slug: string, excerp: string, title: string }" }],
|
||||
response_format: { type: "json_object" }
|
||||
})
|
||||
|
||||
console.log("second response", final.choices[0].message.content)
|
||||
|
||||
let result = Object.assign(JSON.parse(final.choices[0].message.content), {
|
||||
content: response.choices[0].message.content,
|
||||
})
|
||||
return result;
|
||||
}
|
||||
|
||||
function wordsToTokens(n) {
|
||||
return Math.ceil(n / 0.75);
|
||||
}
|
||||
|
||||
export async function getWhisperCaptions(video_url) {
|
||||
const audio = await getYouTubeAudioBuffer(video_url);
|
||||
|
||||
const file = await toFile(audio, "audio.mp3");
|
||||
const res = await openai.audio.transcriptions.create({
|
||||
file: file,
|
||||
model: "whisper-1",
|
||||
}).catch(x => console.log(x));
|
||||
|
||||
return res.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the audio data from a YouTube video URL and returns it as a buffer.
|
||||
* @param {string} videoUrl - The YouTube video URL.
|
||||
* @returns {Promise<Buffer>} A promise that resolves with the audio data as a buffer.
|
||||
*/
|
||||
function getYouTubeAudioBuffer(videoUrl) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!videoUrl) reject();
|
||||
// Download audio from YouTube
|
||||
const audioStream = ytdl(videoUrl, { filter: "audioonly", quality: "lowestaudio" });
|
||||
|
||||
// Create a PassThrough stream to hold the audio data in memory
|
||||
const passThrough = new PassThrough();
|
||||
|
||||
// Pipe the audio stream to the PassThrough stream
|
||||
audioStream.pipe(passThrough);
|
||||
|
||||
// Collect the audio data into a buffer
|
||||
let audioDataBuffer = [];
|
||||
|
||||
// Listen for data events on the PassThrough stream
|
||||
passThrough.on('data', chunk => {
|
||||
audioDataBuffer.push(chunk);
|
||||
});
|
||||
|
||||
// Listen for end event to indicate the stream has finished
|
||||
passThrough.on('end', () => {
|
||||
// Convert the collected chunks into a single Buffer
|
||||
const audioBufferData = Buffer.concat(audioDataBuffer);
|
||||
|
||||
// Resolve the promise with the audio data buffer
|
||||
resolve(audioBufferData);
|
||||
});
|
||||
|
||||
// Listen for error event on the PassThrough stream
|
||||
passThrough.on('error', err => {
|
||||
// Reject the promise if an error occurs
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { sites } from "../db/schemas.js";
|
||||
import nodemailer from 'nodemailer';
|
||||
|
||||
const TOKEN = "a0cc97f4f856d6c16d70bb5984e32cef";
|
||||
const ENDPOINT = "https://send.api.mailtrap.io/";
|
||||
|
||||
const default_sender = "mailtrap@demomailtrap.com";
|
||||
|
||||
var client = nodemailer.createTransport({
|
||||
host: "live.smtp.mailtrap.io",
|
||||
port: 587,
|
||||
auth: {
|
||||
user: "api",
|
||||
pass: "a0cc97f4f856d6c16d70bb5984e32cef"
|
||||
}
|
||||
});
|
||||
|
||||
export async function sendContactEmail(recipient, sender, subject, body) {
|
||||
client.sendMail({
|
||||
from: default_sender,
|
||||
to: recipient,
|
||||
subject: `YouPage.ai: ${subject}`,
|
||||
text: `You got a new message from your Youpage.ai blog!\nSender: ${sender}\nMessage: ${body}`
|
||||
}).catch(console.error);
|
||||
}
|
||||
|
||||
export async function sendFreebie(recipient, blog_id) {
|
||||
const [blog] = await db.select().from(sites).where(eq(sites.id, blog_id));
|
||||
if (!blog) throw new Error("Invalid site");
|
||||
|
||||
if (!blog.use_freebie || !blog.freebie_url) return;
|
||||
|
||||
const sender = default_sender;
|
||||
|
||||
const recipients = [
|
||||
{
|
||||
email: recipient,
|
||||
}
|
||||
];
|
||||
|
||||
client
|
||||
.sendMail({
|
||||
from: sender,
|
||||
to: recipients,
|
||||
subject: `Your freebie from ${blog.name}`,
|
||||
text: `Thank you for subscribing to ${blog.name}! Your freebie is linked below.\n ${blog.freebie_url}`,
|
||||
}).catch(console.error);
|
||||
}
|
@ -6,16 +6,6 @@ const envSchema = z.object({
|
||||
REDIS_URL: z.string().default("redis://127.0.0.1:6379/"),
|
||||
PORT: z.coerce.number().default(8080),
|
||||
HOST: z.string().default("127.0.0.1"),
|
||||
PUBLIC_API_URL: z.string(),
|
||||
FRONTEND_URL: z.string(),
|
||||
SITES_HOST: z.string(),
|
||||
GOOGLE_CLIENT_ID: z.string(),
|
||||
GOOGLE_SECRET: z.string(),
|
||||
OPENAI_TOKEN: z.string(),
|
||||
CERTS_URL: z.string().nullable().default(null),
|
||||
STRIPE_KEY: z.string(),
|
||||
STRIPE_WEBHOOK_SECRET: z.string(),
|
||||
STRIPE_SUBSCRIPTION_PRICE_ID: z.string(),
|
||||
});
|
||||
|
||||
export const env = envSchema.parse(process.env);
|
||||
|
@ -1,75 +1,3 @@
|
||||
export * from "./env.js";
|
||||
export * from "./logger.js";
|
||||
export * from "./redis.js";
|
||||
export * from "./ai.js";
|
||||
export * from "./token.js";
|
||||
export * from "./youtube.js";
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} title
|
||||
* @returns {string}
|
||||
*/
|
||||
export function createArticleSlug(title) {
|
||||
const maxLength = 20;
|
||||
const slug = title.toLowerCase().replace(/[^a-z0-9\s-]/g, '').trim().replace(/\s+/g, '-');
|
||||
const randomChars = "-" + generateRandomChars(6);
|
||||
|
||||
// If slug is shorter than or equal to 12 characters, return it directly
|
||||
if (slug.length <= maxLength) {
|
||||
return slug + randomChars;
|
||||
}
|
||||
|
||||
// Find the last space within the first 12 characters
|
||||
const lastSpaceIndex = slug.substring(0, maxLength).lastIndexOf('-');
|
||||
|
||||
// If no space found, truncate slug to 12 characters
|
||||
const truncatedSlug = lastSpaceIndex !== -1 ? slug.substring(0, lastSpaceIndex) : slug.substring(0, maxLength);
|
||||
|
||||
// Generate 6 random characters
|
||||
|
||||
// Concatenate the truncated slug and random characters
|
||||
const finalSlug = truncatedSlug + randomChars;
|
||||
|
||||
return finalSlug;
|
||||
}
|
||||
|
||||
function generateRandomChars(length) {
|
||||
let result = '';
|
||||
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a JSON object to a valid CSV string
|
||||
* @param {JSON[]} jsonData
|
||||
* @returns {string} CSV Data
|
||||
*/
|
||||
export function jsonToCsv(jsonData) {
|
||||
// Extract headers from the first object in the JSON array
|
||||
const headers = Object.keys(jsonData[0]);
|
||||
|
||||
// Join headers to form the first line of CSV
|
||||
let csv = headers.map(header => `"${header}"`).join(',') + '\n';
|
||||
|
||||
// Loop through each object in the JSON array
|
||||
for (let obj of jsonData) {
|
||||
// Extract values corresponding to each header
|
||||
const values = headers.map(header => {
|
||||
let value = obj[header];
|
||||
// Check if the value contains a comma, if so, wrap it in double quotes
|
||||
if (typeof value === 'string' && value.includes(',')) {
|
||||
value = `"${value}"`;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
// Join values with comma separator
|
||||
csv += values.join(',') + '\n';
|
||||
}
|
||||
|
||||
return csv;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import * as Sentry from "@sentry/node";
|
||||
|
||||
// Ensure to call this before importing any other modules!
|
||||
Sentry.init({
|
||||
dsn: "https://0092593709894b0eaec1702e0136594b@glitchtip.omersabic.com/4",
|
||||
});
|
@ -1,107 +0,0 @@
|
||||
import loadStripe from 'stripe';
|
||||
import { env } from './env.js';
|
||||
import { db } from '../db/index.js';
|
||||
import { users } from '../db/schemas.js';
|
||||
import { eq, sql } from 'drizzle-orm';
|
||||
|
||||
const stripe = await loadStripe(env.STRIPE_KEY);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} email
|
||||
* @param {string} name
|
||||
* @returns {import('stripe-v3').customer.create}
|
||||
*/
|
||||
export async function createCustomer(email, name) {
|
||||
return (await stripe.customers.create({
|
||||
email: email,
|
||||
name: name,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} stripe_id
|
||||
*/
|
||||
export async function getBillingDashboard(stripe_id, return_url) {
|
||||
const session = await stripe.billingPortal.sessions.create({
|
||||
customer: stripe_id,
|
||||
return_url
|
||||
});
|
||||
|
||||
return session.url;
|
||||
}
|
||||
|
||||
export async function createCheckout(price_id, customer_id, metadata = {}, subscription_data = {}) {
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
mode: 'subscription',
|
||||
customer: customer_id,
|
||||
line_items: [
|
||||
{
|
||||
price: price_id,
|
||||
quantity: 1
|
||||
},
|
||||
],
|
||||
metadata,
|
||||
subscription_data,
|
||||
success_url: env.FRONTEND_URL + '/payments/success?session_id={CHECKOUT_SESSION_ID}',
|
||||
cancel_url: env.FRONTEND_URL,
|
||||
});
|
||||
|
||||
return session.url;
|
||||
}
|
||||
|
||||
export async function handleWebhook(body, signature) {
|
||||
let data;
|
||||
let eventType;
|
||||
// Check if webhook signing is configured.
|
||||
const webhookSecret = env.STRIPE_WEBHOOK_SECRET;
|
||||
if (webhookSecret) {
|
||||
// Retrieve the event by verifying the signature using the raw body and secret.
|
||||
let event;
|
||||
try {
|
||||
event = stripe.webhooks.constructEvent(
|
||||
body,
|
||||
signature,
|
||||
webhookSecret
|
||||
);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
console.log(`⚠️ Webhook signature verification failed.`);
|
||||
throw new Error("Verification failed")
|
||||
}
|
||||
// Extract the object from the event.
|
||||
data = event.data;
|
||||
eventType = event.type;
|
||||
} else {
|
||||
// Webhook signing is recommended, but if the secret is not configured in `config.js`,
|
||||
// retrieve the event data directly from the request body.
|
||||
data = body.data;
|
||||
eventType = body.type;
|
||||
}
|
||||
|
||||
switch (eventType) {
|
||||
case 'invoice.paid':
|
||||
console.log("invoice paid!")
|
||||
const [user] = await db.select().from(users).where(eq(users.stripe_id, data.object.customer));
|
||||
console.log(data);
|
||||
if (!user) throw new Error("Failed to get user ID");
|
||||
let currentDate = new Date();
|
||||
let subscriptionEndDate = new Date(currentDate);
|
||||
if(user.trial_used) {
|
||||
subscriptionEndDate.setMonth(currentDate.getMonth() + 1);
|
||||
} else {
|
||||
subscriptionEndDate.setDate(currentDate.getDate() + 14);
|
||||
}
|
||||
|
||||
await db.update(users).set({
|
||||
subscribed_until: subscriptionEndDate,
|
||||
subscription_tier: "basic",
|
||||
tokens: sql`${users.tokens} + 25`,
|
||||
trial_used: true
|
||||
}).where(eq(users.stripe_id, data.object.customer));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { sessions } from "../db/schemas.js";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} user_id User to assign the auth token to
|
||||
* @param {{access_token: string, refresh_token: string, expires_at: Date}} googleAuth
|
||||
*
|
||||
* @returns {Promise<{session_id: string}>} Auth token
|
||||
*/
|
||||
export async function createSession(user_id, {
|
||||
access_token,
|
||||
refresh_token,
|
||||
expires_at,
|
||||
}, tx = db) {
|
||||
try {
|
||||
const [existing_session] = await tx.select().from(sessions).where(eq(sessions.user_id, user_id));
|
||||
|
||||
if (existing_session) {
|
||||
return {
|
||||
session_id: existing_session.id
|
||||
}
|
||||
}
|
||||
|
||||
const token = await tx.insert(sessions).values({
|
||||
user_id,
|
||||
access_token: access_token,
|
||||
refresh_token: refresh_token,
|
||||
expires_at
|
||||
}).returning({ id: sessions.id });
|
||||
if (token.length == 0) {
|
||||
throw new Error("Error creating auth token");
|
||||
}
|
||||
|
||||
return {
|
||||
session_id: token[0].id
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
@ -1,520 +0,0 @@
|
||||
import { eq } from 'drizzle-orm';
|
||||
import { db } from '../db/index.js';
|
||||
import { sessions } from '../db/schemas.js';
|
||||
import { google } from 'googleapis';
|
||||
import ytdl from "@distube/ytdl-core";
|
||||
import { getWhisperCaptions } from './ai.js';
|
||||
import { articles as articlesTable } from "../db/schemas.js";
|
||||
import * as xml2js from 'xml2js';
|
||||
|
||||
const service = google.youtube("v3");
|
||||
|
||||
const agent = ytdl.createAgent([
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678493,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "__Secure-1PAPISID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "Ydllg_a0ziZ2IRkW/AxTe18r6nUqk7BEbQ",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678415,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "__Secure-1PSID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "g.a000mwiFpDXHv-mE1JbzAv29Ye5X1D7V-zT1tEGx1_bd46Kree9yTMpJEGK4nnajwLM5d0hj7gACgYKAYUSARUSFQHGX2MiVlSE8GgO3Vmj3YT3n8k6WhoVAUF8yKoU4xPY7CM6zb7j98zdaVV70076",
|
||||
"id": 2
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1754861761.153214,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "__Secure-1PSIDCC",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "AKEyXzXzGpG2-NgDLDoR0-TXlyJVUQJQ_hzs2wEvAZmPy5VTxaOIXg4QrrR3N_v5EWUqhQ4q",
|
||||
"id": 3
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1754861754.678387,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "__Secure-1PSIDTS",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "sidts-CjIBUFGohzuXoAbjBYmkalmpToyVGhPcAMyp-r3IgiyU7WlYnluERYQWrB-zOvpwcD5F_RAA",
|
||||
"id": 4
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678506,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "__Secure-3PAPISID",
|
||||
"path": "/",
|
||||
"sameSite": "no_restriction",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "Ydllg_a0ziZ2IRkW/AxTe18r6nUqk7BEbQ",
|
||||
"id": 5
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678427,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "__Secure-3PSID",
|
||||
"path": "/",
|
||||
"sameSite": "no_restriction",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "g.a000mwiFpDXHv-mE1JbzAv29Ye5X1D7V-zT1tEGx1_bd46Kree9y4tCIp7vBEBU5tBLxdPiklQACgYKAVgSARUSFQHGX2MiCFYG1JWlH9dAu8gduZa6dRoVAUF8yKpMaD9-H5JRU8a-L-_Za4wd0076",
|
||||
"id": 6
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1754861761.153238,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "__Secure-3PSIDCC",
|
||||
"path": "/",
|
||||
"sameSite": "no_restriction",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "AKEyXzUy-4CY7B0Gu-XHjrZVVpAWPNJNET5PQOlbRbmaa_ecvp7AS8Nwf5gbDTfL47zj0Dez3Q",
|
||||
"id": 7
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1754861754.678402,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "__Secure-3PSIDTS",
|
||||
"path": "/",
|
||||
"sameSite": "no_restriction",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "sidts-CjIBUFGohzuXoAbjBYmkalmpToyVGhPcAMyp-r3IgiyU7WlYnluERYQWrB-zOvpwcD5F_RAA",
|
||||
"id": 8
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757453723.663338,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "__Secure-YEC",
|
||||
"path": "/",
|
||||
"sameSite": "lax",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "CgtVakdtMnJrZ2VwRSi_ut-1BjIKCgJERRIEEgAgKQ%3D%3D",
|
||||
"id": 9
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678463,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "APISID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "PzwvCMFIwi-WXHNK/Aa7aeSu6UGGiR3Xw-",
|
||||
"id": 10
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1723326359,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "CONSISTENCY",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "AKreu9uoPRzjfNbvjscAvYa4AnZ7yXSd9GkhniF8n1uodA2SI5_UawxviB_l5efAOS7TIHbrzFvCUM3riEdLFWvDQ0So_SGThxdrORfZ0vAZzDn30MIgE0ddEa_h-aBhNzX4ispknt4SY4E76opMTGsu",
|
||||
"id": 11
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678441,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "HSID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "An0F5SiZ_NJH4_Rx4",
|
||||
"id": 12
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885756.324828,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "LOGIN_INFO",
|
||||
"path": "/",
|
||||
"sameSite": "no_restriction",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "AFmmF2swRQIgQD5euCkX56qyeRocOC192DF6siCwmZiG5RFdXIsIOKQCIQDVYMUXa9fafpFC4gJAi32F-LsqO7a5ptBfytQ0ooI-7g:QUQ3MjNmd1RmUlRfd25hTUFDT214TF9pcHlXcEh5ZHAzc2d0Rjc2WjZVUEJCRW1KSV9QRTlBZXpTLXA1QXFtdExyMzFncVdteTE4N1pMWk9yUnhTVU8taF93eEZlRm95UTdubHJ3emt4SVBYeVNjQ0dDREtnb2JWeHhHeU1HYy1xVlhlZTU4V3g3TnEyMm9uWDZzTzlBZHhjSG81dXZ3WnJn",
|
||||
"id": 13
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1739136959.800355,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "NID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "516=aE2sFI_rh_Rh7q0T-GD9vzWm4pf6Uak1iFjvzBFuRr8wxfSmJEDS6NzXpXKLLNKi_ba-NaxkIxkfhKJ9I3ODz9TmFnuTwQVvGbSordWz2DI3IvtXEygFNEGTTW1WuKBOHO-WXjdM2nuQ4b7d3KWiDttthySlnE6l0vur98aENPo",
|
||||
"id": 14
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885758.099494,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "PREF",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "f6=40000000&tz=Europe.Berlin",
|
||||
"id": 15
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678475,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "SAPISID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "Ydllg_a0ziZ2IRkW/AxTe18r6nUqk7BEbQ",
|
||||
"id": 16
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678333,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "SID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "g.a000mwiFpDXHv-mE1JbzAv29Ye5X1D7V-zT1tEGx1_bd46Kree9yaWb-XRQACGvVe52ZscToXgACgYKAc4SARUSFQHGX2MipK_BxY_xGkd82ZuR_-usghoVAUF8yKoD-HK1Ms_BeaLioA-9grr10076",
|
||||
"id": 17
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1754861761.153147,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "SIDCC",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "AKEyXzVET2aVXEooYcLzVZcKqrNU4ugR61hBJSb9_Kg9YQSdRmMSiwZNQZEHDNA0spao7jlE",
|
||||
"id": 18
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757453733.489585,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "SOCS",
|
||||
"path": "/",
|
||||
"sameSite": "lax",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "CAESFggDEgk2NjA1NTYzMjIaBWVuLUdCIAEaBgiA29q1Bg",
|
||||
"id": 19
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1757885754.678452,
|
||||
"hostOnly": false,
|
||||
"httpOnly": true,
|
||||
"name": "SSID",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": true,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "AMLcUMa2BaB8t4bo0",
|
||||
"id": 20
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1723325764,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "ST-hcbf8d",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "session_logininfo=AFmmF2swRQIgQD5euCkX56qyeRocOC192DF6siCwmZiG5RFdXIsIOKQCIQDVYMUXa9fafpFC4gJAi32F-LsqO7a5ptBfytQ0ooI-7g%3AQUQ3MjNmd1RmUlRfd25hTUFDT214TF9pcHlXcEh5ZHAzc2d0Rjc2WjZVUEJCRW1KSV9QRTlBZXpTLXA1QXFtdExyMzFncVdteTE4N1pMWk9yUnhTVU8taF93eEZlRm95UTdubHJ3emt4SVBYeVNjQ0dDREtnb2JWeHhHeU1HYy1xVlhlZTU4V3g3TnEyMm9uWDZzTzlBZHhjSG81dXZ3WnJn",
|
||||
"id": 21
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1723325763,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "ST-l3hjtt",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "session_logininfo=AFmmF2swRQIgQD5euCkX56qyeRocOC192DF6siCwmZiG5RFdXIsIOKQCIQDVYMUXa9fafpFC4gJAi32F-LsqO7a5ptBfytQ0ooI-7g%3AQUQ3MjNmd1RmUlRfd25hTUFDT214TF9pcHlXcEh5ZHAzc2d0Rjc2WjZVUEJCRW1KSV9QRTlBZXpTLXA1QXFtdExyMzFncVdteTE4N1pMWk9yUnhTVU8taF93eEZlRm95UTdubHJ3emt4SVBYeVNjQ0dDREtnb2JWeHhHeU1HYy1xVlhlZTU4V3g3TnEyMm9uWDZzTzlBZHhjSG81dXZ3WnJn",
|
||||
"id": 22
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1723325763,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "ST-tladcw",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "session_logininfo=AFmmF2swRQIgQD5euCkX56qyeRocOC192DF6siCwmZiG5RFdXIsIOKQCIQDVYMUXa9fafpFC4gJAi32F-LsqO7a5ptBfytQ0ooI-7g%3AQUQ3MjNmd1RmUlRfd25hTUFDT214TF9pcHlXcEh5ZHAzc2d0Rjc2WjZVUEJCRW1KSV9QRTlBZXpTLXA1QXFtdExyMzFncVdteTE4N1pMWk9yUnhTVU8taF93eEZlRm95UTdubHJ3emt4SVBYeVNjQ0dDREtnb2JWeHhHeU1HYy1xVlhlZTU4V3g3TnEyMm9uWDZzTzlBZHhjSG81dXZ3WnJn",
|
||||
"id": 23
|
||||
},
|
||||
{
|
||||
"domain": ".youtube.com",
|
||||
"expirationDate": 1723325764,
|
||||
"hostOnly": false,
|
||||
"httpOnly": false,
|
||||
"name": "ST-xuwub9",
|
||||
"path": "/",
|
||||
"sameSite": "unspecified",
|
||||
"secure": false,
|
||||
"session": false,
|
||||
"storeId": "1",
|
||||
"value": "session_logininfo=AFmmF2swRQIgQD5euCkX56qyeRocOC192DF6siCwmZiG5RFdXIsIOKQCIQDVYMUXa9fafpFC4gJAi32F-LsqO7a5ptBfytQ0ooI-7g%3AQUQ3MjNmd1RmUlRfd25hTUFDT214TF9pcHlXcEh5ZHAzc2d0Rjc2WjZVUEJCRW1KSV9QRTlBZXpTLXA1QXFtdExyMzFncVdteTE4N1pMWk9yUnhTVU8taF93eEZlRm95UTdubHJ3emt4SVBYeVNjQ0dDREtnb2JWeHhHeU1HYy1xVlhlZTU4V3g3TnEyMm9uWDZzTzlBZHhjSG81dXZ3WnJn",
|
||||
"id": 24
|
||||
}
|
||||
]);
|
||||
|
||||
export async function getVideoById(access_token, video_id) {
|
||||
const video = await service.videos.list({
|
||||
access_token,
|
||||
id: video_id,
|
||||
part: "snippet"
|
||||
}).then(x => x.data.items[0].snippet);
|
||||
|
||||
return video;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} access_token
|
||||
* @param {string} playlist_id
|
||||
*
|
||||
* @returns {Promise<import("googleapis").youtube_v3.Schema$PlaylistItem[]>}
|
||||
*/
|
||||
export async function getVideosFromPlaylist(access_token, playlist_id) {
|
||||
if (!access_token) return [];
|
||||
let videos;
|
||||
try {
|
||||
videos = await service.playlistItems.list({
|
||||
access_token,
|
||||
part: "id,snippet",
|
||||
playlistId: playlist_id,
|
||||
maxResults: 10
|
||||
}).then(res => res)
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
|
||||
console.log(videos.status);
|
||||
if (videos.status > 299 || videos.status < 200) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return videos.data.items;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} access_token
|
||||
*
|
||||
* @returns {Promise<import("googleapis").youtube_v3.Schema$Channel>}
|
||||
*/
|
||||
export async function getChannelInfo(access_token) {
|
||||
const channel = await service.channels.list({
|
||||
access_token,
|
||||
part: "id,contentDetails,snippet",
|
||||
mine: true,
|
||||
maxResults: 1
|
||||
}).then(res => res);
|
||||
|
||||
if (!channel.data.items[0]) {
|
||||
throw new Error("no_channel");
|
||||
}
|
||||
return channel.data.items[0];
|
||||
}
|
||||
|
||||
|
||||
/** @typedef {{name: string, email: string, isVerified: boolean}} UserInfo */
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} access_token
|
||||
*
|
||||
* @returns {Promise<UserInfo>}
|
||||
*/
|
||||
export async function getUserInfo(access_token) {
|
||||
const url = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
|
||||
// const url = "https://people.googleapis.com/v1/people/me?personFields=names,emailAddresses";
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
"Authorization": `Bearer ${access_token}`
|
||||
}
|
||||
})
|
||||
const data = await response.json();
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('fastify').FastifyInstance} fastify
|
||||
* @param {import('fastify').FastifyRequest} request
|
||||
*
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
export async function getAccessToken(fastify, request) {
|
||||
// TODO: Move to cache instead of postgres
|
||||
// const [cachedToken] = await db.select().from(sessions).where(eq(sessions.id, request.session.id));
|
||||
let access_token = request.session.access_token;
|
||||
|
||||
if ((new Date().getTime() + 10) > request.session.expires_at) {
|
||||
/** @type {import('@fastify/oauth2').Token} */
|
||||
const { token } = await fastify.googleOAuth2.getNewAccessTokenUsingRefreshToken(request.session).catch(e => ({ token: null }));
|
||||
|
||||
if (!token) return ""
|
||||
|
||||
access_token = token.access_token;
|
||||
|
||||
await db.update(sessions).set({
|
||||
expires_at: token.expires_at,
|
||||
access_token: token.access_token
|
||||
}).where(eq(sessions.user_id, request.session.user_id));
|
||||
}
|
||||
|
||||
|
||||
return access_token;
|
||||
}
|
||||
|
||||
export async function getVideoDetails(video_url) {
|
||||
if (!(ytdl.validateURL(video_url))) throw new Error("Invalid Youtube URL");
|
||||
const info = await ytdl.getBasicInfo(video_url, {agent});
|
||||
return {
|
||||
title: info.videoDetails.title,
|
||||
description: info.videoDetails.description
|
||||
}
|
||||
}
|
||||
|
||||
export function parseTextFromCaptions(caption_text) {
|
||||
let text_content = "";
|
||||
const captionEntries = caption_text.split(/\n\n/);
|
||||
for (const entry of captionEntries) {
|
||||
const lines = entry.trim().split('\n');
|
||||
if (lines.length >= 2 && !lines[1].includes('-->')) {
|
||||
text_content += lines.slice(1).join(' ').trim() + ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return text_content
|
||||
}
|
||||
|
||||
function parseXMLCaptions(xmlString) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const parser = new xml2js.Parser();
|
||||
|
||||
parser.parseString(xmlString, (err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const textElements = result.transcript.text;
|
||||
let captionText = textElements.map(element => element._).join('\n');
|
||||
resolve(captionText.trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delay(time) {
|
||||
return new Promise(resolve => setTimeout(resolve, time));
|
||||
}
|
||||
|
||||
export async function getVideoWithCaptions(video_url) {
|
||||
const info = await ytdl.getInfo(video_url, {agent});
|
||||
const tracks = info
|
||||
.player_response.captions
|
||||
.playerCaptionsTracklistRenderer.captionTracks;
|
||||
|
||||
if (!tracks || tracks.length < 1) throw new Error("no_captions");
|
||||
const track = tracks.find(t => t.languageCode == "en");
|
||||
if(!track) throw new Error("no_captions");
|
||||
const captions = await (await fetch(`${track.baseUrl}&fmt=srv1`)).text();
|
||||
return {
|
||||
title: info.videoDetails.title,
|
||||
description: info.videoDetails.description,
|
||||
captions: await parseXMLCaptions(captions)
|
||||
}
|
||||
}
|
||||
|
324
test.md
324
test.md
@ -1,324 +0,0 @@
|
||||
last week AMD launched their new
|
||||
graphics cards and I already reviewed
|
||||
the RX 7900 XTX so today I'm going to
|
||||
talk about this RX 7900 XT now I did not
|
||||
have a chance to test the reference card
|
||||
but I do have this tough gaming model
|
||||
from Asus and while I do think that AMD
|
||||
has done a great job at creating
|
||||
high-end graphics cards and bringing
|
||||
some well needed competition to the
|
||||
market I also think that there are
|
||||
plenty of things that still need a bit
|
||||
of work and that should be improved so
|
||||
I'm going to take a bit of a different
|
||||
approach today and I'm going to talk
|
||||
about my issues with this 7900 XT let's
|
||||
go this video is brought to you by
|
||||
Corsair and their brand new Dominator
|
||||
Platinum RGB memory these super fast
|
||||
ddr5 6000 Hertz memory kits are
|
||||
specifically made for ryzen 7000 series
|
||||
CPUs they feature a stylish aluminum
|
||||
heat spreader with dhx technology that
|
||||
keeps them nice and cool under load
|
||||
offering a smooth and stable performance
|
||||
with a lot out of room for overclocking
|
||||
and they come with 12 customizable
|
||||
kapelix LEDs that you can control with
|
||||
their IQ software and easily sync up
|
||||
with your other coarser components check
|
||||
them out using the links in the
|
||||
description below one of the first and
|
||||
most obvious issues I had with this card
|
||||
is its name the RX 7900 XT sounds very
|
||||
similar to the 7900 XTX even though when
|
||||
we look at the specs you can see that
|
||||
they are vastly different the XCX has
|
||||
more cores higher clock speeds more
|
||||
memory and a bigger memory bus than the
|
||||
XT and I don't think that removing One X
|
||||
at the end of the product name is enough
|
||||
to distinguish and obviously lower tier
|
||||
card from a higher tier one it just
|
||||
causes a lot of confusion especially for
|
||||
the less informed consumers that might
|
||||
think that they are buying a very
|
||||
similar product for a hundred dollars
|
||||
less which is definitely not the case
|
||||
here now Nvidia received a lot of
|
||||
criticism for their 4086 16 gig and 4080
|
||||
12 gig cards and AMD here is pretty much
|
||||
doing the same thing the XT is more than
|
||||
15 slower than the xdx and they should
|
||||
have called it a 7800 XT or at least a
|
||||
7900 without any X's just to make it a
|
||||
bit more obvious to everyone and that
|
||||
brings me to my next issue the relative
|
||||
performance because the XT is priced so
|
||||
closely to the XTX its performance
|
||||
should also be at a close distance
|
||||
compared to the xdx and that is
|
||||
definitely not the case here so the xt's
|
||||
recommended price is only 10 lower than
|
||||
the xdx but when it comes to Performance
|
||||
the XTX is 16 faster than the XD and
|
||||
keep in mind I was using the relatively
|
||||
fast third-party version of the XT so
|
||||
for 100 more you can get a card that is
|
||||
16 faster and if you already decided to
|
||||
spend 900 on a GPU upgrading to dxdx for
|
||||
a hundred dollars more just seems like a
|
||||
logical choice and that pressure from
|
||||
the relative performance is a bit of a
|
||||
shame because in absolute terms the XT
|
||||
is a pretty powerful chip at 1440p
|
||||
resolution it shows a great High refresh
|
||||
rate experience in every game I've
|
||||
tested and most games will easily run at
|
||||
144 FPS or above but even the heaviest
|
||||
titles like Dying Light 2 and cyberpunk
|
||||
2077 for example will get pretty close
|
||||
to that at 4K resolution the XC does
|
||||
well offering that 4K 120 experience in
|
||||
lighter titles and 60-ish FPS or above
|
||||
in heavier games amd's FSR has also been
|
||||
adopted by a lot of game developers so
|
||||
for the titles that do support it this
|
||||
7900 XT is actually a very capable 4K
|
||||
gaming card as well but should you buy a
|
||||
much stronger XTX for 100 more
|
||||
absolutely now the next issue I had was
|
||||
performance inconsistency when testing
|
||||
Call of Duty Modern Warfare we were
|
||||
getting really inconsistent results so
|
||||
one moment the XT would be running at
|
||||
around 2400 megahertz showing FPS
|
||||
numbers that kind of fall in line with
|
||||
other cards but during some other runs
|
||||
it would suddenly boost much higher
|
||||
somewhere closer to 2 900 megahertz
|
||||
which would result in a much higher
|
||||
average FPS and which would put it above
|
||||
the RTX 4090 and the 7900 XDS and there
|
||||
was absolutely no logic behind it so it
|
||||
was the same system same settings no
|
||||
updates in between the CPU wasn't
|
||||
throttling or anything else that we can
|
||||
think of actually so every time we
|
||||
reboot the PC it would act differently
|
||||
for no clear reason now in this
|
||||
particular game it doesn't really matter
|
||||
as much because in the worst case
|
||||
scenario it was close to an RTX 4090 and
|
||||
in the best case scenario it was
|
||||
actually beating it which is definitely
|
||||
not bad for a GPU that costs half as
|
||||
much but seeing this inconsistent
|
||||
Behavior always causes doubt whether
|
||||
everything is working well as it should
|
||||
and what kind of an impact does it have
|
||||
in titles where this card was not doing
|
||||
as well but AMD has been on top of this
|
||||
since I mentioned it and they are trying
|
||||
to figure it out but there are no clear
|
||||
answers just yet now hopefully they will
|
||||
come up with a driver update that will
|
||||
stabilize this situation a bit more now
|
||||
my next issue is a really noticeable one
|
||||
coil line in my review of the XTX I
|
||||
mentioned that my reference card had
|
||||
some coil line now coil wine is mostly
|
||||
sample specific and then it is often
|
||||
specific to certain games or super high
|
||||
FPS gameplay but the XT here had a
|
||||
noticeable amount of coal wine regularly
|
||||
and since the launch a lot of reviewers
|
||||
as well as people who bought their cards
|
||||
frequently mentioned coil wine too both
|
||||
in reference cards as well as third
|
||||
party cards so this tough gaming from
|
||||
Asus doesn't always whine but it does
|
||||
sit pretty frequently and since the
|
||||
sound often changes depending on what's
|
||||
going on with your PC it is way more
|
||||
noticeable than if it was just a
|
||||
consistent tone I did manage to test the
|
||||
thermal and noise performance at one
|
||||
point where it wasn't whining and this
|
||||
oversized tough cooler performed
|
||||
extremely well barely going over 50
|
||||
degrees with almost no noise at all and
|
||||
even though this should be a great
|
||||
cooler design it is only quiet sometimes
|
||||
the other times it is just super whiny
|
||||
and given the fact that these reports
|
||||
are so widespread with all sorts of
|
||||
Radeon cards it just feels like this is
|
||||
something that AMD really needs to work
|
||||
on my next issue is the power
|
||||
consumption especially in idle when
|
||||
having multiple monitors connected to
|
||||
your cart if I just connect a single
|
||||
monitor power consumption is completely
|
||||
fine with a single watt of a difference
|
||||
between the 4080 and this 7900 XD but
|
||||
when connecting two monitors so I had
|
||||
one 4K 120 hertz one and one 4K 60hz one
|
||||
the power consumption on the XT went up
|
||||
by a lot it was 15 watts higher than the
|
||||
4080 and I would say that is a
|
||||
significant change now depending on how
|
||||
much you pay for your electricity and
|
||||
how many hours you have your monitors on
|
||||
per day this could really add up quickly
|
||||
now supposedly this should get fixed
|
||||
with the next driver so I will put an
|
||||
update in the comment under this video
|
||||
once I learn more about this
|
||||
but perhaps the biggest issue right now
|
||||
is the supply and pricing before these
|
||||
cards launch there were plenty of posts
|
||||
saying that there should be plenty of
|
||||
stock and that the prices should be as
|
||||
promised but in reality the supply so
|
||||
far hasn't been as good it will vary per
|
||||
region but if I look at the Netherlands
|
||||
I haven't seen a single xdx listed at
|
||||
any reputable retailer and even the XT
|
||||
which had more critical reviews overall
|
||||
has been really hard to find most shops
|
||||
I spoke to told me that they have no
|
||||
clear indication of stock on any Radeon
|
||||
cards at this point and the couple shops
|
||||
that did list the XT seem to have very
|
||||
limited stock and they're selling them
|
||||
at very high prices so right now the
|
||||
cheapest one I can find is at 1300 Euros
|
||||
which is 250 euros over the MSRP and
|
||||
only about 150 Euros less than a 4080
|
||||
and a 4080 is faster has stronger Ray
|
||||
tracing performance and it is more power
|
||||
efficient and I think all this was much
|
||||
worse because of the hype that followed
|
||||
the AMD launch and the belief that there
|
||||
might actually be some stock or that the
|
||||
prices might actually stay down anyway
|
||||
the launch was definitely a bit shaky
|
||||
but it is important to remember that
|
||||
most of the things I mentioned today are
|
||||
absolutely fixable and that was the
|
||||
reason of making this video because I
|
||||
know know that AMD cares about criticism
|
||||
and that they do want to fix things for
|
||||
the end users at least the things that
|
||||
can be fixed because as I said before
|
||||
the absolute performance of this 7900 XT
|
||||
is quite good and the only way to fix
|
||||
their relative performance is to lower
|
||||
the price because if it gets
|
||||
significantly cheaper I'm sure that most
|
||||
of us just would not care about the
|
||||
confusing name business or the fact that
|
||||
it is boosting a bit higher one day and
|
||||
then a bit lower the next now the coil
|
||||
wine is a bit more complicated to fix
|
||||
especially for the cars that already
|
||||
love the factory but for future batches
|
||||
that too is definitely fixable and they
|
||||
definitely should fix it because the GPU
|
||||
Market is so competitive and even a
|
||||
single downside like coil wine for
|
||||
example can make a big difference at the
|
||||
end of the day now that is all I have
|
||||
for today I hope this video was
|
||||
interesting enough let me know in the
|
||||
comments down below what are your
|
||||
thoughts about the XD and if you want to
|
||||
make sure not to miss any of my future
|
||||
videos try to click that subscribe
|
||||
button bye guys and see in the next one
|
||||
|
||||
Prompt 0: Split text : Pass 2k characters in to the context and it will return a json with the required text
|
||||
```
|
||||
You are a personal assistant of mine. I need you to take youtube captions and split them into 1500-2000 character blocks. The blocks should all be self-enclosing. Meaning no context from the 1st block is needed in the 2nd block etc. for it to make sense. Omit any sponsorships and mentions of "this video was brought by".
|
||||
|
||||
VERY IMPORTANT: Respond with a JSON compatible array of strings.
|
||||
```
|
||||
|
||||
Prompt 1: Extract main points
|
||||
```
|
||||
<system>
|
||||
You are my personal assistant. I have a youtube video that needs to be broken down into the main points. Please take the captions I have given you and extract the main talking points along with quotes from the script. Send only a list of points with a quote attached to each point. Do not mention "The reviewer" or "You", only say full statements. Ignore any sponsorships or "this video was brought to you by" statements. Those should be excluded from the list of talking points. The talking points returned should look like this:
|
||||
* Main talking point (Quote: "Quote from the captions")
|
||||
</system>
|
||||
|
||||
<captions>
|
||||
a part of the captions
|
||||
</captions>
|
||||
|
||||
<response>
|
||||
```
|
||||
|
||||
Prompt 2: Combine into blog mistral-7b-instruct-0.2
|
||||
```
|
||||
You are a copywriter. I just got my personal assistant to take the main talking points and quotes from a youtube video of mine. Take these main talking points and write an engaging blog article.
|
||||
|
||||
<talkingpoints>
|
||||
all talking points from previous prompt
|
||||
</talkingpoints>
|
||||
|
||||
<response>
|
||||
```
|
||||
Thoughs: The response was generally pretty OK. Got like 60% on quillbot AI detector.
|
||||
|
||||
Prompt 2 v2: Caption directly into blog
|
||||
```
|
||||
You are a copywriter. Your job is to write blog articles for all of my youtube videos to help with SEO and channel growth. I provide you with SRT captions from my youtube videos and you return an *engaging* blog article I can post to my website. You are allowed to use markdown for formatting. Make sure you do not mention any sponsors or "video was brough to you by" in the blog article.
|
||||
```
|
||||
Thoughts: Very robotic, didn't like it. Also tended to imagine stuff.
|
||||
|
||||
Prompt 2 v3: Main talking points
|
||||
```
|
||||
Take the main points and quotes from my YouTube video, picked out by my assistant, and turn them into a fun and informative blog post. The topic can change depending on the video. Keep it easy to read and relatable, like chatting with a friend. You can use markdown if it helps. The aim is to make content that feels natural and connects well with my audience, while still getting across the main ideas from the video.
|
||||
```
|
||||
|
||||
full response. Model used: mistral-7b-instruct-v0.2
|
||||
|
||||
Title: My Honest Take on the AMD Radeon RX 7900 XT: A Powerful Card with Room for Improvement
|
||||
|
||||
Last week, AMD made waves in the tech world with the launch of their new graphics cards, specifically the RX 7900 XTX. As a tech enthusiast and content creator, I was excited to get my hands on the latest offering from AMD. However, due to unforeseen circumstances, I wasn't able to test the reference card. Instead, I've had the opportunity to review the Asus model of the RX 7900 XT.
|
||||
|
||||
Before we dive into the specifics of my review, I want to acknowledge AMD's success in creating high-end graphics cards and bringing some much-needed competition to the market. The graphics card landscape has been dominated by Nvidia for quite some time, and AMD's entry into the high-end market is a welcome change.
|
||||
|
||||
That being said, I also think that there are plenty of things that still need improvement with the RX 7900 XT. One of the most significant issues is the card's name and the confusion it causes for consumers. The XT model shares a similar name to the XTX, despite significant differences in specs. The XT has fewer cores, lower clock speeds, less memory, and a smaller memory bus than the XTX. AMD is pretty much doing the same thing Nvidia did with their controversial 4086 16 gig and 4080 12 gig cards. For 100 more, you can get a card that is 16 faster.
|
||||
|
||||
Another issue I've encountered is the inconsistent performance of the RX 7900 XT. In Call of Duty Modern Warfare, for instance, the card's performance was inconsistent, with one moment showing FPS numbers that align with other cards, and the next moment boosting much higher, outperforming the RTX 4090 and RTX 7900 XT. Every time we rebooted the PC, the XT acted differently for no clear reason. Seeing this inconsistent behavior always causes doubt whether everything is working well as it should.
|
||||
|
||||
Additionally, the ASUS TUF Gaming Radeon RX 7900 XT graphics card can produce coil whine, which is more noticeable due to its variable sound. This TUF Gaming from Asus doesn't always whine, but it does sit pretty frequently. And since the sound often changes depending on what's going on with your PC, it is way more noticeable than if it was just a consistent tone.
|
||||
|
||||
The oversized cooler on the TUF Gaming RX 7900 XT performs well when it's not whining, maintaining temperatures below 50 degrees with minimal noise. I managed to test the thermal and noise performance at one point where it wasn't whining, and this oversized Tough Cooler performed extremely well, barely going over 50 degrees with almost no noise at all.
|
||||
|
||||
However, there are a few other issues that need addressing. Power consumption is higher when using multiple monitors with the Radeon RX 7900 XT, leading to increased electricity costs. When connecting two monitors, the power consumption on the XT went up by a lot, 15 watts higher than the 4080.
|
||||
|
||||
The launch of the Radeon RX 7900 XT was definitely a bit shaky, but it is important to remember that most of the issues I've mentioned today are absolutely fixable. The only way to fix their relative performance is to lower the price. Coil whine is a bit more complicated to fix, especially for the cards that already left the factory. But for future batches, that too is definitely fixable.
|
||||
|
||||
In conclusion, the AMD Radeon RX 7900 XT is a powerful card with room for improvement. It offers a great high refresh rate experience at 1440p resolution and is capable of 4K gaming with FSR support. However, the inconsistent performance, coil whine, and power consumption issues are significant concerns that need to be addressed. AMD has the potential to create a truly competitive high-end graphics card, and I'm excited to see how they Title: My Honest Take on the AMD Radeon RX 7900 XT: A Powerful Card with Room for Improvement
|
||||
|
||||
Last week, AMD made waves in the tech world with the launch of their new graphics cards, specifically the RX 7900 XTX. As a tech enthusiast and content creator, I was excited to get my hands on the latest offering from AMD. However, due to unforeseen circumstances, I wasn't able to test the reference card. Instead, I've had the opportunity to review the Asus model of the RX 7900 XT.
|
||||
|
||||
Before we dive into the specifics of my review, I want to acknowledge AMD's success in creating high-end graphics cards and bringing some much-needed competition to the market. The graphics card landscape has been dominated by Nvidia for quite some time, and AMD's entry into the high-end market is a welcome change.
|
||||
|
||||
That being said, I also think that there are plenty of things that still need improvement with the RX 7900 XT. One of the most significant issues is the card's name and the confusion it causes for consumers. The XT model shares a similar name to the XTX, despite significant differences in specs. The XT has fewer cores, lower clock speeds, less memory, and a smaller memory bus than the XTX. AMD is pretty much doing the same thing Nvidia did with their controversial 4086 16 gig and 4080 12 gig cards. For 100 more, you can get a card that is 16 faster.
|
||||
|
||||
Another issue I've encountered is the inconsistent performance of the RX 7900 XT. In Call of Duty Modern Warfare, for instance, the card's performance was inconsistent, with one moment showing FPS numbers that align with other cards, and the next moment boosting much higher, outperforming the RTX 4090 and RTX 7900 XT. Every time we rebooted the PC, the XT acted differently for no clear reason. Seeing this inconsistent behavior always causes doubt whether everything is working well as it should.
|
||||
|
||||
Additionally, the ASUS TUF Gaming Radeon RX 7900 XT graphics card can produce coil whine, which is more noticeable due to its variable sound. This TUF Gaming from Asus doesn't always whine, but it does sit pretty frequently. And since the sound often changes depending on what's going on with your PC, it is way more noticeable than if it was just a consistent tone.
|
||||
|
||||
The oversized cooler on the TUF Gaming RX 7900 XT performs well when it's not whining, maintaining temperatures below 50 degrees with minimal noise. I managed to test the thermal and noise performance at one point where it wasn't whining, and this oversized Tough Cooler performed extremely well, barely going over 50 degrees with almost no noise at all.
|
||||
|
||||
However, there are a few other issues that need addressing. Power consumption is higher when using multiple monitors with the Radeon RX 7900 XT, leading to increased electricity costs. When connecting two monitors, the power consumption on the XT went up by a lot, 15 watts higher than the 4080.
|
||||
|
||||
The launch of the Radeon RX 7900 XT was definitely a bit shaky, but it is important to remember that most of the issues I've mentioned today are absolutely fixable. The only way to fix their relative performance is to lower the price. Coil whine is a bit more complicated to fix, especially for the cards that already left the factory. But for future batches, that too is definitely fixable.
|
||||
|
||||
In conclusion, the AMD Radeon RX 7900 XT is a powerful card with room for improvement. It offers a great high refresh rate experience at 1440p resolution and is capable of 4K gaming with FSR support. However, the inconsistent performance, coil whine, and power consumption issues are significant concerns that need to be addressed. AMD has the potential to create a truly competitive high-end graphics card, and I'm excited to see how they will address these issues moving forward.
|
Loading…
Reference in New Issue
Block a user