progress
ci / build (push) Has been cancelled
Details
ci / build (push) Has been cancelled
Details
This commit is contained in:
parent
358e484a12
commit
93b90c5586
|
@ -19,9 +19,6 @@
|
||||||
**/charts/**/charts
|
**/charts/**/charts
|
||||||
**/.mocharc.json
|
**/.mocharc.json
|
||||||
|
|
||||||
**/.env
|
|
||||||
**/node_modules
|
|
||||||
|
|
||||||
packages/strapi/.tmp/
|
packages/strapi/.tmp/
|
||||||
packages/strapi/.cache/
|
packages/strapi/.cache/
|
||||||
packages/strapi/.git/
|
packages/strapi/.git/
|
||||||
|
|
24
Tiltfile
24
Tiltfile
|
@ -48,19 +48,6 @@ dotenv(fn='.env.development')
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
## this method results in the following error. Build Failed: Internal error occurred: failed calling webhook "webhook.cert-manager.io": failed to call webhook: Post "https://cert-manager-webhook.cert-manager.svc:443/validate?timeout=30s": service "cert-manager-webhook" not found
|
|
||||||
# helm_remote(
|
|
||||||
# 'cert-manager',
|
|
||||||
# repo_url='https://charts.jetstack.io',
|
|
||||||
# repo_name='cert-manager',
|
|
||||||
# namespace='cert-manager',
|
|
||||||
# version='1.15.1',
|
|
||||||
# set=[
|
|
||||||
# 'crds.enabled=true'
|
|
||||||
# ]
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
helm_remote(
|
helm_remote(
|
||||||
'traefik',
|
'traefik',
|
||||||
|
@ -125,8 +112,8 @@ k8s_yaml(helm(
|
||||||
docker_build(
|
docker_build(
|
||||||
'fp/strapi',
|
'fp/strapi',
|
||||||
'.',
|
'.',
|
||||||
only=['./packages/strapi', './packages/types'],
|
dockerfile='./d.packages.dockerfile',
|
||||||
dockerfile='./d.strapi.dev.dockerfile',
|
target='strapi',
|
||||||
live_update=[
|
live_update=[
|
||||||
sync('./packages/strapi', '/app')
|
sync('./packages/strapi', '/app')
|
||||||
]
|
]
|
||||||
|
@ -135,7 +122,6 @@ docker_build(
|
||||||
docker_build(
|
docker_build(
|
||||||
'fp/bot',
|
'fp/bot',
|
||||||
'.',
|
'.',
|
||||||
only=['./pnpm-lock.yaml', './package.json', './packages/types', './packages/bot'],
|
|
||||||
dockerfile='./d.packages.dockerfile',
|
dockerfile='./d.packages.dockerfile',
|
||||||
target='bot-dev',
|
target='bot-dev',
|
||||||
live_update=[
|
live_update=[
|
||||||
|
@ -193,8 +179,7 @@ cmd_button('temporal-web:namespace',
|
||||||
docker_build(
|
docker_build(
|
||||||
'fp/next',
|
'fp/next',
|
||||||
'.',
|
'.',
|
||||||
# only=['./pnpm-lock.yaml', './package.json', './packages/next', './packages/types', './ca/letsencrypt-stg-root-x1.pem'],
|
dockerfile='d.packages.dockerfile',
|
||||||
dockerfile='d.next.dockerfile',
|
|
||||||
target='next',
|
target='next',
|
||||||
build_args={
|
build_args={
|
||||||
'NEXT_PUBLIC_STRAPI_URL': 'https://strapi.fp.sbtp.xyz'
|
'NEXT_PUBLIC_STRAPI_URL': 'https://strapi.fp.sbtp.xyz'
|
||||||
|
@ -208,7 +193,6 @@ docker_build(
|
||||||
docker_build(
|
docker_build(
|
||||||
'fp/scout-manager',
|
'fp/scout-manager',
|
||||||
'.',
|
'.',
|
||||||
only=['./pnpm-lock.yaml', './package.json', './packages/scout', './packages/types', './ca/letsencrypt-stg-root-x1.pem'],
|
|
||||||
dockerfile='d.packages.dockerfile',
|
dockerfile='d.packages.dockerfile',
|
||||||
target='scout-manager',
|
target='scout-manager',
|
||||||
live_update=[
|
live_update=[
|
||||||
|
@ -223,7 +207,6 @@ docker_build(
|
||||||
docker_build(
|
docker_build(
|
||||||
'fp/boop',
|
'fp/boop',
|
||||||
'.',
|
'.',
|
||||||
# only=['./pnpm-lock.yaml', './package.json', './packages/scout', './packages/types', './ca/letsencrypt-stg-root-x1.pem'],
|
|
||||||
dockerfile='d.packages.dockerfile',
|
dockerfile='d.packages.dockerfile',
|
||||||
target='boop',
|
target='boop',
|
||||||
live_update=[
|
live_update=[
|
||||||
|
@ -239,7 +222,6 @@ docker_build(
|
||||||
docker_build(
|
docker_build(
|
||||||
'fp/scout-worker',
|
'fp/scout-worker',
|
||||||
'.',
|
'.',
|
||||||
only=['./pnpm-lock.yaml', './package.json', './packages/scout', './packages/types', './ca/letsencrypt-stg-root-x1.pem'],
|
|
||||||
# ignore=['./packages/next'], # I wish I could use this ignore to ignore file changes in this dir, but that's not how it works
|
# ignore=['./packages/next'], # I wish I could use this ignore to ignore file changes in this dir, but that's not how it works
|
||||||
dockerfile='d.packages.dockerfile',
|
dockerfile='d.packages.dockerfile',
|
||||||
target='scout-worker',
|
target='scout-worker',
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
## Important! Build context is the ROOT of the project.
|
|
||||||
## this keeps the door open for future possibility of shared code between pnpm workspace packages
|
|
||||||
|
|
||||||
FROM node:20-slim AS base
|
|
||||||
|
|
||||||
FROM base AS deps
|
|
||||||
ENV PNPM_HOME="/pnpm"
|
|
||||||
ENV PATH="$PNPM_HOME:$PATH"
|
|
||||||
RUN corepack enable
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
|
|
||||||
FROM deps AS install
|
|
||||||
ARG NEXT_PUBLIC_SITE_URL=https://futureporn.net
|
|
||||||
ARG NEXT_PUBLIC_STRAPI_URL=https://portal.futureporn.net
|
|
||||||
ARG NEXT_PUBLIC_UPPY_COMPANION_URL=https://uppy.futureporn.net
|
|
||||||
ENV NEXT_PUBLIC_SITE_URL ${NEXT_PUBLIC_SITE_URL}
|
|
||||||
ENV NEXT_PUBLIC_STRAPI_URL ${NEXT_PUBLIC_STRAPI_URL}
|
|
||||||
ENV NEXT_PUBLIC_UPPY_COMPANION_URL ${NEXT_PUBLIC_UPPY_COMPANION_URL}
|
|
||||||
ENV NEXT_TELEMETRY_DISABLED 1
|
|
||||||
ENV NODE_EXTRA_CA_CERTS "/app/letsencrypt-stg-root-x1.pem"
|
|
||||||
COPY pnpm-lock.yaml ./
|
|
||||||
RUN pnpm fetch
|
|
||||||
COPY ./packages/next /app
|
|
||||||
RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install
|
|
||||||
|
|
||||||
|
|
||||||
FROM install AS dev
|
|
||||||
CMD ["pnpm", "run", "dev"]
|
|
||||||
|
|
||||||
FROM install AS build
|
|
||||||
RUN pnpm run build
|
|
||||||
|
|
||||||
FROM deps AS next
|
|
||||||
RUN apt-get update && apt-get install -y -qq --no-install-recommends dumb-init
|
|
||||||
COPY --chown=node:node --from=build /app/package.json /app/pnpm-lock.yaml ./
|
|
||||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
|
|
||||||
COPY --chown=node:node --from=build /app/public ./public
|
|
||||||
COPY --chown=node:node --from=build /app/.next/standalone ./
|
|
||||||
COPY --chown=node:node --from=build /app/.next/static ./.next/static
|
|
||||||
ENV TZ=UTC
|
|
||||||
ENV NODE_ENV=production
|
|
||||||
ENV HOSTNAME="0.0.0.0"
|
|
||||||
CMD [ "dumb-init", "node", "server.js" ]
|
|
||||||
|
|
|
@ -21,19 +21,37 @@ ENTRYPOINT ["pnpm"]
|
||||||
|
|
||||||
|
|
||||||
FROM base AS build
|
FROM base AS build
|
||||||
ENV NODE_ENV=production
|
ARG NEXT_PUBLIC_SITE_URL=https://futureporn.net
|
||||||
|
ARG NEXT_PUBLIC_STRAPI_URL=https://portal.futureporn.net
|
||||||
|
ARG NEXT_PUBLIC_UPPY_COMPANION_URL=https://uppy.futureporn.net
|
||||||
|
ENV NEXT_PUBLIC_SITE_URL ${NEXT_PUBLIC_SITE_URL}
|
||||||
|
ENV NEXT_PUBLIC_STRAPI_URL ${NEXT_PUBLIC_STRAPI_URL}
|
||||||
|
ENV NEXT_PUBLIC_UPPY_COMPANION_URL ${NEXT_PUBLIC_UPPY_COMPANION_URL}
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED 1
|
||||||
COPY . /usr/src/app
|
COPY . /usr/src/app
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
RUN mkdir -p /prod/scout
|
RUN mkdir -p /prod
|
||||||
RUN pnpm fetch
|
RUN pnpm fetch
|
||||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile --offline
|
## strapi needs node-gyp
|
||||||
|
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install -g node-gyp
|
||||||
|
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
||||||
|
ENV NODE_ENV production
|
||||||
RUN pnpm --recursive build
|
RUN pnpm --recursive build
|
||||||
RUN pnpm deploy --filter=boop /prod/boop
|
## we use pnpm deploy to create bundled, isolated node packages for docker containers. See https://pnpm.io/cli/deploy
|
||||||
# RUN pnpm deploy --filter=scout --prod /prod/scout
|
## we can deploy most packages this way, but with some projects such as next it's not necessary as next's build step packages all dependencies.
|
||||||
# RUN pnpm deploy --filter=bot --prod /prod/bot
|
RUN pnpm deploy --filter=boop --prod /prod/boop
|
||||||
# RUN pnpm deploy --filter=temporal-worker --prod /prod/temporal-worker
|
RUN pnpm deploy --filter=scout --prod /prod/scout
|
||||||
# RUN pnpm deploy --filter=next /prod/next
|
|
||||||
# RUN pnpm deploy --filter=next /prod/next-dev
|
|
||||||
|
FROM base AS strapi
|
||||||
|
COPY --from=build /usr/src/app/packages/strapi .
|
||||||
|
CMD ["run", "develop"]
|
||||||
|
|
||||||
|
|
||||||
|
# NODE_ENV=development is important for the fp/next build.
|
||||||
|
## @todo remove the --filter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FROM base AS boop
|
FROM base AS boop
|
||||||
COPY --from=build /prod/boop /app
|
COPY --from=build /prod/boop /app
|
||||||
|
@ -60,19 +78,25 @@ CMD ["start"]
|
||||||
# RUN pnpm fetch
|
# RUN pnpm fetch
|
||||||
# RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install
|
# RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install
|
||||||
|
|
||||||
FROM base AS next-build
|
# FROM base AS next-build
|
||||||
COPY --from=build /prod/next /app
|
# COPY --from=build /prod/next /app
|
||||||
# RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install
|
# # RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install
|
||||||
# RUN ls -la
|
# # RUN ls -la
|
||||||
RUN pnpm run build
|
# RUN pnpm run build
|
||||||
|
|
||||||
FROM base as next
|
FROM base as next
|
||||||
COPY --from=next-build /app /app
|
RUN apt-get update && apt-get install -y -qq --no-install-recommends dumb-init
|
||||||
|
COPY --chown=node:node --from=build /usr/src/app/packages/next/public ./public
|
||||||
|
COPY --chown=node:node --from=build /usr/src/app/packages/next/.next/standalone ./
|
||||||
|
COPY --chown=node:node --from=build /usr/src/app/packages/next/.next/static ./.next/static
|
||||||
ENV TZ=UTC
|
ENV TZ=UTC
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
ENV HOSTNAME="0.0.0.0"
|
ENV HOSTNAME="0.0.0.0"
|
||||||
ENTRYPOINT [ "dumb-init", "node", "server.js" ]
|
ENTRYPOINT [ "dumb-init", "node", "server.js" ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# FROM base AS next-pre
|
# FROM base AS next-pre
|
||||||
# COPY --from=build /prod/next /app
|
# COPY --from=build /prod/next /app
|
||||||
# ENV NODE_EXTRA_CA_CERTS "/app/letsencrypt-stg-root-x1.pem"
|
# ENV NODE_EXTRA_CA_CERTS "/app/letsencrypt-stg-root-x1.pem"
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
FROM node:18 AS base
|
|
||||||
WORKDIR /usr/src/app/
|
|
||||||
RUN corepack enable
|
|
||||||
ENV PNPM_HOME="/pnpm"
|
|
||||||
ENV PATH="$PNPM_HOME:$PATH"
|
|
||||||
COPY ./packages/strapi/package.json ./packages/strapi/pnpm-lock.yaml .
|
|
||||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
|
||||||
COPY ./packages/strapi/ .
|
|
||||||
RUN ["pnpm", "run", "build"]
|
|
||||||
CMD ["pnpm", "run", "develop"]
|
|
|
@ -15,7 +15,7 @@
|
||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
// Transpile our TypeScript code to JavaScript
|
// Transpile our TypeScript code to JavaScript
|
||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"outDir": "lib",
|
"outDir": "dist",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2022"
|
"es2022"
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"start": "node index.js"
|
"start": "node index.js",
|
||||||
|
"build": "tsc --build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"taco": "workspace:*",
|
"taco": "workspace:*",
|
||||||
|
@ -14,5 +15,8 @@
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC"
|
"license": "Unlicense",
|
||||||
|
"devDependencies": {
|
||||||
|
"typescript": "^5.5.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,3 +14,18 @@ importers:
|
||||||
types:
|
types:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../types
|
version: link:../types
|
||||||
|
devDependencies:
|
||||||
|
typescript:
|
||||||
|
specifier: ^5.5.3
|
||||||
|
version: 5.5.3
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
typescript@5.5.3:
|
||||||
|
resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
|
||||||
|
engines: {node: '>=14.17'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
snapshots:
|
||||||
|
|
||||||
|
typescript@5.5.3: {}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
// Base Options recommended for all projects
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"target": "es2022",
|
||||||
|
"allowJs": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"isolatedModules": true,
|
||||||
|
// Enable strict type checking so you can catch bugs early
|
||||||
|
"strict": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
// Transpile our TypeScript code to JavaScript
|
||||||
|
"module": "NodeNext",
|
||||||
|
"outDir": "dist",
|
||||||
|
"lib": [
|
||||||
|
"es2022",
|
||||||
|
"dom"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// Include the necessary files for your project
|
||||||
|
"include": [
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
// Transpile our TypeScript code to JavaScript
|
// Transpile our TypeScript code to JavaScript
|
||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"outDir": "lib",
|
"outDir": "dist",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2022"
|
"es2022"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
# next
|
# next
|
||||||
|
|
||||||
|
HTML5 frontend for https://futureporn.net
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import { getVodTitle } from '@/components/vod-page';
|
import { getVodTitle } from '@/app/components/vod-page';
|
||||||
import { getUrl, getAllVods } from "@/lib/vods"
|
import { getUrl, getAllVods } from "@/app/lib/vods"
|
||||||
import { IVod } from "@/lib/vods"
|
import { IVod } from "@/app/lib/vods"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import StreamPage from '@/components/stream-page';
|
import StreamPage from '@/app/components/stream-page';
|
||||||
import { getStreamByCuid } from '@/lib/streams';
|
import { getStreamByCuid } from '@/app/lib/streams';
|
||||||
|
|
||||||
|
|
||||||
interface IPageParams {
|
interface IPageParams {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Pager from "@/components/pager";
|
import Pager from "@/app/components/pager";
|
||||||
import StreamsList from "@/components/streams-list";
|
import StreamsList from "@/app/components/streams-list";
|
||||||
import StreamsTable from '@/components/streams-table';
|
import StreamsTable from '@/app/components/streams-table';
|
||||||
import { getAllStreams, getStreamsForVtuber } from "@/lib/streams";
|
import { getAllStreams, getStreamsForVtuber } from "@/app/lib/streams";
|
||||||
// import { getAllVtubers } from "@/lib/vtubers";
|
// import { getAllVtubers } from "@/app/lib/vtubers";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { getAllStreamsForVtuber, getStreamCountForVtuber } from "@/lib/streams";
|
import { getAllStreamsForVtuber, getStreamCountForVtuber } from "@/app/lib/streams";
|
||||||
import { getVodsForVtuber } from "@/lib/vods";
|
import { getVodsForVtuber } from "@/app/lib/vods";
|
||||||
import { IVtuber } from "@/lib/vtubers";
|
import { IVtuber } from "types";
|
||||||
|
|
||||||
export interface IArchiveProgressProps {
|
export interface IArchiveProgressProps {
|
||||||
vtuber: IVtuber;
|
vtuber: IVtuber;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { faPatreon } from '@fortawesome/free-brands-svg-icons';
|
||||||
import { useLocalStorageValue } from '@react-hookz/web';
|
import { useLocalStorageValue } from '@react-hookz/web';
|
||||||
import { faRightFromBracket } from '@fortawesome/free-solid-svg-icons';
|
import { faRightFromBracket } from '@fortawesome/free-solid-svg-icons';
|
||||||
import Skeleton from 'react-loading-skeleton';
|
import Skeleton from 'react-loading-skeleton';
|
||||||
import { strapiUrl } from '@/lib/constants';
|
import { strapiUrl } from '@/app/lib/constants';
|
||||||
// import NextAuth from 'next-auth'; // this is (pipedream) wishlist
|
// import NextAuth from 'next-auth'; // this is (pipedream) wishlist
|
||||||
// import Providers from 'next-auth/providers';
|
// import Providers from 'next-auth/providers';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import { getCampaign } from "@/lib/patreon";
|
import { getCampaign } from "@/app/lib/patreon";
|
||||||
import { getGoals, IGoals } from '@/lib/pm'
|
import { getGoals, IGoals } from '@/app/lib/pm'
|
||||||
import Image from "next/legacy/image";
|
import Image from "next/legacy/image";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons";
|
import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faUser, faUpload } from "@fortawesome/free-solid-svg-icons";
|
import { faUser, faUpload } from "@fortawesome/free-solid-svg-icons";
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { LoginButton, useAuth } from '@/components/auth'
|
import { LoginButton, useAuth } from '@/app/components/auth'
|
||||||
|
|
||||||
|
|
||||||
export default function Navbar() {
|
export default function Navbar() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { IStream } from "@/lib/streams";
|
import { IStream } from "types";
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faCalendar } from "@fortawesome/free-solid-svg-icons";
|
import { faCalendar } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { IStream } from "@/lib/streams";
|
import { IStream } from "types";
|
||||||
// import NotFound from "app/streams/[cuid]/not-found";
|
// import NotFound from "app/streams/[cuid]/not-found";
|
||||||
import { IVod } from "@/lib/vods";
|
import { IVod } from "@/app/lib/vods";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import Image from "next/legacy/image";
|
import Image from "next/legacy/image";
|
||||||
import { LocalizedDate } from "./localized-date";
|
import { LocalizedDate } from "./localized-date";
|
||||||
|
@ -37,7 +37,7 @@ function determineStatus(stream: IStream): Status {
|
||||||
if (stream.attributes.vods.data.length < 1) {
|
if (stream.attributes.vods.data.length < 1) {
|
||||||
return 'missing'
|
return 'missing'
|
||||||
} else {
|
} else {
|
||||||
if (stream.attributes.vods.data.some(vod => !hasNote(vod))) {
|
if (stream.attributes.vods.data.some((vod: IVod) => !hasNote(vod))) {
|
||||||
return 'good';
|
return 'good';
|
||||||
} else {
|
} else {
|
||||||
return 'issue';
|
return 'issue';
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { IStream } from "@/lib/streams";
|
import { IStream } from "types";
|
||||||
import NotFound from "app/vt/[slug]/not-found";
|
import NotFound from "@/app/vt/[slug]/not-found";
|
||||||
import { LocalizedDate } from "./localized-date";
|
import { LocalizedDate } from "./localized-date";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import ChaturbateIcon from "@/components/icons/chaturbate";
|
import ChaturbateIcon from "@/app/components/icons/chaturbate";
|
||||||
import FanslyIcon from "@/components/icons/fansly";
|
import FanslyIcon from "@/app/components/icons/fansly";
|
||||||
import Image from "next/legacy/image";
|
import Image from "next/legacy/image";
|
||||||
|
|
||||||
export interface IStreamProps {
|
export interface IStreamProps {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { IVtuber } from '@/lib/vtubers';
|
import { IVtuber } from 'types';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import { IStream, getAllStreams } from '@/lib/streams';
|
import { getAllStreams } from '@/app/lib/streams';
|
||||||
import { StreamSummary } from '@/components/stream';
|
import { IStream } from 'types';
|
||||||
|
import { StreamSummary } from '@/app/components/stream';
|
||||||
|
|
||||||
interface IStreamsListProps {
|
interface IStreamsListProps {
|
||||||
vtubers: IVtuber[];
|
vtubers: IVtuber[];
|
||||||
|
|
|
@ -19,7 +19,8 @@ import {
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { faSpinner } from '@fortawesome/free-solid-svg-icons'
|
import { faSpinner } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
import { fetchStreamData, IStream } from '@/lib/streams'
|
import { fetchStreamData } from '@/app/lib/streams'
|
||||||
|
import { IStream } from 'types'
|
||||||
|
|
||||||
const queryClient = new QueryClient()
|
const queryClient = new QueryClient()
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { ITagVodRelation, ITagVodRelationsResponse } from "@/lib/tag-vod-relations"
|
import { ITagVodRelation, ITagVodRelationsResponse } from "@/app/lib/tag-vod-relations"
|
||||||
import { isWithinInterval, subHours } from "date-fns";
|
import { isWithinInterval, subHours } from "date-fns";
|
||||||
import { faTrash } from "@fortawesome/free-solid-svg-icons";
|
import { faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { AuthContext, IUseAuth } from "./auth";
|
import { AuthContext, IUseAuth } from "./auth";
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { strapiUrl } from "@/lib/constants";
|
import { strapiUrl } from "@/app/lib/constants";
|
||||||
|
|
||||||
export interface ITagParams {
|
export interface ITagParams {
|
||||||
tvr: ITagVodRelation;
|
tvr: ITagVodRelation;
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState, useCallback, useEffect, useContext } from 'react';
|
import { useState, useCallback, useEffect, useContext } from 'react';
|
||||||
import { IVod } from '@/lib/vods';
|
import { IVod } from '@/app/lib/vods';
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faPlus, faX, faTags } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faX, faTags } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { formatTimestamp } from '@/lib/dates';
|
import { formatTimestamp } from '@/app/lib/dates';
|
||||||
import { readOrCreateTagVodRelation } from '@/lib/tag-vod-relations';
|
import { readOrCreateTagVodRelation } from '@/app/lib/tag-vod-relations';
|
||||||
import { readOrCreateTag } from '@/lib/tags';
|
import { readOrCreateTag } from '@/app/lib/tags';
|
||||||
import { useAuth } from './auth';
|
import { useAuth } from './auth';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
import { strapiUrl } from '@/lib/constants';
|
import { strapiUrl } from '@/app/lib/constants';
|
||||||
import { VideoContext } from './video-context';
|
import { VideoContext } from './video-context';
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { ITimestamp, createTimestamp } from '@/lib/timestamps';
|
import { ITimestamp, createTimestamp } from '@/app/lib/timestamps';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import styles from '@/assets/styles/fp.module.css'
|
import styles from '@/assets/styles/fp.module.css'
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { useContext, useState, useEffect } from "react";
|
import React, { useContext, useState, useEffect } from "react";
|
||||||
import { IVod } from "@/lib/vods";
|
import { IVod } from "@/app/lib/vods";
|
||||||
import {
|
import {
|
||||||
ITimestamp,
|
ITimestamp,
|
||||||
deleteTimestamp
|
deleteTimestamp
|
||||||
} from "@/lib/timestamps";
|
} from "@/app/lib/timestamps";
|
||||||
import {
|
import {
|
||||||
formatTimestamp,
|
formatTimestamp,
|
||||||
formatUrlTimestamp,
|
formatUrlTimestamp,
|
||||||
} from "@/lib/dates";
|
} from "@/app/lib/dates";
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { faClock, faLink, faTrash } from "@fortawesome/free-solid-svg-icons";
|
import { faClock, faLink, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IToy, IToysResponse } from '@/lib/toys';
|
import { IToy, IToysResponse } from '@/app/lib/toys';
|
||||||
import { IVtuber } from '@/lib/vtubers';
|
import { IVtuber } from 'types';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import Image from "next/legacy/image";
|
import Image from "next/legacy/image";
|
||||||
|
|
||||||
|
|
|
@ -1,28 +1,26 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { IVtuber } from "@/lib/vtubers";
|
|
||||||
import { IStream } from "@/lib/streams";
|
import { IVtuber } from "types";
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
import React, { useContext, useState, useEffect } from 'react';
|
import React from 'react';
|
||||||
import { UppyContext } from 'app/uppy';
|
|
||||||
import AwsS3 from '@uppy/aws-s3';
|
import AwsS3 from '@uppy/aws-s3';
|
||||||
import RemoteSources from '@uppy/remote-sources';
|
import RemoteSources from '@uppy/remote-sources';
|
||||||
import { LoginButton, useAuth } from '@/components/auth';
|
import { LoginButton, useAuth } from '@/app/components/auth';
|
||||||
import { Dashboard } from '@uppy/react';
|
import { Dashboard } from '@uppy/react';
|
||||||
import styles from '@/assets/styles/fp.module.css'
|
import styles from '@/assets/styles/fp.module.css'
|
||||||
import { projektMelodyEpoch } from "@/lib/constants";
|
import { projektMelodyEpoch } from "@/app/lib/constants";
|
||||||
import add from "date-fns/add";
|
import add from "date-fns/add";
|
||||||
import sub from "date-fns/sub";
|
import sub from "date-fns/sub";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faCheckCircle, faEraser, faPaperPlane, faSpinner, faX, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faEraser, faPaperPlane, faSpinner, faX, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { useForm, useFieldArray, ValidationMode } from 'react-hook-form';
|
import { useForm, ValidationMode } from 'react-hook-form';
|
||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
import * as Yup from 'yup';
|
import * as Yup from 'yup';
|
||||||
import qs from 'qs';
|
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import { ErrorMessage } from "@hookform/error-message"
|
import { ErrorMessage } from "@hookform/error-message"
|
||||||
import Uppy from '@uppy/core';
|
import Uppy from '@uppy/core';
|
||||||
import { companionUrl } from '@/lib/constants';
|
import { companionUrl } from '@/app/lib/constants';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
|
|
||||||
import VideoApiElement from "@mux/mux-player/dist/types/video-api";
|
import { createContext } from "react";
|
||||||
import { MutableRefObject, createContext, useState } from "react";
|
import { ITagVodRelation } from "@/app/lib/tag-vod-relations";
|
||||||
import { ITagVodRelation } from "@/lib/tag-vod-relations";
|
|
||||||
|
|
||||||
export interface IVideoContextValue {
|
export interface IVideoContextValue {
|
||||||
timeStamp: number;
|
timeStamp: number;
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { IVod } from "@/lib/vods";
|
import { IVod } from "@/app/lib/vods";
|
||||||
import { useRef, useState, useEffect, useCallback } from "react";
|
import { useRef, useState, useEffect, useCallback } from "react";
|
||||||
import { VideoPlayer } from "./video-player";
|
import { VideoPlayer } from "./video-player";
|
||||||
import { Tagger } from './tagger';
|
import { Tagger } from './tagger';
|
||||||
import { ITimestamp, getTimestampsForVod } from "@/lib/timestamps";
|
import { ITimestamp, getTimestampsForVod } from "@/app/lib/timestamps";
|
||||||
import { TimestampsList } from "./timestamps-list";
|
import { TimestampsList } from "./timestamps-list";
|
||||||
import { ITagVodRelation } from "@/lib/tag-vod-relations";
|
import { ITagVodRelation } from "@/app/lib/tag-vod-relations";
|
||||||
import { VideoContext } from "./video-context";
|
import { VideoContext } from "./video-context";
|
||||||
import { getVodTitle } from "./vod-page";
|
import { getVodTitle } from "./vod-page";
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
import VideoApiElement from "@mux/mux-player/dist/types/video-api";
|
import type VideoApiElement from "@mux/mux-player";
|
||||||
import { parseUrlTimestamp } from "@/lib/dates";
|
import { parseUrlTimestamp } from "@/app/lib/dates";
|
||||||
import { faTags, faNoteSticky, faClock } from "@fortawesome/free-solid-svg-icons";
|
import { faTags, faNoteSticky, faClock } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { Tag } from './tag';
|
import { Tag } from './tag';
|
||||||
import VodNav from './vod-nav';
|
import VodNav from './vod-nav';
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect, useState, forwardRef, useContext, Ref } from 'react';
|
import { useEffect, useState, forwardRef, useContext, Ref } from 'react';
|
||||||
import { IVod } from '@/lib/vods';
|
import { IVod } from '@/app/lib/vods';
|
||||||
import { useAuth } from '@/components/auth';
|
import { useAuth } from '@/app/components/auth';
|
||||||
import { getVodTitle } from './vod-page';
|
import { getVodTitle } from './vod-page';
|
||||||
import { VideoSourceSelector } from '@/components/video-source-selector'
|
import { VideoSourceSelector } from '@/app/components/video-source-selector'
|
||||||
import { buildIpfsUrl } from '@/lib/ipfs';
|
import { buildIpfsUrl } from '@/app/lib/ipfs';
|
||||||
import { strapiUrl } from '@/lib/constants';
|
import { strapiUrl } from '@/app/lib/constants';
|
||||||
import MuxPlayer from '@mux/mux-player-react/lazy';
|
import MuxPlayer from '@mux/mux-player-react/lazy';
|
||||||
import { VideoContext } from './video-context';
|
import { VideoContext } from './video-context';
|
||||||
import MuxPlayerElement from '@mux/mux-player';
|
import MuxPlayerElement from '@mux/mux-player';
|
||||||
import VideoApiElement from "@mux/mux-player/dist/types/video-api";
|
import type VideoApiElement from "@mux/mux-player";
|
||||||
|
|
||||||
interface IPlayerProps {
|
interface IPlayerProps {
|
||||||
vod: IVod;
|
vod: IVod;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { getSafeDate } from '@/lib/dates';
|
import { getSafeDate } from '@/app/lib/dates';
|
||||||
import { IVtuber } from '@/lib/vtubers';
|
import { IVtuber } from 'types';
|
||||||
import Image from "next/legacy/image"
|
import Image from "next/legacy/image"
|
||||||
import { LocalizedDate } from '@/components/localized-date'
|
import { LocalizedDate } from '@/app/components/localized-date'
|
||||||
|
|
||||||
interface IVodCardProps {
|
interface IVodCardProps {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
|
@ -5,10 +5,10 @@ import { faXTwitter } from '@fortawesome/free-brands-svg-icons';
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import Image from "next/legacy/image";
|
import Image from "next/legacy/image";
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { IVod } from '@/lib/vods';
|
import { IVod } from '@/app/lib/vods';
|
||||||
import { buildIpfsUrl } from '@/lib/ipfs';
|
import { buildIpfsUrl } from '@/app/lib/ipfs';
|
||||||
import { getSafeDate } from "@/lib/dates";
|
import { getSafeDate } from "@/app/lib/dates";
|
||||||
import { StreamButton } from '@/components/stream-button';
|
import { StreamButton } from '@/app/components/stream-button';
|
||||||
import VtuberButton from "./vtuber-button";
|
import VtuberButton from "./vtuber-button";
|
||||||
import { LocalizedDate } from "./localized-date";
|
import { LocalizedDate } from "./localized-date";
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { getUrl, getNextVod, getPreviousVod, getLocalizedDate } from '@/lib/vods';
|
import { getUrl, getNextVod, getPreviousVod, getLocalizedDate } from '@/app/lib/vods';
|
||||||
import { IVod } from '@/lib/vods';
|
import { IVod } from '@/app/lib/vods';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { VideoInteractive } from './video-interactive';
|
import { VideoInteractive } from './video-interactive';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import VodCard from './vod-card';
|
import VodCard from './vod-card';
|
||||||
import { IVtuber, IVtuberResponse } from '@/lib/vtubers';
|
import { IVtuber } from 'types';
|
||||||
import { IVodsResponse, IVod } from '@/lib/vods';
|
import { IVod } from '@/app/lib/vods';
|
||||||
import { getVodTitle } from './vod-page';
|
import { getVodTitle } from './vod-page';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import type { IVtuber } from '@/lib/vtubers';
|
import type { IVtuber } from 'types';
|
||||||
import { getVodsForVtuber } from "@/lib/vods";
|
import { getVodsForVtuber } from "@/app/lib/vods";
|
||||||
import Image from "next/legacy/image"
|
import Image from "next/legacy/image"
|
||||||
import NotFound from "app/vt/[slug]/not-found";
|
import NotFound from "@/app/vt/[slug]/not-found";
|
||||||
import ArchiveProgress from "./archive-progress";
|
import ArchiveProgress from "./archive-progress";
|
||||||
|
|
||||||
export default async function VTuberCard(vtuber: IVtuber) {
|
export default async function VTuberCard(vtuber: IVtuber) {
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
import { useSearchParams, useRouter } from 'next/navigation'
|
import { useSearchParams, useRouter } from 'next/navigation'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { strapiUrl } from '@/lib/constants'
|
import { strapiUrl } from '@/app/lib/constants'
|
||||||
import { useAuth, IAuthData, IUser, IJWT } from '@/components/auth'
|
import { useAuth, IAuthData, IUser, IJWT } from '@/app/components/auth'
|
||||||
import { DangerNotification } from '@/components/notifications'
|
import { DangerNotification } from '@/app/components/notifications'
|
||||||
|
|
||||||
export type AccessToken = string | null;
|
export type AccessToken = string | null;
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ import { getVtuberBySlug } from '../lib/vtubers'
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons";
|
import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faLink } from '@fortawesome/free-solid-svg-icons';
|
import { faLink } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { projektMelodyEpoch } from '@/lib/constants';
|
import { projektMelodyEpoch } from '@/app/lib/constants';
|
||||||
import LinkableHeading from '@/components/linkable-heading';
|
import LinkableHeading from '@/app/components/linkable-heading';
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { generateFeeds } from "@/lib/rss"
|
import { generateFeeds } from "@/app/lib/rss"
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const feeds = await generateFeeds()
|
const feeds = await generateFeeds()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { generateFeeds } from "@/lib/rss"
|
import { generateFeeds } from "@/app/lib/rss"
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const { atom1 } = await generateFeeds()
|
const { atom1 } = await generateFeeds()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { generateFeeds } from "@/lib/rss"
|
import { generateFeeds } from "@/app/lib/rss"
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const { rss2 } = await generateFeeds()
|
const { rss2 } = await generateFeeds()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { getGoals } from "@/lib/pm";
|
import { getGoals } from "@/app/lib/pm";
|
||||||
import { getCampaign } from "@/lib/patreon";
|
import { getCampaign } from "@/app/lib/patreon";
|
||||||
|
|
||||||
interface IFundingStatusBadgeProps {
|
interface IFundingStatusBadgeProps {
|
||||||
completedPercentage: number;
|
completedPercentage: number;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import VodsList from '@/components/vods-list';
|
import VodsList from '@/app/components/vods-list';
|
||||||
import { getVods } from '@/lib/vods';
|
import { getVods } from '@/app/lib/vods';
|
||||||
import Pager from '@/components/pager';
|
import Pager from '@/app/components/pager';
|
||||||
|
|
||||||
interface IPageParams {
|
interface IPageParams {
|
||||||
params: {
|
params: {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
import VodsList from '@/components/vods-list';
|
import VodsList from '@/app/components/vods-list';
|
||||||
import { IVodsResponse } from '@/lib/vods';
|
import { IVodsResponse } from '@/app/lib/vods';
|
||||||
import Pager from '@/components/pager';
|
import Pager from '@/app/components/pager';
|
||||||
import { getVods } from '@/lib/vods';
|
import { getVods } from '@/app/lib/vods';
|
||||||
|
|
||||||
|
|
||||||
interface IPageParams {
|
interface IPageParams {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { strapiUrl, patreonVideoAccessBenefitId, giteaUrl } from './constants'
|
import { strapiUrl, patreonVideoAccessBenefitId, giteaUrl } from './constants'
|
||||||
import { IAuthData } from '@/components/auth';
|
import { IAuthData } from '@/app/components/auth';
|
||||||
|
|
||||||
export interface IPatron {
|
export interface IPatron {
|
||||||
username: string;
|
username: string;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { authorName, authorEmail, siteUrl, title, description, siteImage, favicon, authorLink } from './constants'
|
import { authorName, authorEmail, siteUrl, title, description, siteImage, favicon, authorLink } from './constants'
|
||||||
import { Feed } from "feed";
|
import { Feed } from "feed";
|
||||||
import { getVods, getUrl, IVod } from '@/lib/vods'
|
import { getVods, getUrl, IVod } from '@/app/lib/vods'
|
||||||
import { ITagVodRelation } from '@/lib/tag-vod-relations';
|
import { ITagVodRelation } from '@/app/lib/tag-vod-relations';
|
||||||
|
|
||||||
export async function generateFeeds() {
|
export async function generateFeeds() {
|
||||||
const feedOptions = {
|
const feedOptions = {
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
import { siteUrl, strapiUrl } from './constants';
|
import { siteUrl, strapiUrl } from './constants';
|
||||||
import { getSafeDate } from './dates';
|
import { getSafeDate } from './dates';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
|
import { IStream } from 'types';
|
||||||
|
import { IStreamsResponse } from 'types';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import qs from 'qs';
|
||||||
import { strapiUrl } from './constants'
|
import { strapiUrl } from './constants'
|
||||||
import { ITagResponse, IToyTagResponse } from './tags';
|
import { ITagResponse, IToyTagResponse } from './tags';
|
||||||
import { IVod, IVodResponse } from './vods';
|
import { IVod, IVodResponse } from './vods';
|
||||||
import { IAuthData } from '@/components/auth';
|
import { IAuthData } from '@/app/components/auth';
|
||||||
import { IMeta } from 'types';
|
import { IMeta } from 'types';
|
||||||
|
|
||||||
export interface ITagVodRelation {
|
export interface ITagVodRelation {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { fetchPaginatedData } from './fetchers';
|
||||||
import { IVod } from './vods';
|
import { IVod } from './vods';
|
||||||
import slugify from 'slugify';
|
import slugify from 'slugify';
|
||||||
import { IToy } from './toys';
|
import { IToy } from './toys';
|
||||||
import { IAuthData } from '@/components/auth';
|
import { IAuthData } from '@/app/components/auth';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { IMeta } from 'types';
|
import { IMeta } from 'types';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { strapiUrl } from './constants'
|
import { strapiUrl } from './constants'
|
||||||
import { IAuthData } from '@/components/auth';
|
import { IAuthData } from '@/app/components/auth';
|
||||||
import { ITagsResponse, ITag, ITagResponse } from './tags';
|
import { ITagsResponse, ITag, ITagResponse } from './tags';
|
||||||
import { IMeta } from 'types';
|
import { IMeta } from 'types';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
import { ITag, ITagResponse, ITagsResponse } from '@/lib/tags'
|
import { ITag, ITagResponse, ITagsResponse } from '@/app/lib/tags'
|
||||||
import { IMeta } from 'types';
|
import { IMeta } from 'types';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { IVtuberResponse } from "./vtubers";
|
import { IVtuberResponse } from "types";
|
||||||
import { IMeta } from "types";
|
import { IMeta } from "types";
|
||||||
|
|
||||||
export interface ITweet {
|
export interface ITweet {
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
|
|
||||||
import { strapiUrl, siteUrl } from './constants';
|
import { strapiUrl, siteUrl } from './constants';
|
||||||
import { getDateFromSafeDate, getSafeDate } from './dates';
|
import { getDateFromSafeDate, getSafeDate } from './dates';
|
||||||
import { IVtuber, IVtuberResponse } from './vtubers';
|
import { IVtuber, IVtuberResponse, IStream, IStreamResponse } from 'types';
|
||||||
import { IStream, IStreamResponse } from './streams';
|
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { ITagVodRelationsResponse } from './tag-vod-relations';
|
import { ITagVodRelationsResponse } from './tag-vod-relations';
|
||||||
import { ITimestampsResponse } from './timestamps';
|
import { ITimestampsResponse } from './timestamps';
|
||||||
import { IMeta, IMuxAsset, IMuxAssetResponse } from 'types';
|
import { IMeta, IMuxAsset, IMuxAssetResponse } from 'types';
|
||||||
import { IB2File, IB2FileResponse } from '@/lib/b2File';
|
import { IB2File, IB2FileResponse } from '@/app/lib/b2File';
|
||||||
import fetchAPI from './fetch-api';
|
import fetchAPI from './fetch-api';
|
||||||
import { IUserResponse } from './users';
|
import { IUserResponse } from './users';
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { IVod } from './vods'
|
import { IVod } from './vods'
|
||||||
import { strapiUrl, siteUrl } from './constants';
|
import { strapiUrl, siteUrl } from './constants';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { IMeta } from 'types';
|
import { IMeta, IVtuber, IVtubersResponse } from 'types';
|
||||||
|
|
||||||
|
|
||||||
const fetchVtubersOptions = {
|
const fetchVtubersOptions = {
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
|
|
||||||
import FundingGoal from "@/components/funding-goal";
|
import FundingGoal from "@/app/components/funding-goal";
|
||||||
import VodCard from "@/components/vod-card";
|
import VodCard from "@/app/components/vod-card";
|
||||||
import { getVodTitle } from "@/components/vod-page";
|
import { getVodTitle } from "@/app/components/vod-page";
|
||||||
import { getVods } from '@/lib/vods';
|
import { getVods } from '@/app/lib/vods';
|
||||||
import { IVod } from "@/lib/vods";
|
import { IVod } from "@/app/lib/vods";
|
||||||
import { getVtubers, IVtuber } from "./lib/vtubers";
|
import { IVtuber } from 'types';
|
||||||
|
import { getVtubers } from "./lib/vtubers";
|
||||||
import VTuberCard from "./components/vtuber-card";
|
import VTuberCard from "./components/vtuber-card";
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const vods = await getVods(1, 9, true);
|
const vods = await getVods(1, 9, true);
|
||||||
console.log('vods as follows')
|
// console.log('vods as follows')
|
||||||
console.log(JSON.stringify(vods, null, 2))
|
// console.log(JSON.stringify(vods, null, 2))
|
||||||
|
|
||||||
|
|
||||||
const vtubers = await getVtubers();
|
const vtubers = await getVtubers();
|
||||||
if (!vtubers) notFound();
|
if (!vtubers) notFound();
|
||||||
console.log(`vtubers as follows`)
|
// console.log(`vtubers as follows`)
|
||||||
console.log(JSON.stringify(vtubers, null, 2))
|
// console.log(JSON.stringify(vtubers, null, 2))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { getVodsForTag, IVod } from '@/lib/vods'
|
import { getVodsForTag, IVod } from '@/app/lib/vods'
|
||||||
import VodCard from '@/components/vod-card'
|
import VodCard from '@/app/components/vod-card'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { getVodTitle } from '@/components/vod-page'
|
import { getVodTitle } from '@/app/components/vod-page'
|
||||||
import { notFound } from 'next/navigation'
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
export default async function Page({ params }: { params: { slug: string }}) {
|
export default async function Page({ params }: { params: { slug: string }}) {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
|
|
||||||
import { getAllVtubers } from '@/lib/vtubers';
|
import { getAllVtubers } from '@/app/lib/vtubers';
|
||||||
import UploadForm from '@/components/upload-form';
|
import UploadForm from '@/app/components/upload-form';
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
|
|
||||||
import '@uppy/core/dist/style.min.css';
|
import '@uppy/core/dist/style.min.css';
|
||||||
import '@uppy/dashboard/dist/style.min.css';
|
import '@uppy/dashboard/dist/style.min.css';
|
||||||
import { getStreamByCuid } from '@/lib/streams';
|
import { getStreamByCuid } from '@/app/lib/streams';
|
||||||
|
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Uppy from '@uppy/core';
|
||||||
import AwsS3 from '@uppy/aws-s3';
|
import AwsS3 from '@uppy/aws-s3';
|
||||||
import RemoteSources from '@uppy/remote-sources';
|
import RemoteSources from '@uppy/remote-sources';
|
||||||
import { useAuth } from './components/auth';
|
import { useAuth } from './components/auth';
|
||||||
import { companionUrl } from '@/lib/constants';
|
import { companionUrl } from '@/app/lib/constants';
|
||||||
|
|
||||||
|
|
||||||
// Uppy is a challenging react integration. Following are some references
|
// Uppy is a challenging react integration. Following are some references
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import VodPage from '@/components/vod-page';
|
import VodPage from '@/app/components/vod-page';
|
||||||
import { IVodPageProps, getVodFromSafeDateOrCuid } from '@/lib/vods';
|
import { IVodPageProps, getVodFromSafeDateOrCuid } from '@/app/lib/vods';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
import VodsList from '@/components/vods-list';
|
import VodsList from '@/app/components/vods-list';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { getVtuberBySlug } from '@/lib/vtubers'
|
import { getVtuberBySlug } from '@/app/lib/vtubers'
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faExternalLinkAlt, faBagShopping } from "@fortawesome/free-solid-svg-icons";
|
import { faExternalLinkAlt, faBagShopping } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { faFacebook, faInstagram, faPatreon, faYoutube, faTwitch, faTiktok, faXTwitter, faReddit, faDiscord } from "@fortawesome/free-brands-svg-icons";
|
import { faFacebook, faInstagram, faPatreon, faYoutube, faTwitch, faTiktok, faXTwitter, faReddit, faDiscord } from "@fortawesome/free-brands-svg-icons";
|
||||||
import Image from "next/legacy/image";
|
import Image from "next/legacy/image";
|
||||||
import OnlyfansIcon from "@/components/icons/onlyfans";
|
import OnlyfansIcon from "@/app/components/icons/onlyfans";
|
||||||
import PornhubIcon from '@/components/icons/pornhub';
|
import PornhubIcon from '@/app/components/icons/pornhub';
|
||||||
import ThroneIcon from '@/components/icons/throne';
|
import ThroneIcon from '@/app/components/icons/throne';
|
||||||
import LinktreeIcon from '@/components/icons/linktree';
|
import LinktreeIcon from '@/app/components/icons/linktree';
|
||||||
import FanslyIcon from '@/components/icons/fansly';
|
import FanslyIcon from '@/app/components/icons/fansly';
|
||||||
import ChaturbateIcon from '@/components/icons/chaturbate';
|
import ChaturbateIcon from '@/app/components/icons/chaturbate';
|
||||||
import CarrdIcon from '@/components/icons/carrd';
|
import CarrdIcon from '@/app/components/icons/carrd';
|
||||||
import styles from '@/assets/styles/icon.module.css';
|
import styles from '@/assets/styles/icon.module.css';
|
||||||
|
|
||||||
import { getVodsForVtuber } from '@/lib/vods';
|
import { getVodsForVtuber } from '@/app/lib/vods';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
import ArchiveProgress from '@/components/archive-progress';
|
import ArchiveProgress from '@/app/components/archive-progress';
|
||||||
import { getAllStreamsForVtuber, getStreamsForVtuber } from '@/lib/streams';
|
import { getAllStreamsForVtuber, getStreamsForVtuber } from '@/app/lib/streams';
|
||||||
import LinkableHeading from '@/components/linkable-heading';
|
import LinkableHeading from '@/app/components/linkable-heading';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import { Stream } from '@/components/stream';
|
import { Stream } from '@/app/components/stream';
|
||||||
import { IStream, getStreamForVtuber } from '@/lib/streams';
|
import { getStreamForVtuber } from '@/app/lib/streams';
|
||||||
import { getVtuberBySlug } from '@/lib/vtubers';
|
import { getVtuberBySlug } from '@/app/lib/vtubers';
|
||||||
import NotFound from '../../not-found';
|
import NotFound from '../../not-found';
|
||||||
|
|
||||||
interface IPageProps {
|
interface IPageProps {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import { getVtuberBySlug } from '@/lib/vtubers';
|
import { getVtuberBySlug } from '@/app/lib/vtubers';
|
||||||
import { getStreamsForVtuber } from '@/lib/streams';
|
import { getStreamsForVtuber } from '@/app/lib/streams';
|
||||||
import Pager from '@/components/pager';
|
import Pager from '@/app/components/pager';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
interface IPageParams {
|
interface IPageParams {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
// import VodsList, { VodsListHeading } from '@/components/vods-list'
|
// import VodsList, { VodsListHeading } from '@/app/components/vods-list'
|
||||||
// import { getVtuberBySlug } from '@/lib/vtubers'
|
// import { getVtuberBySlug } from '@/app/lib/vtubers'
|
||||||
// // import { IToys, getToysForVtuber } from '@/lib/toys'
|
// // import { IToys, getToysForVtuber } from '@/app/lib/toys'
|
||||||
// import { ToysList, ToysListHeading } from '@/components/toys'
|
// import { ToysList, ToysListHeading } from '@/app/components/toys'
|
||||||
// import Pager from '@/components/pager'
|
// import Pager from '@/app/components/pager'
|
||||||
|
|
||||||
// interface IPageParams {
|
// interface IPageParams {
|
||||||
// params: {
|
// params: {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
// import VodsList, { VodsListHeading } from '@/components/vods-list'
|
// import VodsList, { VodsListHeading } from '@/app/components/vods-list'
|
||||||
// import { getVtuberBySlug } from '@/lib/vtubers'
|
// import { getVtuberBySlug } from '@/app/lib/vtubers'
|
||||||
// // import { IToys, getToysForVtuber } from '@/lib/toys'
|
// // import { IToys, getToysForVtuber } from '@/app/lib/toys'
|
||||||
// import { ToysList } from '@/components/toys'
|
// import { ToysList } from '@/app/components/toys'
|
||||||
// import Pager from '@/components/pager'
|
// import Pager from '@/app/components/pager'
|
||||||
|
|
||||||
interface IPageParams {
|
interface IPageParams {
|
||||||
params: {
|
params: {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import VodPage from '@/components/vod-page'
|
import VodPage from '@/app/components/vod-page'
|
||||||
import { IVodPageProps, getVodFromSafeDateOrCuid } from '@/lib/vods'
|
import { IVodPageProps, getVodFromSafeDateOrCuid } from '@/app/lib/vods'
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import VodsList, { VodsListHeading } from '@/components/vods-list';
|
import VodsList, { VodsListHeading } from '@/app/components/vods-list';
|
||||||
import { getVtuberBySlug, getUrl } from '@/lib/vtubers';
|
import { getVtuberBySlug, getUrl } from '@/app/lib/vtubers';
|
||||||
import { IVodsResponse, getVodsForVtuber } from '@/lib/vods';
|
import { IVodsResponse, getVodsForVtuber } from '@/app/lib/vods';
|
||||||
import Pager from '@/components/pager';
|
import Pager from '@/app/components/pager';
|
||||||
import { notFound } from 'next/navigation';
|
import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
import VodsList, { VodsListHeading } from '@/components/vods-list'
|
import VodsList, { VodsListHeading } from '@/app/components/vods-list'
|
||||||
import { getVtuberBySlug, getUrl } from '@/lib/vtubers'
|
import { getVtuberBySlug, getUrl } from '@/app/lib/vtubers'
|
||||||
import { IVodsResponse, getVodsForVtuber, getPaginatedUrl } from '@/lib/vods'
|
import { IVodsResponse, getVodsForVtuber, getPaginatedUrl } from '@/app/lib/vods'
|
||||||
import Pager from '@/components/pager'
|
import Pager from '@/app/components/pager'
|
||||||
import { notFound } from 'next/navigation'
|
import { notFound } from 'next/navigation'
|
||||||
|
|
||||||
interface IPageParams {
|
interface IPageParams {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { notFound } from 'next/navigation'
|
import { notFound } from 'next/navigation'
|
||||||
import VTuberCard from '../components/vtuber-card'
|
import VTuberCard from '../components/vtuber-card'
|
||||||
import { getVtubers, IVtuber } from '../lib/vtubers'
|
import { getVtubers } from '../lib/vtubers'
|
||||||
|
import { IVtuber } from 'types'
|
||||||
|
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
|
|
|
@ -1,31 +1,13 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"paths": {
|
|
||||||
"@/components/*": [
|
|
||||||
"app/components/*"
|
|
||||||
],
|
|
||||||
"@/lib/*": [
|
|
||||||
"app/lib/*"
|
|
||||||
],
|
|
||||||
"@/assets/*": [
|
|
||||||
"assets/*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"target": "es5",
|
|
||||||
"lib": [
|
|
||||||
"dom",
|
|
||||||
"dom.iterable",
|
|
||||||
"esnext"
|
|
||||||
],
|
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
@ -34,16 +16,12 @@
|
||||||
{
|
{
|
||||||
"name": "next"
|
"name": "next"
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"next-env.d.ts",
|
|
||||||
"**/*.ts",
|
|
||||||
"**/*.tsx",
|
|
||||||
"dist/types/**/*.ts",
|
|
||||||
".next/types/**/*.ts"
|
|
||||||
],
|
],
|
||||||
"exclude": [
|
"paths": {
|
||||||
"node_modules"
|
"@/*": ["./*"]
|
||||||
]
|
}
|
||||||
}
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/components/*": [
|
||||||
|
"app/components/*"
|
||||||
|
],
|
||||||
|
"@/lib/*": [
|
||||||
|
"app/lib/*"
|
||||||
|
],
|
||||||
|
"@/assets/*": [
|
||||||
|
"assets/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"target": "es5",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
"dist/types/**/*.ts",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
"./app",
|
||||||
|
"./assets"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
|
@ -47,6 +47,7 @@
|
||||||
"slugify": "^1.6.6",
|
"slugify": "^1.6.6",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"tsx": "^4.7.2",
|
"tsx": "^4.7.2",
|
||||||
|
"types": "workspace:^",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"xpath": "^0.0.34"
|
"xpath": "^0.0.34"
|
||||||
},
|
},
|
||||||
|
|
|
@ -95,6 +95,9 @@ importers:
|
||||||
tsx:
|
tsx:
|
||||||
specifier: ^4.7.2
|
specifier: ^4.7.2
|
||||||
version: 4.15.1
|
version: 4.15.1
|
||||||
|
types:
|
||||||
|
specifier: workspace:^
|
||||||
|
version: link:../types
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.4.5
|
specifier: ^5.4.5
|
||||||
version: 5.4.5
|
version: 5.4.5
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
|
|
||||||
import dotenv from 'dotenv'
|
|
||||||
dotenv.config({
|
|
||||||
path: '../../.env'
|
|
||||||
})
|
|
||||||
import twitter from './twitter.js'
|
|
||||||
import fansly from './fansly.js'
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Acquire a vtuber image from the www
|
|
||||||
*
|
|
||||||
* Sources preference
|
|
||||||
* 1. Twitter
|
|
||||||
* 2. Fansly
|
|
||||||
*
|
|
||||||
* Our task is to download an avatar image of the vtuber.
|
|
||||||
* A slug is good for pulling a record from the database. From there, we can see any social medias such as Twitter or Fansly.
|
|
||||||
* Twitter is preferred.
|
|
||||||
*
|
|
||||||
* We depend on one of these social media URLs. If there is neither Twitter or fansly listed, we throw an error.
|
|
||||||
*
|
|
||||||
* @param {Object} vtuber -- vtuber instance from strapi
|
|
||||||
* @returns {String} filePath -- path on disk where the image was saved
|
|
||||||
*/
|
|
||||||
export async function getImage(vtuber) {
|
|
||||||
if (!vtuber) throw new Error('first arg must be vtuber instance');
|
|
||||||
|
|
||||||
const { twitter: twitterUrl, fanslyId: fanslyId } = vtuber.attributes
|
|
||||||
const twitterUsername = twitterUrl && twitter.regex.username.exec(twitterUrl).at(1)
|
|
||||||
|
|
||||||
let img;
|
|
||||||
if (twitterUrl) {
|
|
||||||
img = await twitter.data.image(twitterUsername)
|
|
||||||
} else if (fanslyId) {
|
|
||||||
img = await fansly.data.image(fanslyId)
|
|
||||||
} else {
|
|
||||||
const msg = ` while attempting to get vtuber image, there was neither twitterUrl nor fanslyId listed. One of these must exist for us to download an image. \nvtuber=${JSON.stringify(vtuber, null, 2)}`
|
|
||||||
console.error(msg)
|
|
||||||
throw new Error(msg)
|
|
||||||
}
|
|
||||||
return img
|
|
||||||
}
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config({
|
||||||
|
path: '../../.env',
|
||||||
|
});
|
||||||
|
|
||||||
|
import { type IVtuber } from 'types';
|
||||||
|
import twitter from './twitter.js';
|
||||||
|
import fansly from './fansly.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acquire a vtuber image from the www
|
||||||
|
*
|
||||||
|
* Sources preference
|
||||||
|
* 1. Twitter
|
||||||
|
* 2. Fansly
|
||||||
|
*
|
||||||
|
* Our task is to download an avatar image of the vtuber.
|
||||||
|
* A slug is good for pulling a record from the database. From there, we can see any social medias such as Twitter or Fansly.
|
||||||
|
* Twitter is preferred.
|
||||||
|
*
|
||||||
|
* We depend on one of these social media URLs. If there is neither Twitter nor Fansly listed, we throw an error.
|
||||||
|
*
|
||||||
|
* @param {IVtuber} vtuber -- vtuber instance from Strapi
|
||||||
|
* @returns {string} filePath -- path on disk where the image was saved
|
||||||
|
*/
|
||||||
|
export async function getImage(vtuber: IVtuber): Promise<string> {
|
||||||
|
if (!vtuber) throw new Error('first arg must be vtuber instance');
|
||||||
|
|
||||||
|
const { twitter: twitterUrl, fanslyId: fanslyId } = vtuber.attributes;
|
||||||
|
const twitterUsername = twitterUrl && twitterUrl.match(/@(\w+)/)?.[1];
|
||||||
|
|
||||||
|
let img: string;
|
||||||
|
if (twitterUrl) {
|
||||||
|
img = await twitter.data.image(twitterUsername);
|
||||||
|
} else if (fanslyId) {
|
||||||
|
img = await fansly.data.image(fanslyId);
|
||||||
|
} else {
|
||||||
|
const msg = `while attempting to get vtuber image, there was neither twitterUrl nor fanslyId listed. One of these must exist for us to download an image.\nvtuber=${JSON.stringify(vtuber, null, 2)}`;
|
||||||
|
console.error(msg);
|
||||||
|
throw new Error(msg);
|
||||||
|
}
|
||||||
|
return img;
|
||||||
|
}
|
|
@ -1,30 +1,31 @@
|
||||||
// {
|
|
||||||
// "compilerOptions": {
|
|
||||||
// "outDir": "./built",
|
|
||||||
// "allowJs": true,
|
|
||||||
// "target": "ES2017",
|
|
||||||
// "module": "NodeNext"
|
|
||||||
// },
|
|
||||||
// "include": ["./src/**/*"]
|
|
||||||
// }
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"extends": "@tsconfig/node20/tsconfig.json",
|
|
||||||
"version": "4.4.2",
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2017",
|
// Base Options recommended for all projects
|
||||||
"module": "esnext",
|
"esModuleInterop": true,
|
||||||
"moduleResolution": "node",
|
"skipLibCheck": true,
|
||||||
"declaration": true,
|
"target": "es2022",
|
||||||
"declarationMap": true,
|
"allowJs": true,
|
||||||
"sourceMap": true,
|
"resolveJsonModule": true,
|
||||||
"rootDir": "./src",
|
"moduleDetection": "force",
|
||||||
"outDir": "./dist"
|
"isolatedModules": true,
|
||||||
},
|
"verbatimModuleSyntax": true,
|
||||||
"include": ["**/*.ts"],
|
// Enable strict type checking so you can catch bugs early
|
||||||
"ts-node": {
|
"strict": true,
|
||||||
"experimentalSpecifierResolution": "node",
|
"noUncheckedIndexedAccess": true,
|
||||||
"transpileOnly": true,
|
"noImplicitOverride": true,
|
||||||
"esm": true,
|
// Transpile our TypeScript code to JavaScript
|
||||||
|
"module": "NodeNext",
|
||||||
|
"outDir": "dist",
|
||||||
|
"lib": [
|
||||||
|
"es2022"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
// Include the necessary files for your project
|
||||||
|
"include": [
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
// Transpile our TypeScript code to JavaScript
|
// Transpile our TypeScript code to JavaScript
|
||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"outDir": "lib",
|
"outDir": "dist",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2022"
|
"es2022"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "temporal-worker",
|
"name": "temporal-worker",
|
||||||
|
"type": "module",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
"declarationMap": true,
|
"declarationMap": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "./lib"
|
"outDir": "dist"
|
||||||
},
|
},
|
||||||
"include": ["**/*.ts"]
|
"include": ["**/*.ts"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Worker } from '@temporalio/worker';
|
import { Worker } from '@temporalio/worker';
|
||||||
import * as activities from '../temporal-workflows/src/all-activities';
|
import * as activities from '../temporal-workflows/src/all-activities.js';
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
// Step 1: Register Workflows and Activities with the Worker and connect to
|
// Step 1: Register Workflows and Activities with the Worker and connect to
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@temporalio/activity": "^1.9.0",
|
"@temporalio/activity": "^1.9.0",
|
||||||
"@temporalio/workflow": "^1.9.0",
|
"@temporalio/workflow": "^1.9.0",
|
||||||
|
"@types/qs": "^6.9.15",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
"image": "workspace:*",
|
"image": "workspace:*",
|
||||||
"qs": "^6.12.3",
|
"qs": "^6.12.3",
|
||||||
|
|
|
@ -14,6 +14,9 @@ importers:
|
||||||
'@temporalio/workflow':
|
'@temporalio/workflow':
|
||||||
specifier: ^1.9.0
|
specifier: ^1.9.0
|
||||||
version: 1.10.1
|
version: 1.10.1
|
||||||
|
'@types/qs':
|
||||||
|
specifier: ^6.9.15
|
||||||
|
version: 6.9.15
|
||||||
date-fns:
|
date-fns:
|
||||||
specifier: ^3.6.0
|
specifier: ^3.6.0
|
||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
|
@ -151,6 +154,9 @@ packages:
|
||||||
'@types/node@20.14.10':
|
'@types/node@20.14.10':
|
||||||
resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
|
resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
|
||||||
|
|
||||||
|
'@types/qs@6.9.15':
|
||||||
|
resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==}
|
||||||
|
|
||||||
'@types/semver@7.5.8':
|
'@types/semver@7.5.8':
|
||||||
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
|
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
|
||||||
|
|
||||||
|
@ -959,6 +965,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 5.26.5
|
undici-types: 5.26.5
|
||||||
|
|
||||||
|
'@types/qs@6.9.15': {}
|
||||||
|
|
||||||
'@types/semver@7.5.8': {}
|
'@types/semver@7.5.8': {}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5)':
|
'@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5)':
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { IStreamResponse } from 'types';
|
import { IStreamResponse, IStreamsResponse } from 'types';
|
||||||
import { subMinutes, addMinutes } from 'date-fns';
|
import { subMinutes, addMinutes } from 'date-fns';
|
||||||
import qs from 'qs'
|
import qs from 'qs'
|
||||||
|
|
||||||
|
@ -53,22 +53,24 @@ export async function upsertStream({
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const findStreamData = await findStreamRes.json() as IStreamResponse
|
const findStreamData = await findStreamRes.json() as IStreamsResponse
|
||||||
if (findStreamData?.data && findStreamData.data.length > 0) {
|
if (findStreamData?.data && findStreamData.data.length > 0) {
|
||||||
console.log('>> we found a findStreamData json. (there is an existing stream for this e-mail/notification)')
|
console.log('>> we found a findStreamData json. (there is an existing stream for this e-mail/notification)')
|
||||||
console.log(JSON.stringify(findStreamData, null, 2))
|
console.log(JSON.stringify(findStreamData, null, 2))
|
||||||
streamId = findStreamData.data[0].id
|
const stream = findStreamData.data[0]
|
||||||
|
if (!stream) throw new Error('stream was undefined');
|
||||||
|
streamId = stream.id
|
||||||
|
|
||||||
// Before we're done here, we need to do something extra. We need to populate isChaturbateStream and/or isFanslyStream.
|
// Before we're done here, we need to do something extra. We need to populate isChaturbateStream and/or isFanslyStream.
|
||||||
// We know which of these booleans to set based on the stream's related platformNotifications
|
// We know which of these booleans to set based on the stream's related platformNotifications
|
||||||
// We go through each pNotif and look at it's platform
|
// We go through each pNotif and look at it's platform
|
||||||
let isFanslyStream = false
|
let isFanslyStream = false
|
||||||
let isChaturbateStream = false
|
let isChaturbateStream = false
|
||||||
if (findStreamData.data[0].attributes.platformNotifications) {
|
if (stream.attributes.platformNotifications) {
|
||||||
for (const pn of findStreamData.data[0].attributes.platformNotifications) {
|
for (const pn of stream.attributes.platformNotifications) {
|
||||||
if (pn.platform === 'fansly') {
|
if (pn.attributes.platform === 'fansly') {
|
||||||
isFanslyStream = true
|
isFanslyStream = true
|
||||||
} else if (pn.platform === 'chaturbate') {
|
} else if (pn.attributes.platform === 'chaturbate') {
|
||||||
isChaturbateStream = true
|
isChaturbateStream = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +133,7 @@ export async function upsertStream({
|
||||||
console.error(JSON.stringify(createStreamJson.error, null, 2))
|
console.error(JSON.stringify(createStreamJson.error, null, 2))
|
||||||
throw new Error('Failed to create stream in DB due to an error. (see above)')
|
throw new Error('Failed to create stream in DB due to an error. (see above)')
|
||||||
}
|
}
|
||||||
streamId = createStreamJson.id
|
streamId = createStreamJson.data.id
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!streamId) throw new Error('failed to get streamId')
|
if (!streamId) throw new Error('failed to get streamId')
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { NotificationData, IVtubersResponse, IVtuberResponse } from 'types';
|
import { NotificationData, IVtubersResponse, IVtuberResponse, IVtuber } from 'types';
|
||||||
import { fpSlugify } from 'utils';
|
import { fpSlugify } from 'utils';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { getProminentColor } from 'image';
|
import { getProminentColor } from 'image';
|
||||||
|
@ -8,7 +8,7 @@ import { uploadFile } from 'storage/s3.js';
|
||||||
/**
|
/**
|
||||||
* find or create vtuber in Strapi
|
* find or create vtuber in Strapi
|
||||||
*/
|
*/
|
||||||
export async function upsertVtuber({ platform, userId, url, channel }: NotificationData): Promise<number> {
|
export async function upsertVtuber({ platform, userId, url, channel }: { platform: string, userId: string | null, url: string, channel: string }): Promise<number> {
|
||||||
|
|
||||||
let vtuberId
|
let vtuberId
|
||||||
console.log('>> # Step 1, upsertVtuber')
|
console.log('>> # Step 1, upsertVtuber')
|
||||||
|
@ -74,10 +74,16 @@ export async function upsertVtuber({ platform, userId, url, channel }: Notificat
|
||||||
|
|
||||||
// download image from platform
|
// download image from platform
|
||||||
// vtuber.getImage expects a vtuber object, which we don't have yet, so we create a dummy one
|
// vtuber.getImage expects a vtuber object, which we don't have yet, so we create a dummy one
|
||||||
const dummyVtuber = {
|
const dummyVtuber: IVtuber = {
|
||||||
|
id: 69,
|
||||||
attributes: {
|
attributes: {
|
||||||
slug: fpSlugify(channel),
|
slug: fpSlugify(channel),
|
||||||
fanslyId: (platform === 'fansly') ? userId : null
|
displayName: 'example',
|
||||||
|
vods: [],
|
||||||
|
description1: ' ',
|
||||||
|
image: ' ',
|
||||||
|
themeColor: ' ',
|
||||||
|
fanslyId: (platform === 'fansly') ? (userId ? userId : undefined) : undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const imageFile = await getImage(dummyVtuber)
|
const imageFile = await getImage(dummyVtuber)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { proxyActivities, sleep, log } from '@temporalio/workflow';
|
import { proxyActivities, sleep, log } from '@temporalio/workflow';
|
||||||
|
import { NotificationData } from 'types';
|
||||||
// Only import the activity types
|
// Only import the activity types
|
||||||
import type * as upsertVtuberType from './activities/upsertVtuber';
|
import type * as upsertVtuberType from './activities/upsertVtuber.js';
|
||||||
import type * as upsertStreamType from './activities/upsertStream';
|
import type * as upsertStreamType from './activities/upsertStream.js';
|
||||||
import type * as upsertPlatformNotificationType from './activities/upsertPlatformNotification';
|
import type * as upsertPlatformNotificationType from './activities/upsertPlatformNotification.js';
|
||||||
|
|
||||||
const { upsertVtuber } = proxyActivities<typeof upsertVtuberType>({
|
const { upsertVtuber } = proxyActivities<typeof upsertVtuberType>({
|
||||||
startToCloseTimeout: '1 minute',
|
startToCloseTimeout: '1 minute',
|
||||||
|
@ -14,10 +15,10 @@ const { upsertPlatformNotification } = proxyActivities<typeof upsertPlatformNoti
|
||||||
startToCloseTimeout: '1 minute',
|
startToCloseTimeout: '1 minute',
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function WorkflowA(name: string): Promise<string> {
|
export async function processNotifEmail({ url, platform, channel, displayName, date, userId, avatar }: NotificationData): Promise<string> {
|
||||||
log.info('Hello from processNotifEmail');
|
log.info('Hello from processNotifEmail workflow');
|
||||||
const res1 = await upsertVtuber(name);
|
const vtuberId = await upsertVtuber({ platform, userId, url, channel });
|
||||||
const res2 = await upsertStream(name);
|
const pNotifId = await upsertPlatformNotification({ source: 'email', date, platform, vtuberId });
|
||||||
const res3 = await upsertPlatformNotification(name);
|
const streamId = await upsertStream({ date, vtuberId, platform, pNotifId });
|
||||||
return `A: ${res1} | B: ${res2} | C: ${res3}`;
|
return `vtuberId: ${vtuberId} | pNotifId: ${pNotifId} | streamId: ${streamId}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { proxyActivities, sleep, log } from '@temporalio/workflow';
|
import { proxyActivities, sleep, log } from '@temporalio/workflow';
|
||||||
// Only import the activity types
|
// Only import the activity types
|
||||||
import type * as activitiesA from './activities/activitiesA';
|
import type * as activitiesA from './activities/activitiesA.js';
|
||||||
import type * as activitiesB from './activities/activitiesB';
|
import type * as activitiesB from './activities/activitiesB.js';
|
||||||
|
|
||||||
const { activityA } = proxyActivities<typeof activitiesA>({
|
const { activityA } = proxyActivities<typeof activitiesA>({
|
||||||
startToCloseTimeout: '1 minute',
|
startToCloseTimeout: '1 minute',
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
// Transpile our TypeScript code to JavaScript
|
// Transpile our TypeScript code to JavaScript
|
||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"outDir": "lib",
|
"outDir": "dist",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2022"
|
"es2022"
|
||||||
]
|
]
|
||||||
|
|
|
@ -57,6 +57,7 @@ export interface IStream {
|
||||||
tweet: ITweetResponse;
|
tweet: ITweetResponse;
|
||||||
isChaturbateStream: boolean;
|
isChaturbateStream: boolean;
|
||||||
isFanslyStream: boolean;
|
isFanslyStream: boolean;
|
||||||
|
platformNotifications: IPlatformNotification[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"declarationMap": true,
|
"declarationMap": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"outDir": "./lib"
|
"outDir": "dist"
|
||||||
},
|
},
|
||||||
"files": ["index.d.ts"]
|
"files": ["index.d.ts"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import * as slugify from 'slugify';
|
import slugify from './src/slugifyFix.js';
|
||||||
import { basename, join } from 'path';
|
import { basename, join } from 'path';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
@ -42,11 +42,12 @@ export async function download({ url, filePath }: { url: string; filePath?: stri
|
||||||
});
|
});
|
||||||
|
|
||||||
const { body } = response;
|
const { body } = response;
|
||||||
|
if (!body) throw new Error('body was null');
|
||||||
await finished(Readable.fromWeb(body).pipe(stream));
|
await finished(Readable.fromWeb(body).pipe(stream));
|
||||||
|
|
||||||
// Abort retrying if the resource doesn't exist
|
// Abort retrying if the resource doesn't exist
|
||||||
if (response.status === 404) {
|
if (response.status === 404) {
|
||||||
throw new AbortError(response.statusText);
|
throw new Error(response.statusText);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@paralleldrive/cuid2": "^2.2.2",
|
||||||
"@types/node": "^20.14.9",
|
"@types/node": "^20.14.9",
|
||||||
|
"p-retry": "^5.1.2",
|
||||||
"scout": "workspace:^",
|
"scout": "workspace:^",
|
||||||
"slugify": "^1.6.6"
|
"slugify": "^1.6.6"
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,9 +8,15 @@ importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
'@paralleldrive/cuid2':
|
||||||
|
specifier: ^2.2.2
|
||||||
|
version: 2.2.2
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20.14.9
|
specifier: ^20.14.9
|
||||||
version: 20.14.10
|
version: 20.14.10
|
||||||
|
p-retry:
|
||||||
|
specifier: ^5.1.2
|
||||||
|
version: 5.1.2
|
||||||
scout:
|
scout:
|
||||||
specifier: workspace:^
|
specifier: workspace:^
|
||||||
version: link:../scout
|
version: link:../scout
|
||||||
|
@ -50,6 +56,13 @@ packages:
|
||||||
'@jridgewell/trace-mapping@0.3.9':
|
'@jridgewell/trace-mapping@0.3.9':
|
||||||
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
|
||||||
|
|
||||||
|
'@noble/hashes@1.4.0':
|
||||||
|
resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
|
||||||
|
engines: {node: '>= 16'}
|
||||||
|
|
||||||
|
'@paralleldrive/cuid2@2.2.2':
|
||||||
|
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||||
|
|
||||||
'@tsconfig/node10@1.0.11':
|
'@tsconfig/node10@1.0.11':
|
||||||
resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
|
resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
|
||||||
|
|
||||||
|
@ -71,6 +84,9 @@ packages:
|
||||||
'@types/node@20.14.10':
|
'@types/node@20.14.10':
|
||||||
resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
|
resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==}
|
||||||
|
|
||||||
|
'@types/retry@0.12.1':
|
||||||
|
resolution: {integrity: sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==}
|
||||||
|
|
||||||
acorn-walk@8.3.3:
|
acorn-walk@8.3.3:
|
||||||
resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==}
|
resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
|
@ -319,6 +335,10 @@ packages:
|
||||||
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
p-retry@5.1.2:
|
||||||
|
resolution: {integrity: sha512-couX95waDu98NfNZV+i/iLt+fdVxmI7CbrrdC2uDWfPdUAApyxT4wmDlyOtR5KtTDmkDO0zDScDjDou9YHhd9g==}
|
||||||
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
path-exists@4.0.0:
|
path-exists@4.0.0:
|
||||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
@ -342,6 +362,10 @@ packages:
|
||||||
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
retry@0.13.1:
|
||||||
|
resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
|
||||||
|
engines: {node: '>= 4'}
|
||||||
|
|
||||||
safe-buffer@5.2.1:
|
safe-buffer@5.2.1:
|
||||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||||
|
|
||||||
|
@ -450,6 +474,12 @@ snapshots:
|
||||||
'@jridgewell/resolve-uri': 3.1.2
|
'@jridgewell/resolve-uri': 3.1.2
|
||||||
'@jridgewell/sourcemap-codec': 1.5.0
|
'@jridgewell/sourcemap-codec': 1.5.0
|
||||||
|
|
||||||
|
'@noble/hashes@1.4.0': {}
|
||||||
|
|
||||||
|
'@paralleldrive/cuid2@2.2.2':
|
||||||
|
dependencies:
|
||||||
|
'@noble/hashes': 1.4.0
|
||||||
|
|
||||||
'@tsconfig/node10@1.0.11': {}
|
'@tsconfig/node10@1.0.11': {}
|
||||||
|
|
||||||
'@tsconfig/node12@1.0.11': {}
|
'@tsconfig/node12@1.0.11': {}
|
||||||
|
@ -466,6 +496,8 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 5.26.5
|
undici-types: 5.26.5
|
||||||
|
|
||||||
|
'@types/retry@0.12.1': {}
|
||||||
|
|
||||||
acorn-walk@8.3.3:
|
acorn-walk@8.3.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
acorn: 8.12.1
|
acorn: 8.12.1
|
||||||
|
@ -693,6 +725,11 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
p-limit: 3.1.0
|
p-limit: 3.1.0
|
||||||
|
|
||||||
|
p-retry@5.1.2:
|
||||||
|
dependencies:
|
||||||
|
'@types/retry': 0.12.1
|
||||||
|
retry: 0.13.1
|
||||||
|
|
||||||
path-exists@4.0.0: {}
|
path-exists@4.0.0: {}
|
||||||
|
|
||||||
pathval@2.0.0: {}
|
pathval@2.0.0: {}
|
||||||
|
@ -709,6 +746,8 @@ snapshots:
|
||||||
|
|
||||||
require-directory@2.1.1: {}
|
require-directory@2.1.1: {}
|
||||||
|
|
||||||
|
retry@0.13.1: {}
|
||||||
|
|
||||||
safe-buffer@5.2.1: {}
|
safe-buffer@5.2.1: {}
|
||||||
|
|
||||||
serialize-javascript@6.0.2:
|
serialize-javascript@6.0.2:
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack to make 'slugify' import work with "type": "module".
|
||||||
|
* @see https://github.com/simov/slugify/issues/173
|
||||||
|
*/
|
||||||
|
import slugify from 'slugify'
|
||||||
|
|
||||||
|
export default slugify as unknown as typeof slugify.default
|
|
@ -14,7 +14,7 @@
|
||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
// Transpile our TypeScript code to JavaScript
|
// Transpile our TypeScript code to JavaScript
|
||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
"outDir": "lib",
|
"outDir": "dist",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2022"
|
"es2022"
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue